ARDUINO con SHIELD 3G SIM5216

Buenas a toda la comunidad, estuve investigando mucho en internet pero no logro hacer funcionar este programa..

Idea final: Poder imprimir un mensaje (para luego transformar ese mensaje en una web completa) a través de una conexión TCP al Shield mediante el 3G

Voy a describir todos los pasos hasta ahora...

Paso 1:

Lo principal fué probar el Shield (Es un SHIELD 3G de ElecFreaks, basado en el SIM5216E).

Para probarlo:

  • Le coloqué los Jumpers en Rx=2, Tx=3.
  • Creé un simple sketch que lo leído en el Serial lo envíe al Shield, y lo leído en el Shield lo imprima en el Serial:
#include <SoftwareSerial.h>

SoftwareSerial Shield(2,3);

void setup() {
  Serial.begin(115200);
  Shield.begin(115200);
}

void loop() {
  while(Serial.available()) Shield.write(Serial.read());
  while(Shield.available()) Serial.write(Shield.read());
}

Envié comandos AT y me respondió perfectamente, el Shield andaba de maravilla.

Paso 2:

Inserté una secuencia de comandos AT en el código para formar una sencilla web de HTML PLANO:

#include <SoftwareSerial.h>

SoftwareSerial Shield(2,3);

const int pin = 5;
const int pin2 = 6;
boolean enviado;


void setup() {
  Serial.begin(115200);
  Shield.begin(115200);

  pinMode(pin, INPUT);
  pinMode(pin2, INPUT);

  enviado = false;


}

void loop() {
  while(Serial.available()) Shield.write(Serial.read());
  while(Shield.available()) Serial.write(Shield.read());


  if(digitalRead(pin) == HIGH){
    if(!enviado){
      Shield.println("AT+TCPWRITE=15");
      //delay(5);
      delay(500);
      Shield.println("HTTP/1.1 200 OK");
      delay(2000);
      Shield.println("AT+TCPWRITE=23");
      //delay(5);
      delay(500);
      Shield.println("Content-Type: text/html");
      //delay(100);
      delay(2000);
      Shield.println("AT+TCPWRITE=17");
      delay(500);
      //delay(5);
      Shield.println("Connection: close");
      //delay(100);
      delay(2000);
      Shield.println("AT+TCPWRITE=15");
      delay(500);
      //delay(5);
      Shield.println("<!DOCTYPE html>");
      //delay(100);
      delay(2000);
      Shield.println("AT+TCPWRITE=6");
      delay(500);
      //delay(5);
      Shield.println("<html>");
      //delay(100);
      delay(2000);
      Shield.println("AT+TCPWRITE=6");
      delay(500);
      //delay(5);
      Shield.println("<head>");
      //delay(100);
      delay(2000);
      Shield.println("AT+TCPWRITE=19");
      delay(500);
      //delay(5);
      Shield.println("<title>HOLA</title>");
      //delay(100);
      delay(2000);
      Shield.println("AT+TCPWRITE=7");
      delay(500);
      //delay(5);
      Shield.println("</head>");
      //delay(100);
      delay(2000);
      Shield.println("AT+TCPWRITE=6");
      delay(500);
      //delay(5);
      Shield.println("<body>");
      //delay(100);
      delay(2000);
      Shield.println("AT+TCPWRITE=13");
      delay(500);
      //delay(5);
      Shield.println("<h1>HOLA</h1>");
      //delay(100);
      delay(2000);
      Shield.println("AT+TCPWRITE=7");
      delay(500);
      //delay(5);
      Shield.println("</body>");
      //delay(100);
      delay(2000);
      Shield.println("AT+TCPWRITE=7");
      delay(500);
      //delay(5);
      Shield.println("</html>");
      
      enviado = true;
    }
  }

  if(digitalRead(pin2) == HIGH){
    enviado = false;
  }
}

Hasta acá funcionaba todo perfecto.
Entonces decidí pasar los comandos AT que enviaba manualmente al programa, para que esto se realice de forma automática. Pero me encontré la necesidad de leer la respuesta del Shield!

Paso 3:

Encontré un Sketch, que al modificarlo un poco, logré que ande la mayor parte de la comunicación..
No inserto el Sketch porque es muy largo, si lo piden lo comparto en un comentario.. Pero la secuencia de comandos AT es la siguiente:

AT
// Responde OK
AT+CSOCKAUTH=1,1,"gprs","gprs"
// Responde OK
AT+CGSOCKCONT=1,"IP","gprs.personal.com"
// Responde OK
AT+NETOPEN="TCP",41953
// Abre la conexión "TCP" en puerto 41953 // Probé con diferentes puertos
AT+SERVERSTART
// Inicia Servidor
AT+IPADDR
// Responde IP
/////////////////// ME CONECTO

Pero noté algo muy raro, al recibir los datos de la dirección IP, recibía mucha basura..
Como si al recibir los bits, se restaba o sumaba un bit realizando una mala lectura.. Es decir, en vez de 'A' me llegaba '@'; en vez de '.' me llegaba '/', lo mismo con los números, en vez de '4', '5', etc..

Por lo que, al solicitar la dirección IP desde un sketch, me encontraba que no era la correcta! Si no que era una IP ficticia debido a la basura que obtenía al leer los bits entre Shield - Arduino!

Entonces volví al comienzo..

Paso 4:

Creando un sketch que almacene la lectura de la respuesta del Shield hacia el Arduino, y con un pulso en un botón me muestre esa respuesta almacenada:

#include <SoftwareSerial.h>

SoftwareSerial Shield(2,3);

char rta[100];
int x = 0;

void setup() {
  Serial.begin(115200);
  Shield.begin(115200);
}

void loop() {
  while(Serial.available()) Shield.write(Serial.read());
  //while(Shield.available()) Serial.write(Shield.read());

  if(Shield.available()){
    getResponse();
  }

  if(digitalRead(8) == HIGH){
    Serial.print("VARIABLE: ");
    Serial.println(rta);
  }
}

void getResponse(){
  memset(rta, 0, 100);
  x = 0;

  while(Shield.available()){

    rta[x] = Shield.read();
    //Serial.print(rta[x]);
    
    x++;
  }

  Serial.print("Mensaje: ");
  Serial.println(rta);
}

Al probar este código, noté que la variable también almacenaba la basura, por lo que el problema de los bits no era desde el arduino hacia la consola a través del Serial; si no que es desde el Shield hacia el Arduino el problema..

Paso 5:

Volví al primer sketch de control manual, cambié la velocidad del Shield de 115200 (Velocidad de fábrica), a una menor (9600, 19200, 57600, etc), y utilizando la misma en el Serial del Arduino, pero directamente dejaba de obtener respuestas de cualquier tipo de comando AT, inclusive el simple 'AT' inicial.

Resumen: Espero que alguien pueda ayudarme a solucionar este problema de lectura evitando la basura para así poder crear un sketch que lea respuestas correctas en el primer intento logrando obtener una dirección IP válida a la primera.

Gracias a todos por tomarse su tiempo de leer mi post!

Desde ya muchas gracias,
Federico.