Stap 5: GPRS
Als je dit veel en u kunt een SMS of bellen, of een andere manier valideren dat je hebt inderdaad een goed functionerende verbinding met het mobiele netwerk dan we kunnen proberen te gaan met een GPRS-sessie.Deze code is een gehackte up van een monster die ik gevonden door een jongen genaamd Toby: https://github.com/tobek/SM5100B-GPRS/blob/master/... het was vrij veel de enige functionerende bit code op het internet! Dank u Toby Fox!
Het roept naar httpbin.org en maakt een http get verzoek. httpbin.org is een handige set van pagina's voor het debuggen van http spullen.
U kunt gewoon gaan en grijpen Toby van monster in plaats daarvan de oorzaak is van de oorspronkelijke, probrably beter en is goed gedocumenteerd, hoewel dit een hieronder is al gewijzigd voor het gebruik van de UART-Hardware voor GSM en software voor seriële monitor zoals eerder is vermeld.
Met behulp van de Hardware UART in eerste instantie voor het programmeren van de schets,
Verbreek de GSM seriële verbinding, usb aansluit uno en uploaden van de schets.
Dan om te testen de schets, verwijder vervolgens de usb van de uno en sluit aan op de USB-serieel-module.
Sluit de GSM modem serial draden weer aan op de hardware UART pinnen 0 & 1 weer
Het idee is het gebruik van de GSM modem met de hardware UART als de seriële Software-bibliotheek
is te langzaam voor GSM modem, maar zijn uiteraard prima voor het debuggen van spullen
#include
#define GSMSerial seriële
SoftwareSerial SMSerial(2,3); Met behulp van seriële Software als tweede UART-
Const String apn = "internet"; de naam van het toegangspunt voor GPRS
Const String ip = "54.235.174.110"; IP-adres van de server waarmee die we verbinding met maken
Const String host = "httpbin.org"; vereist in de HTTP 1.1 - wat is de naam van de host op dit IP-adres?
Const String verzoek = "GET /get? gegevens testen HTTP/1.1 =";
Const String useragent = "Mozilla/5.0"; voor onze doeleinden de useragent maakt niet uit - als ik het goed begrijp is het nuttig om iets generieke die zal worden herkend door de server te gebruiken
VOID Setup
{
SMSerial.begin(9600);
SMSerial.println ("vanaf SM5100B communicatie...");
GSMSerial.begin(9600);
waitTil ("+ SIND: 4"); blijven drukken GSMSerial til we krijgen de uitgang "+ SIND: 4"
SMSerial.println ("Module ready");
}
void loop
{
SMSerial.println ("verbonden GPRS...");
GSMSerial.println("AT+CGATT=1");
waitFor("OK");
SMSerial.println ("het opzetten van PDP Context...");
GSMSerial.println("AT+CGDCONT=1,\"IP\",\""+apn+"\"");
waitFor("OK");
SMSerial.println ("activeren PDP Context...");
GSMSerial.println("AT+CGACT=1,1");
waitFor("OK");
SMSerial.println ("configureren TCP verbinding met TCP Server...");
GSMSerial.println("AT+SDATACONF=1,\"TCP\",\""+ip+"\",80");
waitFor("OK");
SMSerial.println ("vanaf TCP-verbinding...");
GSMSerial.println("AT+SDATASTART=1,1");
waitFor("OK");
terwijl (1) {/ / nu we zullen eeuwig, de socket status controleren en alleen breken wanneer we verbinden
SMSerial.println ("de status van de socket controleren:");
GSMSerial.println("AT+SDATASTATUS=1"); We krijgen weer SOCKSTATUS en klik vervolgens op OK
Sockstat koord = getMessage();
waitFor("OK");
Als (sockstat == "+ SOCKSTATUS: 1,0,0104,0,0,0") {}
SMSerial.println ('niet verbonden nog. 1 seconde wachten en opnieuw proberen.");
delay(750);
}
anders als (sockstat == "+ SOCKSTATUS: 1,1,0102,0,0,0") {}
SMSerial.print("!!! Socket verbonden!!! ");
breken;
}
else {}
SMSerial.println ("We niet verwachten dat.");
cellOutputForever();
}
}
int packetLength = 26+host.length()+request.length()+useragent.length(); 26 is de grootte van de niet-variabele onderdelen van het pakket, zie grootte opmerkingen hieronder
SMSerial.println ("verzenden HTTP packet...");
GSMSerial.print("AT+SDATATSEND=1,"+String(packetLength)+"\r");
waitFor('>'); wachten op GSM module om ons te vertellen dat het is klaar om te ontvangen van het pakket
GSMSerial.print(request+"\r\n"); GROOTTE: 2
GSMSerial.print ("Host:" + host + "\r\n"); GROOTTE: 8
GSMSerial.print ("User-Agent:" + useragent + "\r\n\r\n"); GROOTTE: 16
GSMSerial.write(26); CTRL + z-teken: het pakket verzenden
waitFor("OK");
waitTil("+STCPD:1"); Dit betekent dat gegevens ontvangen
waitTil("+STCPC:1"); Dit betekent socket wordt gesloten
SMSerial.println ("lezen van gegevens van server...");
GSMSerial.println("AT+SDATAREAD=1"); Hoe lezen we data server heeft verzonden
cellOutputForever(); Houd enkel afdrukken welke GSM-module is ons te vertellen
}
/ * NOTITIES
*
* Wat is + STIN:1?
*
* te verbreken na uitzending: AT + CGACT = 0, 1 einden socket. AT + CGATT = 0 lijkt te werken meer bindend?
* AT + SDATASTART = 1, 0 / / TCP verbinding sluiten
* AT + SDATASTATUS = 1 / / clear verzonden/ack bytes vanaf SOCKSTATUS
*
*/
=== HELPER FUNCTIES === / /
Houd het lezen van de seriële berichten die we ontvangen van de module
eeuwig totdat we krijgen niet-nulzijnde string eindigend in \r\n - print en dat terug te keren.
TODO: uitvoering van een time-out van de retourwaarde 0?
String getMessage() {}
String s = "";
while(1) {}
if(GSMSerial.available() > 0) {}
s = s+(char)GSMSerial.read();
Als (s.length() > 1 & & s[s.length () -2] == '\r' & & s[s.length()-1]=='\n') {/ / als laatste 2 chars \r\n
Als (s == "\r\n" || s == "\r\n") {/ / sla deze, voortmaken
s="";
}
else {/ / hebben we nog een boodschap!
SMSerial.println(s.substring(0,s.length()-2));
Return s.substring(0,s.length()-2);
}
}
}
}
}
voor het eten van een enkel bericht verwachten wij van de module
het volgende bericht uit de module wordt afgedrukt. Als het niet de verwachte waarde is, sterven
VOID waitFor(String s) {}
String message=getMessage();
Als (bericht! = s) {}
SMSerial.println ("wacht, dat is niet wat we hadden verwacht. We wilden \""+s+"\" ");
cellOutputForever();
}
delay(100); een klein beetje wachten voordat de volgende opdracht
}
houden met het spugen van berichten van de module til we krijgen die we verwachten
VOID waitTil(String s) {}
Koord bericht;
terwijl (1) {}
Message = getMessage();
Als (bericht == s) {}
delay(100); oorzaak we waarschijnlijk ongeveer te verzenden van een andere opdracht
terugkeer;
}
}
}
Houd lezend tekens totdat we char c
VOID waitFor(char c) {}
while(1) {}
if(GSMSerial.available() > 0) {}
Als ((char)GSMSerial.read() == c) {}
delay(100);
terugkeer;
}
}
}
}
Als er iets misgaat, afbreken en cel module output alleen weergeven zodat we foutberichten zien kunnen
Dit zal eeuwig
ongeldig cellOutputForever() {}
SMSerial.println ("nu weer te geven cel module output forever");
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(); Krijgen van het teken vanuit de terminal
GSMSerial.print(incoming_char); Stuur het teken naar de cellulaire module.
}
}
}
zoals hierboven, maar in hex, nuttig voor debugging
ongeldig cellHexForever() {}
while(1) {}
if(GSMSerial.available() > 0) {}
char c = (char)GSMSerial.read();
Serial.Print ("een char:");
SMSerial.print (c, HEX);
SMSerial.print("");
SMSerial.println(c);
}
}
}
Ontvangen tekenreeks zoals "SOCKSTATUS: 1,1,0102,10,10,0"
0 is de koppelings-id. 1 is of aangesloten of niet. 2 is de status (0104 verbinding maakt, 0102 is verbonden, anderen)
3 verzonden bytes. 4 wordt erkend bytes. 5 is "ontvangen gegevensteller"
DEZE functie zal controle die bytes verzonden == ack bytes, en die waarde retourneren
0 terug als ze niet overeenkomen of als hoeveelheid gegevens 0 is
int checkSocketString (String s) {}
Als (socketStringSlice(3,s) == 0)
keren 0;
else if (socketStringSlice(3,s) == socketStringSlice(4,s))
Return socketStringSlice(3,s);
anders
keren 0;
}
geeft de index van het nde aanleg van char c in String s
int nthIndexOf (int n, char c, String s) {}
int index = 0;
for (int i = 0; ik < = n; i ++) {}
index = s.indexOf(c,index+1);
}
Retourneer index;
}
zoals verwacht van de tekenreeks "SOCKSTATUS: 1,1,0102,10,10,0"
retourneert de nde hoeveelheid gegevens, gescheiden door komma 's
int socketStringSlice (int n, String s) {}
Tekenreeks segment = s.substring(nthIndexOf(n-1,',',s)+1,nthIndexOf(n,',',s));
char cArray[slice.length () + 1];
slice.toCharArray (cArray, sizeof(cArray));
Return atoi(cArray);
}
Hier is de output van de seriële monitor kunt u verwachten
Vanaf de mededeling van de SM5100B...
ÐèÐÐÐ
+ SIND: 1
+ SIND: 10, "SM", 1 "FD", 1 "LD", 1 "MC", 1, "RC", 1, "ME", 1
+ STIN:0
+ SIND: 11
+ SIND: 3
+ SIND: 4
Module klaar
GPRS verbonden...
OK
PDP Context instellen...
OK
Activeer PDP Context...
OK
TCP verbinding configureert met TCP Server...
OK
TCP-verbinding wordt gestart...
OK
De status van de socket te controleren:
+ SOCKSTATUS: 1,0,0104,0,0,0
OK
De status van de socket te controleren:
+ SOCKSTATUS: 1,1,0102,0,0,0
OK
!!! Socket verbonden!!! Het verzenden van HTTP-pakket...
OK
+ STCPD:1
Het lezen van gegevens van de server...
Nu weergeven voor altijd cel module output
+ DELAMPENFABRIKANT :1,486,485454502F312E3120323030204F4B0D0A4163636573732D436F6E74726F6C2D416C6C6F772D4F726967696E3A202A0D0A436F6E74656E742D547970653A206170706C69636174696F6E2F6A736F6E0D0A446174653A205468752C203134204E6F7620323031332030353A32373A323320474D540D0A5365727665723A2067756E69636F726E2F302E31372E340D0A436F6E74656E742D4C656E6774683A203236330D0A582D43616368653A204D4953532066726F6D207478323272727065703233620D0A436F6E6E656374696F6E3A206B6565702D616C6976650D0A0D0A7B0A20202275726C223A2022687474703A2F2F6874747062696E2E6F72672F6765743F646174613D74657374696E67222C0A20202268656164657273223A207B0A2020202022436F6E6E656374696F6E223A2022636C6F7365222C0A2020202022486F7374223A20226874747062696E2E6F7267222C0A202020202243616368652D436F6E74726F6C223A20226D61782D6167653D323539323030222C0A2020202022557365722D4167656E74223A20224D6F7A696C6C612F352E30220A20207D2C0A2020226F726967696E223A202234392E3138302E3132322E3337222C0A20202261726773223A207B0A202020202264617461223A202274657374696E67220A20207D0A7D
OK
+ SDATA:1, 0,
OK
Merk op dat de + DELAMPENFABRIKANT uitvoer is in HEX, zodat grote oude tekenreeks verminkt ontvangt u terug moet worden geconverteerd.
U kunt het plakken van deze site om een eenvoudige blik op wat de uitvoer was: http://www.dolcevie.com/js/converter.html
en na decodering de hex, onze output is
HTTP/1.1 200 OK?? Toegang-controle-toestaan-oorsprong: *?? Content-Type: application/json?? Datum: Thu, 14 Nov 2013 05:27:23 GMT?? Server: gunicorn/0.17.4?? Content-Length: 263?? X-Cache: MISS van tx22rrpep23b?? Verbinding: keep-alive??? {? "url": "http://httpbin.org/get?data=testing",? "headers": {? "Verbinding": "afsluiten",? "Host": "httpbin.org",? 'Cache-Control': "max-age = 259200",? "User-Agent": "Mozilla/5.0"? },? "oorsprong": "49.180.122.37",? "args": {? "gegevens": "testen"? }?}?
Dus een succesvolle http krijgt verzoek, ik nooit gedacht dat het zou gebeuren.
BEWERKEN!
U kunt de 5100B om over te spelen u de recived gegevens in ASCII vertellen!! Met een eenvoudig commando "AT + SDATARXMD = 1, 1, 0"
Dus voordat dit line:"GSMSerial.println("AT+SDATAREAD=1"); Hoe lezen we data server heeft gestuurd"
Voeg de code toe:
GSMSerial.println("AT+SDATARXMD=1,1,0");
waitFor("OK");
Dit zal de output ingesteld op ASCII, net voordat u contact opneemt met de SDATAREAD!
En de gegevens uw gepresenteerde nu ziet er veel mooier meer zoals dit:
+ SSTR:1, HTTP/1.1 200 OK
Toegang-controle-toestaan-oorsprong: *
Cont12:16 GMT
Server: gunicorn/0.17.4
Content-Length: 264
X-Cache: MISS from tx22rrpep38a
Verbinding: keep-alive
{
"args": {}
"gegevens": "testen"
},
"headers": {}
"Host": "httpbin.org",
"User-Agent": "Mozilla/5.0",
'Cache-Control': "max-age = 259200",
"Verbinding": "sluiten"
},
"url": "http://httpbin.org/get?data=testing",
"oorsprong": "49.180.112.246"
}
Met geen noodzaak voor u om te schrijven een Hex naar ASCII-conversiefunctie:)
Een grote oude probleem dit presenteert is de "OK" dat is onderdeel van een HTTP-antwoord.
OK is ook de manier waarop de SM5100B ons de verwerkte vertelt een opdracht, wanneer we se "OK\r\n" als een tekenreeks in de seriële buffer, we weten dat de GSM-module heeft beantwoord en dit het einde van het bericht,,, dus dan zijn moeilijk om te weten vormt als de "OK\r\n" aan het begin van de HTTP-reactie onderdeel van het antwoord of het bericht aan het eind is van de AT-opdracht met succes wordt verwerkt.
"Dus op zoek naar de tweede"OK\r\n"I thought... maar dan wat als er ook een"OK\r\n"in het lichaam van de reactie!!!
Enig idee iemand, bueller, iedereen?