Módulo GSM SIM800L

Neste tutorial, iremos testar as principais aplicações do módulo GSM SIM800L diretamente com os comandos AT pela UART , assim, podemos fazer o mesmo código para diversos microcontroladores como PIC, ESP8266/32, ARM, AVR, etc, mudando apenas os métodos de utilização da UART de MCU para MCU, já que os comandos AT serão sempre iguais. Para esse tutorial usaremos o Arduino Mega como controlador.

Módulo GSM SIM800L
Figura 1 – Módulo GSM SIM800L

[toc]

kit robotica educacional com Arduino ESP ou Microbit

O que vamos aprender?

As principais aplicações deste módulo são:

  • SMS (receber e enviar).
  • Obter horário da rede, similar ao NTP ou RTC.
  • Obter localização por triangulação da rede.
  • Conexões TCP/UDP (inclusive SSL/TLS).
  • Ligações com entrada e saída de áudio.

Neste tutorial, Aprenderemos os 3 primeiros itens separadamente encontrados na lista apresentada.


Mãos a obra – Testando algumas funções do SIM800L

Componentes necessários

Montando o projeto

Atenção: esse módulo pode utilizar muita corrente de sua fonte em picos de transmissão (até 2A), então não alimente-o diretamente pelo Arduino. Recomenda-se utilizar uma fonte externa de 3,4V a 4,3V de no mínimo 2A. Caso não tenha uma fonte com tanta corrente, você pode adicionar alguns capacitores de alto valor capacitivo para ajudar nos picos de transmissão. Se a fonte não for suficiente para alimentá-lo, ele irá reiniciar aleatoriamente durante as transmissões.

 

Esquematico no Frittzing Arudino Mega e Módulo GSM SIM800L
Figura 2 – Esquematico no Frittzing

Projeto 1 – Enviando e recebendo SMS

Programando o Arduino

void setup()
{
  Serial2.begin(115200);
  pinMode(13, OUTPUT);//LED
  pinMode(8, OUTPUT);//Pino de reset do GSM

  //reinicia o GSM
  digitalWrite(8, 0);
  delay(2000);
  digitalWrite(8, 1);
  delay(7000);

  if (gsmWrite("AT", "OK") == "FAIL")
  {
    return;//Se o GSM nao responder, retorna a funcao (trava o mcu)
  }

  delay(5000);//Espera o termino da inicializacao do GSM
  SMSsnd("014998202683", "Arduino ON, lendo mensagens...");//Envia a mensagem pro numero. Atencao: precisa do DDD!

  
}

void loop()
{
  SMSrd();//Verifica se há novas mensagens para serem lidas a cada 10seg
  delay(10000);
}


String gsmWrite(String snd, String rcv)//Funcao que envia dados pro GSM e espera a resposta de ate 30seg
{
  Serial2.println(snd);

  if (rcv.indexOf("+CMGS") > -1)
  {
    delay(150);
    Serial2.write(0x1A);
  }

  for (uint16_t i = 0; i < 1200; i++)
  {
    delay(25);
    if (Serial2.available())
    {
      delay(50);
      String a = Serial2.readString();


      if (a.indexOf(rcv) > -1 || rcv.length() == 0)
      {
        return a;
      }
    }
  }

  return "FAIL";
}

void SMSsnd(String nm, String msg)//Funcao que envia o SMS
{
  String snd = "AT+CMGS=\"";  snd += nm;  snd += "\"";

  gsmWrite("AT+CMGF=1", "OK");
  gsmWrite("AT+CSMP=17,255,0,0", "OK");
  gsmWrite(snd, ">");
  gsmWrite(msg, "+CMGS:");
}

void SMSrd()//Funcao que le se ha SMS nao lido
{
  String c = "";
  gsmWrite("AT+CMGF=1", "OK");
  c = gsmWrite("AT+CMGL=\"REC UNREAD\"", "");

  if (c.indexOf("+CMGL:") > -1)
  {
    if    (c.indexOf("ON") > -1)//ON
    {
      digitalWrite(13, 1);//se o SMS conter o texto ON, liga o LED
    }
    else if (c.indexOf("OFF") > -1)//OFF
    {
      digitalWrite(13, 0);//se o SMS conter o texto OFF, desliga o LED
    }

    gsmWrite("AT+CMGD=1,1", "OK");//apaga todas mensagens (SIM card ha pouca memoria)
  }
}

