SM5100B GPRS och allmänna anteckningar (5 / 6 steg)
Steg 5: GPRS
Om du fick detta långt och du kan antingen skicka ett SMS eller ringa ett samtal, eller något annat sätt verifiera att du verkligen har en fungerande anslutning till mobilnätet så kan vi försöka få en GPRS-session igång.Denna kod är en hacka upp från ett prov som jag hittade av en kille som heter Toby: https://github.com/tobek/SM5100B-GPRS/blob/master/... det var ganska mycket det enda fungerande bit kod på internet! Tack Toby Fox!
Det ropar till httpbin.org och gör en http få begäran. httpbin.org är en praktisk uppsättning sidor för felsökning av http grejer.
Kan du bara gå och ta Tobys provet istället orsak det är den ursprungliga, probrably bättre och är väl dokumenterat, även om här nedan en redan ändras för att använda hårdvara UART för GSM och programvara för seriell monitor som tidigare nämnts.
Med hjälp av hårdvara UART inledningsvis för att programmera skissen,
Koppla från GSM seriell anslutning, Anslut usb till uno och ladda upp skiss.
Sedan för att testa skissen, sedan bort usb från uno och kopplar in i USB-seriell modulen.
koppla in GSM modem serial trådarna tillbaka i hårdvara UART stiften 0 & 1 igen
Tanken är att använda GSM-modem med hårdvara UART som mjukvaran följetong biblioteket
är att sakta för GSM modem, men dess uppenbarligen bra för felsökning grejer
#include
#define GSMSerial följetong
SoftwareSerial SMSerial(2,3); Med mjukvaran följetong som andra UART-
const String apn = "internet". Access-punkt namn för GPRS
const String ip = "54.235.174.110"; Vi ansluter till serverns IP-adress
const String värd = "httpbin.org"; krävs i HTTP 1.1 - Vad är namnet på värden på denna IP-adress?
const String begäran = "GET/get /? data = testa HTTP/1.1";
const String useragent = "Mozilla/5.0"; för våra ändamål spelar ingen förbrukaren agent roll - om jag förstått saken rätt är det bra att använda något generiskt servern kommer igen
void setup()
{
SMSerial.begin(9600);
SMSerial.println ("Start SM5100B meddelande...");
GSMSerial.begin(9600);
waitTil ("+ SIND: 4"); hålla utskrift GSMSerial utgång til vi får "+ SIND: 4"
SMSerial.println ("modul ready");
}
void loop()
{
SMSerial.println ("fästa GPRS...");
GSMSerial.println("AT+CGATT=1");
waitFor("OK");
SMSerial.println ("ställa in PDP sammanhang...");
GSMSerial.println("AT+CGDCONT=1,\"IP\",\""+apn+"\"");
waitFor("OK");
SMSerial.println ("Aktivera PDP sammanhang...");
GSMSerial.println("AT+CGACT=1,1");
waitFor("OK");
SMSerial.println ("Konfigurera TCP-anslutningen till TCP Server...");
GSMSerial.println("AT+SDATACONF=1,\"TCP\",\""+ip+"\",80");
waitFor("OK");
SMSerial.println ("Start TCP-anslutning...");
GSMSerial.println("AT+SDATASTART=1,1");
waitFor("OK");
samtidigt (1) {/ / nu vi ska slinga för evigt, kontrollera socket status och bara bryta när vi ansluter
SMSerial.println ("kontrollera socket status:");
GSMSerial.println("AT+SDATASTATUS=1"); Vi får tillbaka SOCKSTATUS och sedan OK
Sträng sockstat = getMessage();
waitFor("OK");
om (sockstat == "+ SOCKSTATUS: 1,0,0104,0,0,0") {
SMSerial.println ("inte ansluten ännu. Väntar på 1 sekund och försöker igen.");
Delay(750);
}
annars om (sockstat == "+ SOCKSTATUS: 1,1,0102,0,0,0") {
SMSerial.print("!!! Socket ansluten! ");
bryta;
}
annat {
SMSerial.println ("vi inte förvänta sig att.");
cellOutputForever();
}
}
int packetLength = 26+host.length()+request.length()+useragent.length(); 26 är storleken på de icke-variabla delarna av paketet, se storlek kommentarerna nedan
SMSerial.println ("Skicka HTTP paket...");
GSMSerial.print("AT+SDATATSEND=1,"+String(packetLength)+"\r");
waitFor('>'); vänta på GSM-modul för att berätta om det är redo att ta emot paketet
GSMSerial.print(request+"\r\n"); STORLEK: 2
GSMSerial.print ("Host:" + värd + "\r\n"); STORLEK: 8
GSMSerial.print ("User-Agent:" + useragent + "\r\n\r\n"); STORLEK: 16
GSMSerial.write(26); Ctrl + z-tecknet: skicka paketet
waitFor("OK");
waitTil("+STCPD:1"); Detta innebär att data tas emot
waitTil("+STCPC:1"); Detta innebär att uttaget är stängd
SMSerial.println ("läser data från servern...");
GSMSerial.println("AT+SDATAREAD=1"); hur vi läser dataserver har skickat
cellOutputForever(); bara hålla utskrift oavsett GSM modul säger oss
}
/ * ANTECKNINGAR
*
* Vad är + STIN:1?
*
* att koppla efter sändning: AT + CGACT = 0, 1 raster socket. AT + CGATT = 0 verkar fungera mer auktoritärt?
* AT + SDATASTART = 1, 0 / / Stäng TCP-anslutning
* AT + SDATASTATUS = 1 / / rensa skickas/ack byte från SOCKSTATUS
*
*/
=== HELPER FUNGERAR === / /
hålla läsa följetong meddelanden vi får från modulen
loop för alltid tills vi får ett annat värde än noll strängen slutar i \r\n - print och återvända som.
TODO: genomföra en timeout som returnerar 0?
Sträng getMessage() {
Sträng s = "";
While(1) {
IF(GSMSerial.available() > 0) {
s = s+(char)GSMSerial.read();
om (s.length() > 1 & & s[s.length () -2] == '\r' & & s[s.length()-1]=='\n') {/ / om sista 2 tecken finns \r\n
om (s == "\r\n" || s == "\r\n") {/ / hoppa över detta, gå vidare
s="";
}
annat {/ / vi har ett meddelande!
SMSerial.println(s.substring(0,s.length()-2));
återvända s.substring(0,s.length()-2);
}
}
}
}
}
för att äta en enda meddelande vi förväntar oss från modulen
skriver ut nästa meddelande från modulen. om det inte är det förväntade värdet, dö
void waitFor(String s) {
Sträng message=getMessage();
om (meddelande! = s) {
SMSerial.println ("vänta, det är inte vad vi väntade. Vi ville ha \""+s+"\" ");
cellOutputForever();
}
Delay(100); vänta på en liten bit innan du skickar nästa kommando
}
hålla spottar ut meddelanden från modulen til får vi det som vi förväntar oss
void waitTil(String s) {
Sträng meddelande;
samtidigt (1) {
meddelande = getMessage();
om (meddelande == s) {
Delay(100); orsaken är vi förmodligen om att skicka ett annat kommando
hemkomst.
}
}
}
Fortsätt att läsa tecken tills vi får char c
void waitFor(char c) {
While(1) {
IF(GSMSerial.available() > 0) {
om ((char)GSMSerial.read() == c) {
Delay(100);
hemkomst.
}
}
}
}
om något går fel, avbryta och bara Visa cell modul utgång så vi kan se felmeddelanden
Detta kommer att slinga för evigt
void cellOutputForever() {
SMSerial.println ("nu visar cell modul utgång för alltid");
GSMSerial.println("AT+SDATAREAD=1\r\n");
char incoming_char = 0;
While(1)
{
IF(GSMSerial.available() > 0)
{
SMSerial.write(GSMSerial.read());
}
IF(SMSerial.available() > 0)
{
incoming_char=SMSerial.Read(); Få karaktär kommer från terminalen
GSMSerial.print(incoming_char); Skicka karaktären av cellulära modulen.
}
}
}
som ovan, men i hex, användbara för felsökning
void cellHexForever() {
While(1) {
IF(GSMSerial.available() > 0) {
char c = (char)GSMSerial.read();
Serial.Print ("en röding:");
SMSerial.print (c, HEX).
SMSerial.print("");
SMSerial.println(c);
}
}
}
ta emot sträng som "SOCKSTATUS: 1,1,0102,10,10,0"
0 är anslutnings-id. 1 är ansluten eller inte. 2 är status (0104 ansluter, 0102 är ansluten, andra)
3 skickas byte. 4 är erkänt byte. 5 är "mottagna data disk"
DENNA funktion kommer att kontrollera att skickade byte == ack byte, och returnerar det värdet
returnera 0 om de inte matchar eller om mängden data är 0
int checkSocketString (String s) {
om (socketStringSlice(3,s) == 0)
Return 0;
annat if (socketStringSlice(3,s) == socketStringSlice(4,s))
återvända socketStringSlice(3,s);
annat
Return 0;
}
Returnerar index för den n: te instansen av char c i strängen s
int nthIndexOf (int n, char c, strängen s) {
heltal index = 0;
för (int jag = 0; jag < = n; i ++) {
index = s.indexOf(c,index+1);
}
Return index.
}
förväntar sig sträng som "SOCKSTATUS: 1,1,0102,10,10,0"
Returnerar den n: te bit av data, avgränsade med kommatecken
int socketStringSlice (int n, strängen s) {
Sträng skiva = s.substring(nthIndexOf(n-1,',',s)+1,nthIndexOf(n,',',s));
char cArray[slice.length () + 1];
slice.toCharArray (cArray, sizeof(cArray));
återvända atoi(cArray);
}
Här är seriell monitorutgången bör du räkna med
Startar SM5100B kommunikation...
ÐèÐÐÐ
+ SIND: 1
+ SIND: 10, "SM", 1, "FD", 1, "LD", 1, "MC", 1, "RC", 1, "ME", 1
+ STIN:0
+ SIND: 11
+ SIND: 3
+ SIND: 4
Modul redo
Fästa GPRS...
Okej
Ställa in PDP sammanhang...
Okej
Aktivera PDP sammanhang...
Okej
Konfigurera TCP-anslutningen till TCP Server...
Okej
Start TCP-anslutning...
Okej
Kontrollera status för socket:
+ SOCKSTATUS: 1,0,0104,0,0,0
Okej
Kontrollera status för socket:
+ SOCKSTATUS: 1,1,0102,0,0,0
Okej
!!! Socket ansluten! Skicka HTTP-paket...
Okej
+ STCPD:1
Läsa data från servern...
Nu visar cell modul utgång för evigt
+ SDATA :1,486,485454502F312E3120323030204F4B0D0A4163636573732D436F6E74726F6C2D416C6C6F772D4F726967696E3A202A0D0A436F6E74656E742D547970653A206170706C69636174696F6E2F6A736F6E0D0A446174653A205468752C203134204E6F7620323031332030353A32373A323320474D540D0A5365727665723A2067756E69636F726E2F302E31372E340D0A436F6E74656E742D4C656E6774683A203236330D0A582D43616368653A204D4953532066726F6D207478323272727065703233620D0A436F6E6E656374696F6E3A206B6565702D616C6976650D0A0D0A7B0A20202275726C223A2022687474703A2F2F6874747062696E2E6F72672F6765743F646174613D74657374696E67222C0A20202268656164657273223A207B0A2020202022436F6E6E656374696F6E223A2022636C6F7365222C0A2020202022486F7374223A20226874747062696E2E6F7267222C0A202020202243616368652D436F6E74726F6C223A20226D61782D6167653D323539323030222C0A2020202022557365722D4167656E74223A20224D6F7A696C6C612F352E30220A20207D2C0A2020226F726967696E223A202234392E3138302E3132322E3337222C0A20202261726773223A207B0A202020202264617461223A202274657374696E67220A20207D0A7D
Okej
+ SDATA:1, 0,
Okej
Observera att den + SDATA produktionen är i HEX, så att stora gamla sträng av förvanska får du tillbaka måste konverteras.
Du kan klistra in den i denna webbplats för att få en enkel titt på vad produktionen var: http://www.dolcevie.com/js/converter.html
och efter avkodning hex, vår produktion är
HTTP/1.1 200 OK?? Access-kontroll-tillåta-ursprung: *?? Content-Type: application/json?? Datum: Thu, 14 Nov 2013 05:27:23 GMT?? Server: gunicorn/0.17.4?? Content-Length: 263?? X-Cache: MISS från tx22rrpep23b?? Anslutning: keepalive-??? {? "url": "http://httpbin.org/get?data=testing"? "headers": {? "Anslutning": "nära",? "Host": "httpbin.org"? "Cache-Control": "max-ålder = 259200",? "User-Agent": "Mozilla/5.0"? },? "ursprung": "49.180.122.37"? "arg": {? "data": "test"? }?}?
Så en lyckad http få begäran, trodde jag aldrig det skulle hända.
REDIGERA!
Du kan berätta 5100B att spela du fick ta emot data i ASCII! Med ett enkelt kommando "AT + SDATARXMD = 1, 1, 0"
Så innan denna line:"GSMSerial.println("AT+SDATAREAD=1"); hur vi läser dataserver har skickat"
Lägg till kod:
GSMSerial.println("AT+SDATARXMD=1,1,0");
waitFor("OK");
Produktionen kommer att anges till ASCII precis innan du kallar SDATAREAD!
Och uppgifterna dina presenteras nu ser mycket vackrare mer såhär:
+ SSTR:1, HTTP/1.1 200 OK
Access-kontroll-tillåta-ursprung: *
Cont12:16 GMT
Server: gunicorn/0.17.4
Content-Length: 264
X-Cache: MISS från tx22rrpep38a
Anslutning: keep-alive
{
"arg": {
"data": "test"
},
"headers": {
"Host": "httpbin.org",
"User-Agent": "Mozilla/5.0",
"Cache-Control": "max-ålder = 259200",
"Anslutning": "Stäng"
},
"url": "http://httpbin.org/get?data=testing",
"ursprung": "49.180.112.246"
}
Med ingen anledning för dig att skriva en Hex till ASCII konverteringsfunktion:)
Ett stort gammalt problem presenterar detta är "OK" som är en del av ett HTTP-svar.
OK är också det sätt SM5100B berättar dess bearbetade ett kommando, när vi se "OK\r\n" som en sträng i följetong bufferten vi vet att GSM modulen har svarat och bildar detta i slutet av meddelandet,,, så då det är svårt att veta om "OK\r\n" i början av HTTP-svaret är en del av svaret eller meddelandet i slutet av framgångsrikt bearbetning av AT-kommandot.
"Så leta efter den andra"OK\r\n"Jag tänkte... men då vad om det finns också en"OK\r\n"i kroppen av svar!
Några idéer någon, bueller, någon?