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.


sábado, 21 de setembro de 2013

Arduino leonardo + RFID Executando ação

Como visto em:

Arduino leonardo + RFID introdução
Arduino leonardo + RFID escrevendo no cartão

Agora alem de fazer a leitura do cartão vamos tomar uma ação se os dados estiverem de acordo. Vamos bloquear um computador/desbloquear usando apenas o cartão de RFID.

Vamos ao que interessa, para bloquear um computador com windows executamos o seguinte comando no teclado WINDOWS+L, para desbloquear entramos com a senha e apertamos ENTER. O Arduin leonardo vai executar essas ações automaticamente, isso vai depender da leitura que ele fizer no cartão de RFID, se o cartão, que foi gravado anteriormente, tiver as informações corretas o Arduino toma a ação.

Esse é o escopo do programa, vai bloquear/desbloquear Windows 8:

  1. #include <PN532.h>
  2. #define SCK 13
  3. #define MOSI 11
  4. #define SS 10
  5. #define MISO 12
  6. int log_on_out;
  7. PN532 nfc(SCK, MISO, MOSI, SS);
  8. void setup(void)
  9. {
  10.   Serial.begin(9600);
  11.   Serial.println("Ola!");
  12.   Keyboard.begin();
  13.   nfc.begin();
  14.   uint32_t versiondata = nfc.getFirmwareVersion();
  15.   if (! versiondata)
  16.   {
  17.     Serial.print("Nao encontrou placa PN53x");
  18.     while (1); // halt
  19.   }
  20.     // Recebeu dados, hora de imprimir!
  21.     Serial.print("Chip PN5 encontrado"); Serial.println((versiondata>>24) & 0xFF, HEX);
  22.     Serial.print("Versao do Firmware: "); Serial.print((versiondata>>16) & 0xFF, DEC);
  23.     Serial.print('.'); Serial.println((versiondata>>8) & 0xFF, DEC);
  24.     Serial.print("Suporta "); Serial.println(versiondata & 0xFF, HEX);
  25.     // configura placa para ler RFID
  26.     nfc.SAMConfig();
  27. }
  28. void loop(void)
  29. {
  30.   uint32_t id;
  31.   // procura por cartoes
  32.   id = nfc.readPassiveTargetID(PN532_MIFARE_ISO14443A);
  33.   if (id != 0)
  34.   {
  35.     Serial.print("Read card #");
  36.     Serial.println(id);
  37.     // testa cartao
  38.     if(id==126074446)
  39.       {
  40.         Serial.println("Cartao certo!");
  41.       }
  42.       else
  43.         Serial.println("Cartao errado!");
  44.    
  45.     uint8_t keys[]= {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
  46.     if(nfc.authenticateBlock(1, id ,0x08,KEY_A,keys)) //autentica bloco 8 0x08
  47.     {
  48.     //se autenticou com sucesso
  49.     uint8_t block[16];
  50.     //faz leitura do bloco 0x08
  51.     if(nfc.readMemoryBlock(1,0x08,block))
  52.     {
  53.     //se operacao de leitura teve sucesso
  54.       for(uint8_t i=0;i<16;i++)
  55.       {
  56.         //imprime bloco de memoria
  57.         Serial.print(block[i],HEX);
  58.         Serial.print(" ");
  59.       }
  60.       // testa codigo bloco 0x08
  61.       if(block[0]==0 && block[1]==1 && block[2]==2 && block[3]==3)
  62.        {
  63.          Serial.println("Senha do bloco correta!");
  64.          
  65.          log_on_out = !log_on_out;
  66.         if(log_on_out==1)
  67.           {
  68.           // se for bloquear
  69.           // CTRL-ALT-DEL:
  70.           Keyboard.press(KEY_LEFT_CTRL);
  71.           Keyboard.press(KEY_LEFT_ALT);
  72.           Keyboard.press(KEY_DELETE);
  73.           delay(100);
  74.           Keyboard.releaseAll();
  75.           //ALT-s:
  76.           delay(2000);
  77.           Keyboard.press(KEY_LEFT_ALT);
  78.           Keyboard.press('l');
  79.           Keyboard.releaseAll();
  80.           // Enter to confirm logout:
  81.           Keyboard.write(KEY_RETURN);
  82.         }
  83.        
  84.         else if(log_on_out==0)
  85.           {
  86.           // se for desbloquear
  87.           Keyboard.press(KEY_BACKSPACE);
  88.           delay(1000);
  89.           Keyboard.print("1110");// sua senha do windows
  90.           }
  91.        }
  92.          else
  93.             Serial.println("Senha do bloco errada!");
  94.            
  95.       Serial.println();
  96.     }
  97.    }
  98.   }
  99.   delay(500);
  100. }


Leitura feita:

Found 1 tags
Sens Response: 0x4
Sel Response: 0x8
 0x7 0x83 0xBE 0x4ERead card #126074446
Cartao certo!
0 1 2 3 4 5 6 7 8 9 A B C D E F Senha do bloco correta!


Um vídeo para exemplificar o funcionamento:


Alterando o programa para funcionar no Windows 7, altere as linhas 68-104:

if(block[0]==0 && block[1]==1 && block[2]==2 && block[3]==3)
       {
         Serial.println("Senha do bloco correta!");
       
         log_on_out = !log_on_out;

        if(log_on_out==1)
          {
          // se for bloquear
          // CTRL-ALT-DEL:
          Keyboard.press(KEY_LEFT_CTRL);
          Keyboard.press(KEY_LEFT_ALT);
          Keyboard.press(KEY_DELETE);
          delay(100);
          Keyboard.releaseAll();
          //ALT-s:
          delay(2000);
          Keyboard.press(KEY_LEFT_ALT);
          Keyboard.press('l');
          Keyboard.releaseAll();
          // Enter to confirm logout:
          Keyboard.write(KEY_RETURN);
        }
     
        else if(log_on_out==0)
          {
          // se for desbloquear
          Keyboard.press(KEY_BACKSPACE);
          delay(1000);
          Keyboard.print("vr");// sua senha do windows
          Keyboard.write(KEY_RETURN);
          }
       }
         else
            Serial.println("Senha do bloco errada!");
         
      Serial.println();