Colocando para funcionar

Depois de ligar nosso projeto na alimentação, vamos logo receber uma mensagem indicando que o sistema está ativo, mostrando que o envio de SMS funcionou perfeitamente. Também foi adicionada a leitura de SMS, de modo que, quando um SMS é enviado com a mensagem “ON” ou “OFF”,  o LED no pino 13 seja ligado ou desligado.

Mensagem recebida do Módulo GSM SIM800L
Figura 3 – Mensagem recebida do Módulo GSM SIM800L

Projeto 2 – Obtendo horário através da rede

Programando o Arduino

void setup()
{
  Serial.begin(115200);
  Serial2.begin(115200);//Inicia a Serial do GSM
  pinMode(8, OUTPUT);//Pino de reset do GSM

  //Reinicia o GSM
  digitalWrite(8, 0);
  delay(2000);
  digitalWrite(8, 1);
  delay(7000);

  String rcv = gsmWrite("AT", "*PSUTTZ:");//Espera o GSM obter o horario da rede
  if (rcv.indexOf("FAIL") > -1)
  {
    gsmWrite("AT+CLTS=1;&W", "OK");//Se nao responder, pode ser configuracao do seu GSM, entao vamos ativar a obtencao automatica de horario pela rede
    setup();//retorna ao inicio
  }

  delay(5000);
  

  
}

void loop()
{
  Serial.println(gsmTIME());//Mostra a data e horario no Serial Monitor
  delay(5000);
}


String gsmWrite(String snd, String rcv)//Funcao que envia dados ao GSM e espera a resposta
{
  Serial2.println(snd);

  if (rcv.indexOf("+CMGS") > -1)
  {
    delay(150);
    Serial2.write(0x1A);
  }

  for (uint16_t i = 0; i < 1200; i++)
  {
    delay(25);
    if (Serial2.available())
    {
      delay(50);
      String a = Serial2.readString();


      if (a.indexOf(rcv) > -1 || rcv.length() == 0)
      {
        return a;
      }
    }
  }

  return "FAIL";
}

String gsmTIME()//Funcao que retorna a data e horario
{
  String c = gsmWrite("AT+CCLK?", "+CCLK:");

  int16_t a = c.indexOf("\"") + 1;
  int16_t b = c.indexOf("\"", a);
  return c.substring(a, b);
}

Colocando para funcionar

Abrindo o Serial Monitor, podemos observar a data e o horário retornado pelo módulo GSM, lembrando que a data está no padrão (ano/mês/dia). O ultimo valor do horário corresponde ao fuso horário*4, logo, para obter nosso fuso horário, basta dividir “-12” por 4  e chegamos em -3 (fuso horário de brasília).

Data e hora do módulo GSM SIM800L
Figura 4 – Data e hora do módulo GSM SIM800L

Projeto 3 – Obtendo localização através da rede

Programando o Arduino

void setup()
{
  Serial.begin(115200);
  Serial2.begin(115200);
  pinMode(8, OUTPUT);//Pino de reset do GSM

  //Reseta o GSM
  digitalWrite(8, 0);
  delay(2000);
  digitalWrite(8, 1);
  delay(7000);

  if (gsmWrite("AT", "OK") == "FAIL")
  {
    return;
  }

  delay(5000);
  
  if (gsmWrite("AT+SAPBR=1,1", "OK") == "FAIL")//Ativa a rede pra localizacao
  {
    return;
  }
  else
  {
    String rcv = gsmWrite("AT+CIPGSMLOC=1,1", "+CIPGSMLOC:");//Pergunta a localizacao ao GSM
    int a = rcv.indexOf(":") + 2;
    int b = rcv.indexOf(",", a);
    if (rcv.substring(a, b) == "0")
    {
      a = rcv.indexOf(",", b) + 1;
      b = rcv.indexOf(",", a) + 1;
      b = rcv.indexOf(",", b);
      Serial.println(rcv.substring(a, b));//Mostra a localizacao no Serial monitor
    }
  }
}

