segunda-feira, 23 de setembro de 2013

Arduino GPRS - SIM900, Ler SMS Executar Ação

Dando continuidade ao post:

Arduino GPRS - SIM900, projeto aplicado lendo SMS

Agora alem de fazer a leitura do SMS, vamos executar um comando!

Primeiramente gostaria de agradecer a todos que vem visitando o blog. Isso começou como um passa tempo para catalogar meus projetos e publicar alguns pensamentos. Varias pessoas curtiram os posts sobre o SIM900, realmente essa placa é show de bola. E muitos pediram para aperfeiçoar a parte de fazer a leitura de um SMS e executar um comando previamente cadastrado.

Para fazer a leitura da SMS podemos fazer de dois modos, usar a biblioteca TextFinder, ou criar nosso parâmetros de busca no texto. Eu prefiro a segunda opção para não ficar atrelado a varias bibliotecas, alem do mais o programa fica mais enxuto e com firmware otimizado.

Antes de passar o código e explicar como funciona, temos que fazer uma modificação profunda no IDE do Arduino, do contrário NÃO VAI FUNCIONAR!

Enquanto eu criava esse programa, eu enfrentei alguns problemas na hora de transmitir muitos dados de uma so vez. Quando controlamos o SIM900 usamos a porta serial, e em certo momento enviamos um pico de sinal. O Arduino possui um core de código para buffer bem legal, onde você pode manter informações e ler posteriormente. No entanto é por default apenas 64 bytes. Essa valor é hard coded no core do Arduino, e é aplicado a todas placas, até mesmo as que possuem mais memoria RAM.

O limite de 64 bytes significa que um envio de dados maior que isso vai causar perda nas informações.
A solução é simples, alterar esse valor para permitir maior volume de dados e não perder as informações.
O que temos que fazer?


  • Entrar na pasta onde se encontra o IDE do Arduino - C:\Users\Vinicius\Downloads\arduino-1.0.5-windows\arduino-1.0.5\libraries\SoftwareSerial
  • Faça uma copia desse diretorio.
  • Abra o arquivo SoftwareSerial.h com seu editor preferido.
  • Encontre a linha: #define _SS_MAX_RX_BUFF 64
  • Substitua por : #define _SS_MAX_RX_BUFF 256 
  • Salve o arquivo e abre o IDE do Arduino.


Feito! Agora vai funcionar.

O programa a seguir faz o seguinte, lê a primeira SMS, e salva os dados, se na próxima leitura a SMS for a mesma que a anterior ele apaga. Para executar uma ação basta estipular, se ele ler uma ação previamente programada, o uC faz X ação, como no exemplo, acende os LEDs.

