Módulo GSM SIM800L - Aplicações com Arduino
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.
[toc]
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
- 1x - SIM800L
- 1x - Fonte externa de 3,4 a 4.4V de 2A.
- 1x - Arduino Mega
- Fios Jumpers
- Protoboard
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-seutilizar 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.
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.
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).
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.
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
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
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.