void loop()
{
  
}


String gsmWrite(String snd, String rcv)//Funcao que envia dados ao GSM e espera a resposta
{
  Serial2.println(snd);

  if (rcv.indexOf("+CMGS") > -1)
  {
    delay(150);
    Serial2.write(0x1A);
  }

  for (uint16_t i = 0; i < 1200; i++)
  {
    delay(25);
    if (Serial2.available())
    {
      delay(50);
      String a = Serial2.readString();


      if (a.indexOf(rcv) > -1 || rcv.length() == 0)
      {
        return a;
      }
    }
  }

  return "FAIL";
}

Colocando para funcionar

As coordenadas que o módulo GSM retorna é longitude e latitude respectivamente.

Coordenadas lidas pelo Módulo GSM SIM800L
Figura 5 – Coordenadas lidas pelo Módulo GSM SIM800L

Entendendo a fundo

Software

Para utilização do módulo GSM foram usados os comandos “AT” do Datasheet, este pode ser encontrado logo abaixo em nossa seção de referências. Existem incontáveis comandos para as mais diversas aplicações e se você pretende utilizar o módulo GSM, aconselhamos que estude o Datasheet e conheça os comandos necessários para seu projeto.

A comunicação entre o Microcontrolador e o módulo GSM é feita através da porta Serial (UART) à 115200b/s neste caso, mas pode ser alterada. A cada comando enviado, normalmente, retorna-se uma resposta, então sempre que enviamos um comando, precisamos esperar a resposta para saber se os dados enviados foram realmente enviados. Para isso, foi criada uma função básica cuja função é escrever o dado no módulo GSM e esperar o retorno da resposta em um tempo limite de 30 segundos. Tome cuidado que alguns comandos podem demorar até 85 segundos para retornar resposta e caso isso aconteça, o código irá falhar por timeout. Para arrumar isso, aumente o timeout da função de leitura.

-Função gsmWrite(String snd, String rcv)

gsmWrite("AT", "OK");

A função criada para envio de dados do módulo GSM é uma boa maneira de utilizar o mesmo em diversos tipos de códigos, entretanto, como normalmente após a escrita de algum comando nós esperamos uma resposta, isto pode deixar nosso código lento e travando, já que alguns comandos demoram até 85 segundos!

Essa função basicamente escreve o comando (primeiro argumento da função, “snd“) AT na porta Serial e posteriormente espera a resposta do mesmo (segundo argumento da função, “rcv“). Caso o módulo GSM não retorne a reposta esperada em 30 segundos que definimos no loop FOR() da função, retorna-se a mensagem “FAIL”.

 -Comandos AT

O módulo GSM SIM800L funciona com os comandos AT e a maioria deles retorna alguma mensagem de confirmação ou erro, vamos ver como alguns deles funcionam!

AT+CCLK

Figura 6 – AT+CCLK

Quando requisitado “AT+CCLK?” do SIM800L, retorna-se “+CCLK: <time>” e ao fim, “OK”. Também pode-se retornar erros como mostrado na imagem.

AT+CMGL

Figura 7 – AT+CMGL

A leitura de SMS do nosso projeto foi dedicada apenas às mensagens não lidas, por isso utilizamos “AT+CMGL=”REC UNREAD””, mas você pode trocar para qualquer uma das opções acima que se encaixar melhor ao seu projeto.


Conclusões finais

As utilidades para o módulo GSM são inúmeras e isto nos permite ter uma gama de aplicações muito grande em um mesmo projeto, já que conta com diversas features, desde SMS até conexões TCP e etc. Apesar de alguns comandos demorarem bastante por causa da latência da rede telefônica, ainda podemos usufruir bem deste incrível módulo. O SIM800L faz muito mais do que mostrado aqui, entretanto estamos mostrando apenas o básico para norteá-los.

Referencias

Privacy Preference Center