Lembrando que sua ação vem dentro de @ Ação <
Isso é feito para criar uma proteção as SMS recebidas(tirando espúrios), é praticamente uma senha. O Inicializador(@) e finalizador(<) da mensagem pode ser mudado, como exemplo <texto> Ação </texto>, ou qualquer outra maneira que você achar legal.

  1. #include <SoftwareSerial.h>
  2. SoftwareSerial mySerial(23);
  3. String  linhaAtual = "";              
  4. String  sms = "";  
  5. String  smsAnterior = "";  
  6. boolean lendoSMS = false;
  7. int led = 4;
  8. void setup()
  9. {
  10. mySerial.begin(19200);
  11. Serial.begin(19200);
  12. pinMode(led, OUTPUT);
  13. ligandoModulo();
  14. Serial.println("Configurando SMS modo texto");
  15. mySerial.println("AT+CMGF=1");
  16. mostraDadosSerial();
  17. }
  18. void loop()
  19. {
  20.   //Serial.println("Fazendo leitura do 1 SMS");
  21.   mySerial.println("AT+CMGR=1");
  22.   mostraDadosSerial();
  23.   delay(1000);
  24.   while (mySerial.available()>0)
  25.      {
  26.       char inChar = mySerial.read();
  27.       linhaAtual += inChar;
  28.         if (inChar == '\n')
  29.           {
  30.             linhaAtual = "";
  31.           }
  32.         if (linhaAtual.endsWith("@"))
  33.           {
  34.             lendoSMS = true;
  35.             sms = "";
  36.           }
  37.         if (lendoSMS)
  38.           {
  39.           if (inChar != '<')
  40.             {
  41.               sms += inChar;
  42.             }
  43.           else
  44.             {
  45.             lendoSMS = false;
  46.             Serial.println(sms);
  47.             if(sms=="@Liga LED" && smsAnterior!=sms)
  48.              {
  49.                Serial.println("Ligando LED");
  50.                digitalWrite(led, HIGH);
  51.              }
  52.              
  53.             if(sms=="@Desliga LED" && smsAnterior!=sms)
  54.              {
  55.                Serial.println("Desligando LED");
  56.                digitalWrite(led, LOW);
  57.              }
  58.               if(sms == smsAnterior)
  59.                 {
  60.                   mySerial.println("AT+CMGD=1,4");
  61.                   sms="";
  62.                 }    
  63.              smsAnterior=sms;
  64.             }
  65.           }
  66.     }
  67.     mySerial.println("");
  68. }
  69. void ligandoModulo()
  70. {
  71.   Serial.println("Ligando/Reiniciando Modulo GSM...");
  72.   if(digitalRead(6)==LOW)
  73.     {
  74.       digitalWrite(6,LOW);
  75.       delay(300);
  76.       digitalWrite(6,HIGH);
  77.       delay(15000);
  78.     }
  79.   Serial.println("Modulo Ligado!");
  80. }
  81. void mostraDadosSerial()
  82. {
  83.   while(mySerial.available()!=0)
  84.   {
  85.     Serial.write(mySerial.read());
  86.   }
  87. }

Ligando/Reiniciando Modulo GSM...
Modulo Ligado!
Configurando SMS modo texto
ÿÿÿÿÿÿÿÿ
RDY

+CFUN: 1

+CPIN: READY

+PACSP: 1
@Liga LED
Ligando LED

@Desliga LED
Desligando LED

Vídeo de exemplo do funcionamento do programa:





É isso ai pessoal, se você gostou compartilhe com seus amigos, ou pode fazer uma pequena doação para continuar mantendo o ritmo e sempre atender o pedido do pessoal e desenvolver os programas.


