Paso 5: GPRS
Si llegado el momento y puede enviar un SMS o hacer una llamada, o alguna otra forma de validar que usted efectivamente tiene una funcionamiento conexión a la red móvil entonces podemos intentar conseguir pasar sesión GPRS.Este código es una hackeada de una muestra que he encontrado por un chico llamado Toby: https://github.com/tobek/SM5100B-GPRS/blob/master/... era prácticamente la única parte funcionamiento de código en internet! Gracias Toby Fox!!
Se llama httpbin.org y hace un http llegar solicitud. httpbin.org es un práctico conjunto de páginas para cosas de http de depuración.
Usted puede ir y tomar muestra de Toby en cambio causa es mejor probrably original y está bien documentada, aunque éste a continuación ya está modificado para utilizar la UART Hardware para GSM y software para monitor serial como se ha mencionado anteriormente.
Usando el Hardware UART inicialmente para programar el bosquejo,
Desconecte la conexión serial GSM, enchufe usb en uno y subir el dibujo.
Luego para probar el bosquejo, luego quitar el usb de uno y enchufe el módulo USB-serie.
Conecte los cables en serie módem GSM en los pasadores UART hardware 0 y 1 nuevo
La idea es utilizar el módem GSM con el hardware del UART Serial biblioteca de Software
es lento para módem GSM, pero su obviamente bien para depurar la materia
#include
#define GSMSerial serie
SoftwareSerial SMSerial(2,3); Utilizando Software Serial como segundo UART-
const cadena apn = "internet"; Nombre punto de acceso para GPRS
const String ip = "54.235.174.110"; Dirección IP del servidor que nos estamos conectando a
const host cadena = "httpbin.org"; en HTTP 1.1 - ¿Qué es el nombre del host en la dirección IP?
solicitud de cadena const = "obtener /get? datos = prueba HTTP/1.1";
const cadena useragent = "Mozilla/5.0"; para nuestros propósitos el agente de usuario no importa - si no me equivoco es útil usar algo genérico que el servidor va a reconocer
void setup()
{
SMSerial.begin(9600);
SMSerial.println ("iniciar comunicación SM5100B...");
GSMSerial.begin(9600);
waitTil ("+ SIND: 4"); seguir imprimiendo GSMSerial til obtenemos la salida "+ SIND: 4"
SMSerial.println ("módulo listo");
}
void loop()
{
SMSerial.println ("fijación de GPRS...");
GSMSerial.println("AT+CGATT=1");
waitFor("OK");
SMSerial.println ("establecer contexto PDP...");
GSMSerial.println("AT+CGDCONT=1,\"IP\",\""+apn+"\"");
waitFor("OK");
SMSerial.println ("activar el contexto PDP...");
GSMSerial.println("AT+CGACT=1,1");
waitFor("OK");
SMSerial.println ("configuración de conexión TCP al servidor TCP...");
GSMSerial.println("AT+SDATACONF=1,\"TCP\",\""+ip+"\",80");
waitFor("OK");
SMSerial.println ("iniciar conexión TCP...");
GSMSerial.println("AT+SDATASTART=1,1");
waitFor("OK");
mientras (1) {/ / ahora te lazo para siempre, comprobar el estado de la toma y rompe sólo cuando nos conectamos
SMSerial.println ("comprobación del estado de la toma de corriente:");
GSMSerial.println("AT+SDATASTATUS=1"); nosotros volver SOCKSTATUS y luego en aceptar
Cadena sockstat = getMessage();
waitFor("OK");
Si (sockstat == "+ SOCKSTATUS: 1,0,0104,0,0,0") {}
SMSerial.println ("no conectado todavía. Espera 1 segundo y tratar otra vez.");
Delay(750);
}
else if (sockstat == "+ SOCKSTATUS: 1,1,0102,0,0,0") {}
SMSerial.print("!!! Toma conectada!!! ");
rotura;
}
Else {}
SMSerial.println ("no esperábamos que.");
cellOutputForever();
}
}
packetLength int = 26+host.length()+request.length()+useragent.length(); 26 es el tamaño de las partes no variables de los paquetes, ver tamaño comentarios abajo
SMSerial.println ("HTTP de envío de paquetes...");
GSMSerial.print("AT+SDATATSEND=1,"+String(packetLength)+"\r");
waitFor('>'); esperar para que el módulo GSM que nos diga que está listo para recibir el paquete
GSMSerial.print(request+"\r\n"); TAMAÑO: 2
GSMSerial.print ("Host:" + host + "\r\n"); TAMAÑO: 8
GSMSerial.print ("User-Agent:" + useragent "\r\n\r\n"); TAMAÑO: 16
GSMSerial.write(26); Ctrl z carácter: enviar el paquete
waitFor("OK");
waitTil("+STCPD:1"); Esto significa que recibe datos
waitTil("+STCPC:1"); Esto significa que toma está cerrada
SMSerial.println ("lectura de datos del servidor...");
GSMSerial.println("AT+SDATAREAD=1"); Cómo podemos leer datos servidor ha enviado
cellOutputForever(); mantener cualquier módulo GSM nos dice de la impresión
}
/ * NOTAS
*
* ¿Qué es + STIN:1?
*
* para desconectar después de la transmisión: AT + CGACT = 0, 1 toma descansos. ¿AT + CGATT = 0 parece funcionar con más autoridad?
* AT + SDATASTART = 1, 0 / / cerrar la conexión TCP
* AT + SDATASTATUS = 1 / / claro bytes enviados/ack de SOCKSTATUS
*
*/
=== AYUDA FUNCIONA === / /
seguir leyendo los mensajes de seriales que recibimos desde el módulo
lazo para siempre hasta que tengamos una cadena distinto de cero en \r\n - impresión y volver a eso.
¿TODO: implementar un tiempo de espera que devuelve el valor 0?
String getMessage() {}
String s = "";
{while(1)}
if(GSMSerial.Available() > 0) {}
s = s+(char)GSMSerial.read();
Si (s.length() > 1 & & (s[s.length) -2] == '\r' & & s[s.length()-1]=='\n') {/ / si son de 2 últimos caracteres \r\n
Si (s == "\r\n" || s == "\r\n") {/ / saltar estos, pasemos
s="";
}
Else {/ / tenemos un mensaje!
SMSerial.println(s.substring(0,s.length()-2));
volver s.substring(0,s.length()-2);
}
}
}
}
}
para comer un solo mensaje que esperamos del módulo de
imprime el siguiente mensaje del módulo. Si no es el valor esperado, dado
void waitFor(String s) {}
String message=getMessage();
Si (mensaje! = s) {}
SMSerial.println ("espera, que no lo esperábamos. Hemos querido \""+s+"\" ");
cellOutputForever();
}
Delay(100); Espere un poquito antes de enviar el siguiente comando
}
evitar escupir mensajes desde el módulo hasta que conseguimos que nos espera
void waitTil(String s) {}
Cadena de mensaje;
mientras que {} (1)
mensaje = getMessage();
Si (mensaje == s) {}
Delay(100); causa que está probablemente de enviar otro comando
retorno;
}
}
}
Siga leyendo caracteres hasta que char c
void waitFor(char c) {}
{while(1)}
if(GSMSerial.Available() > 0) {}
Si ((char)GSMSerial.read() == c) {}
Delay(100);
retorno;
}
}
}
}
Si algo sale mal, abortar y solo mostrar la salida del módulo de la célula por lo que podemos ver mensajes de error
Esto será de lazo para siempre
void cellOutputForever() {}
SMSerial.println ("ahora muestra salida del módulo de la célula para siempre");
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(); Obtener el carácter que viene de la terminal
GSMSerial.print(incoming_char); Envíe el carácter en el módulo celular.
}
}
}
como arriba, pero en hexadecimal, útil para la depuración
void cellHexForever() {}
{while(1)}
if(GSMSerial.Available() > 0) {}
char c = (char)GSMSerial.read();
Serial.Print ("un caracter:");
SMSerial.print c, HEX;
SMSerial.print("");
SMSerial.println(c);
}
}
}
recibir cadena como "SOCKSTATUS: 1,1,0102,10,10,0"
0 es el identificador de conexión. 1 es ya sea conectado o no. 2 es el estado (0104 está conectando, se conecta 0102, otros)
3 se envía bytes. 4 se reconoce bytes. 5 es "contador de datos recibidos"
ESTA verificación de función que envía bytes == ack bytes y devuelve ese valor
devuelven 0 si no coinciden o si la cantidad de datos es 0
int checkSocketString (String s) {}
Si (socketStringSlice(3,s) == 0)
return 0;
else if (socketStringSlice(3,s) == socketStringSlice(4,s))
volver socketStringSlice(3,s);
otra cosa
return 0;
}
Devuelve el índice de la enésima instancia de char c de cadena s
int nthIndexOf (int n, char c, String s) {}
Índice de int = 0;
para (int i = 0; i < = n; i ++) {}
Índice = s.indexOf(c,index+1);
}
volver índice;
}
espera la cadena como "SOCKSTATUS: 1,1,0102,10,10,0"
Devuelve el enésimo paquete de datos, delimitados por comas
int socketStringSlice (int n, String s) {}
Segmento de la cadena = s.substring(nthIndexOf(n-1,',',s)+1,nthIndexOf(n,',',s));
char cArray[slice.length () + 1];
slice.toCharArray (cArray, sizeof(cArray));
volver atoi(cArray);
}
Aquí está la salida de monitor Serial debe esperar
A partir de comunicación 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
Módulo listo
Conexión GPRS...
Vale
Creación de contexto PDP...
Vale
Activar el contexto PDP...
Vale
Configuración de conexión TCP al servidor TCP...
Vale
A partir de conexión TCP...
Vale
Comprobación del estado del socket:
+ SOCKSTATUS: 1,0,0104,0,0,0
Vale
Comprobación del estado del socket:
+ SOCKSTATUS: 1,1,0102,0,0,0
Vale
!!! Toma conectada!!! Envío de paquete HTTP...
Vale
+ STCPD:1
Lectura de datos desde el servidor...
Ahora viendo la salida del módulo celular para siempre
+ SDATA :1,486,485454502F312E3120323030204F4B0D0A4163636573732D436F6E74726F6C2D416C6C6F772D4F726967696E3A202A0D0A436F6E74656E742D547970653A206170706C69636174696F6E2F6A736F6E0D0A446174653A205468752C203134204E6F7620323031332030353A32373A323320474D540D0A5365727665723A2067756E69636F726E2F302E31372E340D0A436F6E74656E742D4C656E6774683A203236330D0A582D43616368653A204D4953532066726F6D207478323272727065703233620D0A436F6E6E656374696F6E3A206B6565702D616C6976650D0A0D0A7B0A20202275726C223A2022687474703A2F2F6874747062696E2E6F72672F6765743F646174613D74657374696E67222C0A20202268656164657273223A207B0A2020202022436F6E6E656374696F6E223A2022636C6F7365222C0A2020202022486F7374223A20226874747062696E2E6F7267222C0A202020202243616368652D436F6E74726F6C223A20226D61782D6167653D323539323030222C0A2020202022557365722D4167656E74223A20224D6F7A696C6C612F352E30220A20207D2C0A2020226F726967696E223A202234392E3138302E3132322E3337222C0A20202261726773223A207B0A202020202264617461223A202274657374696E67220A20207D0A7D
Vale
+ SDATA:1, 0,
Vale
Tenga en cuenta que el + salida SDATA es en hexadecimal, que cuerda antigua grande de mutilar, recibirá espalda necesita ser convertido.
Se puede pegar en este sitio para conseguir un look fácil en lo que fue la salida: http://www.dolcevie.com/js/converter.html
y después de descifrar el hex, nuestra producción es de
HTTP/1.1 200 OK?? Acceso-Access-Control-Allow-Origin: *?? Content-Type: aplicación/json?? Fecha: Jue, 14 de noviembre de 2013 05:27:23 GMT?? Servidor: gunicorn/0.17.4?? Content-Length: 263?? X-Cache: MISS de tx22rrpep23b?? Conexión: keep-alive??? {? ¿"url": "http://httpbin.org/get?data=testing"? ¿"cabeceras": {? ¿"Conexión": "cerrar",? ¿"Anfitrión": "httpbin.org"? ¿"Cache-Control": "max-age = 259200"? ¿"User-Agent": "Mozilla/5.0"? },? ¿"origen": "49.180.122.37"? ¿"args": {? ¿"datos": "pruebas"? }?}?
Para un exitoso http petición, nunca pensé que iba a suceder.
EDITAR!!!!!!
Puede decir 5100B usted reproducir los datos recived en ASCII!!!! Con un simple comando "AT + SDATARXMD = 1, 1, 0"
Así que antes de este line:"GSMSerial.println("AT+SDATAREAD=1"); Cómo podemos leer datos servidor ha enviado"
Agregue el código:
GSMSerial.println("AT+SDATARXMD=1,1,0");
waitFor("OK");
Esto ajustará la salida a ASCII antes de llamar a la SDATAREAD!
Y los datos su presentado ahora parecerá mucho más hermoso más como esto:
+ SSTR:1, HTTP/1.1 200 OK
Acceso-Access-Control-Allow-Origin: *
Cont12:16 GMT
Servidor: gunicorn/0.17.4
Content-Length: 264
X-Cache: MISS de tx22rrpep38a
Conexión: keep-alive
{
"args": {}
"datos": "la prueba"
},
"cabeceras": {}
"Anfitrión": "httpbin.org",
"User-Agent": "Mozilla/5.0",
"Cache-Control": "max-age = 259200",
"Conexión": "cerrar"
},
"url": "http://httpbin.org/get?data=testing",
"origen": "49.180.112.246"
}
Sin necesidad de escribir un maleficio a la función de conversión de ASCII:)
Un grande viejo problema que esto presenta es el "OK" es parte de la respuesta HTTP.
OK es también la manera de la SM5100B nos dice su procesado un comando, cada vez se "OK\r\n" como una cadena en el búfer serial, sabemos que el módulo GSM ha respondido y esto forma el final del mensaje,,, entonces su difícil saber si la "OK\r\n" al principio de la respuesta HTTP es parte de la respuesta o el mensaje final de procesar correctamente el comando AT.
"Así que busca el segundo"OK\r\n"me pensamiento... pero entonces qué si hay también un"OK\r\n"en el cuerpo de la respuesta!!!!!!
¿Alguna idea Alguien, bueller, alguien?