22 comentários:

  1. Aonde eu ponho numero do celular,para conecta-lo e para da os comandos vem as mensagens e eu so retorno elas para o arduino.

    ResponderExcluir
    Respostas
    1. OI,

      Não entendi muito bem o que você quis dizer.
      Não ha necessidade de estipular o numero do celular, ele vai ler apenas SMS que tenha como padrão:

      @ Sua MSG aqui <

      Excluir
    2. Mas como ele vai identificar o meu celular.

      Excluir
    3. ele identifica qualquer MSG que siga esse padrão:
      @ Sua MSG aqui <
      Não importa o celular que enviar, voce pode alterar a forma de recepção @ < por outro valor.

      Excluir
  2. Olá, Estou desenvolvendo um projeto parecido com este citado acima só que estou utilizando arduino duemilanove e shield sim900D.
    Já está quase tudo pronto no projeto, porém gostaria de obter ajuda quanto à seguinte questão:
    Necessito cadastrar alguns números de telefone para que apenas esses números executem os comandos, e caso o nº não esteja cadastrado informar o acesso negado no monitor.
    Segue abaixo o código que estou utilizando:

    #include

    #define PINNUMBER ""

    GSM gsmAccess;
    GSM_SMS sms;

    int powerkey = 5;
    int statuspin = 6;
    int pinState = 0;

    String inputString = "";
    char senderNumber[20];
    int led1 = 13;
    int led2 = 12;
    char c;
    boolean notConnected = true;

    void setup()
    {
    inputString.reserve(200);
    pinMode(powerkey, OUTPUT);
    pinMode(statuspin, INPUT);
    pinMode(pinState, INPUT);


    Serial.begin(9600);
    Serial.println("Serial Conectada");
    pinState = digitalRead(statuspin);

    if(pinState==LOW){
    digitalWrite(powerkey, HIGH); // set the LED on
    delay(2000);
    digitalWrite(powerkey, LOW);
    }
    while(notConnected)
    {
    if(gsmAccess.begin(PINNUMBER,false)==GSM_READY)
    {
    notConnected = false;
    Serial.println("rede localizada");
    }
    else
    {
    Serial.println("Não conectado");
    delay(100);
    //pinState = LOW;
    }
    }
    pinMode(led1, OUTPUT);
    digitalWrite(led1, LOW);
    pinMode(led2, OUTPUT);
    digitalWrite(led2, LOW);

    Serial.println("Aguardando novas mensagens");
    }

    void loop()
    {

    pinState = digitalRead(statuspin);

    if(pinState==LOW){
    digitalWrite(powerkey, HIGH); // set the LED on
    delay(2000);
    digitalWrite(powerkey, LOW);
    }

    // If there are any SMSs available()
    if (sms.available())
    {
    Serial.println("Mensagem recebida de:");
    sms.remoteNumber(senderNumber, 20);
    Serial.println(senderNumber);
    if(sms.peek()=='A')
    {
    digitalWrite(led2, LOW);
    digitalWrite(led1, HIGH);
    Serial.println("Portao Aberto");
    if(digitalRead(led2)==LOW&&(led1)==HIGH);
    {
    Serial.println("Confirma Portao aberto");
    sms.beginSMS(senderNumber);
    sms.print("Portao Aberto");
    sms.endSMS();
    }

    }
    else if (sms.peek()=='F')
    {
    digitalWrite(led1, LOW);
    digitalWrite(led2, HIGH);
    Serial.println("Portao fechado");

    if(digitalRead(led1)==LOW&&(led2)==HIGH);

    {
    Serial.println("Confirma portao fechado");
    sms.beginSMS(senderNumber);
    sms.print("portao fechado");
    sms.endSMS();
    }
    }
    // Read message bytes and print them
    while(c=sms.read())
    Serial.print(c);

    Serial.println("\nFIM DA MENSAGEM");
    sms.flush();
    Serial.println("MENSAGEM APAGADA");
    Serial.println("\nCOMPLETO!\n");
    sms.flush();
    } //Fim da verificação de mensagens
    delay(100);

    }


    Se puder dar alguma dica, ficarei muito agradecido.
    Abraço

    Alencar

    ResponderExcluir
    Respostas
    1. Fala parceiro, assim que tiver um tempo livre vou dar uma olhada no seu código. Esta usando a biblioteca do arduino GSM né?

      Bom basicamente o que voce tem que fazer é o seguinte, criar uma string para fazer a leitura do numero de telefone, e so executar as ações se a mensagem enviada for igual ao numero de telefone previamente cadastrado.

      assim que puder te dou uma força

      Excluir
  3. Olá estou realizando um projeto para meu ensino tecnico e preciso de projeto e um rastreador e bloqueador com arduino e sim900 e gostaria de saber se voçe faz o projeto .

    Pode ficar tranquilo que eu pago pra voçê e so falar quanto sai o projeto pra voçe desenvolver e me entregar pronto.

    Email: welington.14@hotmail.com.

    Valeu....

    Obrigado.......

    ResponderExcluir
  4. Boa tarde,

    Parabéns pelo post, me ajudou a solucionar alguns problemas relacionados ao recebimento de sms usando shield gsm com arduino. Estou fazendo vários testes, e percebi que as vezes a mensagem não é enviada, ou não está chegando na shield, gostaria de saber se você já fez alguma análise quanto a confiabilidade do mesmo, e comentar um pouco mais a respeito do que podemos fazer para amenizar esses problemas.

    ResponderExcluir
    Respostas
    1. Fala Bruno!

      Obrigado pelo comentário, fico feliz que esteja gostando do blog.
      Sobre suas perguntas. O sistema de leitura de SMS depende de algumas variáveis, ressalto algumas importantes por exemplo nas operadora de telefonia celular, onde SMS de operadoras que não seja a mesma do destinatário podem sim sofrer um atraso no recebimento. SMS entre a mesma operadora costuma ser mais rápido.

      O código do Arduíno esta sendo aprimorado e em breve teremos uma versão mais eficaz :-)

      é isso ai, abs

      Excluir
    2. Entendi,

      Bom consegui fazer com que a minha placa funcionasse, porém estou tendo falhas, tem hora que funciona normal, ai do nada para de funcionar, e fica assim oscilando. Quando abro o serial monitor, minha leitura está como a do colega abaixo:

      Ligando/Reiniciando Modulo GSM...
      Modulo Ligado!
      Configurando SMS modo texto

      Pelo que eu entendi do seu código, ele não está lendo, ou não está imprimindo o que a função "mostraDadosSerial" está lendo.

      Excluir
    3. Essa semana ainda posto uma versão atualizada, quem sabe funcione melhor, qual modelo de placa esta utilizando?

      Excluir
    4. https://lh5.googleusercontent.com/nbaX_-kpv6fxHaKF5-cLZdFvvfI4To8XYZG-jPsyrVGNXEFE1WfyyNoRCnmbzA-ZVA=w1254-h496

      Excluir
    5. Mandei um link da foto da placa, comprei ela no ebay...

      Excluir
    6. voce aumentou o tamanho do buffer como eu expliquei no post ?

      Excluir
  5. Vinicius ,

    Como ficaria a mensagem enviada para acender o LED ???

    ficaria @ Liga LED > ??

    e para apagar o LED: @ Desliga LED > é isto msm ?

    Abraçoss!!

    ResponderExcluir
    Respostas
    1. Fala Tulio,

      SMS segue esse padrão:

      @Comando<
      Neste casso: @Liga LED<
      @Desliga LED<

      Você pode trocar o comando inicial e final '@' e '<' por qualquer outro carácter, apenas lembre-se de enviar SMS no padrão:

      'inicial'Comando'final' , onde 'inicial' e 'final' são os caracteres que você estipulou na programação.

      Excluir
    2. Vinicius ,

      no serial monitor aparece

      Ligando/Reiniciando Modulo GSM...
      Modulo Ligado!
      Configurando SMS modo texto

      mais nada o que poder ser ?

      quando eu tento abrir o SoftwareSerial.h com o programa arduino arduino-1.0.5 ela da esata mensagem

      Processing can only open its own sketches and other files ending i .ino or. pde o que pode ser ?
      nao entendi ?

      a mensagem q mandei do celular foi @ Liga LED>


      abraços

      Excluir
    3. Você tem que editar o arquivo abrindo ele por exemplo no notepad do windows, ou notepad++. Qualquer editor de texto funciona...

      A SMS tem que ser exatamente assim @Liga LED<

      Excluir
    4. Vinicius fiz o que vc me disse e aconteceu o seguinte,

      Ligando/Reiniciando Modulo GSM...
      Modulo Ligado!
      Configurando SMS modo texto
      Ligando/Reiniciando Modulo GSM...
      Modulo Ligado!
      Configurando SMS modo texto

      ÿÿÿÿÿÿÿÿ怘€ ™`˜†fy`ÌÀ怘€ž† ˜x˜f™ø˜˜ €˜à˜ 0 0fæ€ ˜f††˜˜ € a™ ™

      depois q eu reiniciei o arduino e a placa mais nao acendeu o Led o que pode ser ?

      Excluir
    5. "ÿÿÿÿÿÿÿÿ怘€ ™`˜†fy`ÌÀ怘€ž† ˜x˜f™ø˜˜ €˜à˜ 0 0fæ€ ˜f††˜˜ € a™ ™"

      provavelmente você esta usando baud rate(taxa de comunicação errada)

      Excluir
    6. Esta em 19200 o engraçado que so aparece essa mensagem quando eu reinicio o Arduino e o shlid.

      o que posso tentar fazer para arrumar vc tem alguma ideia ?

      Excluir
    7. teste 4800, 9600, ou melhor olhe no datasheet da sua placa a velocidade padrão

      Excluir