[RESOLVIDO] ARDUINO UNO + IComsat v1.0 shield SIM900 GSM

Antes de mais nada quero agradecer a todos que irão contribuir!

Recentemente comprei os seguintes placas:

  1. Arduino UNO``
  2. Shield SIM900 GSM/GPRS IComsat, Itead Studio (http://iteadstudio.com/store/images/produce/Shield/IComSat/icomsat%20V1.1_DS.pdf)

Configurei meu Shield GSM para que o Arduino possa utilizar qualquer uma das 08 portas que tenho no shield, bastou retirar os jumpers.

Minha idéia inicial e fazer um código que simplesmente permita que eu envie comando pelo SerialMonior e (tipo uma comando AT) e eu veja a resposta.

Além das portas, preciso configurar mais alguma coisa nesse Shield?
Consigo ligar o somente shield com um cabo Prolific USB-to-serial (em niveis TTL)? Se sim, posso alimentar o shield com o próprio cabo? Como devo ligar as saidas do cabos com o shield?

Anexo está a configuração dos jumpers para RX e TX.

Obrigado.

g7henrique: Configurei meu Shield GSM para que o Arduino possa utilizar qualquer uma das 08 portas que tenho no shield, bastou retirar os jumpers.

Os jumpers estão lá para escolheres as portas que pretendes utilizar... sem jumpers, não existe um contacto eléctrico entre ambas as placas, logo não funciona.

g7henrique: Minha idéia inicial e fazer um código que simplesmente permita que eu envie comando pelo SerialMonior e (tipo uma comando AT) e eu veja a resposta.

E para que precisas dum shield GSM? Podes fazer isso só com o Arduino. :|

g7henrique: Além das portas, preciso configurar mais alguma coisa nesse Shield? Consigo ligar o somente shield com um cabo Prolific USB-to-serial (em niveis TTL)? Se sim, posso alimentar o shield com o próprio cabo? Como devo ligar as saidas do cabos com o shield?

A documentação que colocaste aqui não é muito boa para sabermos se é preciso mais alguma coisa. De onde tiraste isto, não tinham exemplos que pudesses usar?

Que cabo é esse? Podes usar o Arduino (se tiver o chip em formato DIP), simplesmente tirando o chip do socket e configurando os jumpers como tem no manual para usares o Arduino como um meio de ligação ao PC.

Suponho que o mesmo seja feito com o tal Prolific, uma vez que ambos usam o mesmo chip para "falar" em USB.

Obrigado Edison,

Eu conectei o meu cabo e funcionou, também configurei as portas TX e RX com jumpers respectivamente nos terminais 0 e 1.
O Arduino UNO será usado no Shield GSM quando o código estiver pronto e minha intenção em conectar o cabo e para enviar comando mais rapidamente, sem a necessidade de inserir um código no microcontrolador do arduino todo vez que eu quiser enviar um comando, eu realmente não tenho familiaridade com o Arduino ainda.

Hoje utilizando comandos AT do módulo SIM900 eu consegui fazer ligações a partir do módulo.
Infelizmente tentei por diversas vezes enviar SMS, mas não tive sucesso. Os comandos AT que usei foram:

  1. AT
    resp. do modem: OK

  2. AT+CMGF=1
    resp. do modem: OK
    obs.: comando usado para configurar os SMS para TEXT MODE

  3. AT+CMGS=“9708xxxx”

TESTE <Ctrl+Z>
resp. do modem: o modem não responde e qualquer outro comando que eu envio após este não tem responda (travado?).

Tem algum erro de syntax ou é preciso alguma configuração de operadora (no caso uso VIVO)para o envio de SMS?
Alguma configuração do SIM card pode ocasionar está falha?

Já testei o cabo e verifiquei que está tudo certo.

Aguardo alguma ajuda.
Obrigado.

  1. AT+CMGS=“9708xxxx”

TESTE <Ctrl+Z>
resp. do modem: o modem não responde e qualquer outro comando que eu envio após este não tem responda (travado?).

Da minha experiencia com modem da simens que usa o mesmo AT command que esse Icomsat sugeria te primeiramente tentares enviar a sms usando um cliente de hiperterminal( eu uso o putty mas qualquer outro serve).
Desta forma e mais facil fazeres o debug e evitas a programaçao para ja no arduino.
Entao abres o putty com o baud rate correcto e fazes o seguinte:

Escreves at e enter
Deve te ser devolvido um ok
Depois escreves AT+CMGF=1 e enter (isto coloca o modem em modo texto)
Deves receber outro ok
Depois escreves AT+CMGS=96xxxxxxx e das ENTER (sem as aspas)
Logo de seguida ira te aparecer no ecra o simbolo > Escreves o teu sms logo aqui e no fim das no teclado CTRL+Z (primidas ao mesmo tempo) e desta forma terminas o texto
Deves receber tambem um ok no fim e a mensagem devera ser enviada
Esta e a forma de enviar no siemens mc 35i que apos uma breve analise me parece ter os mesmos AT commands como ja referi
Quando conseguires no hiperterminal enviar a sms entao depois e so pulares para a programaçao no arduino tentando repetir esses comandos via Serial.Write(para CTRL+Z) e para enviares texto Serial.Print
Espero ter ajudado
Bons estudos

Era isso que eu ia perguntar... como é que envias o Ctrl+Z. Olhando aos exemplos da biblioteca, isso consegue-se enviando o valor 0x1a.

De resto, tenta o comando para ver se tens rede, poderá ser uma situação dessas. :S

como é que envias o Ctrl+Z. Olhando aos exemplos da biblioteca, isso consegue-se enviando o valor 0x1a.

Eu usava Serial.write(0x1a);

HugoPT:

  1. AT+CMGS=“9708xxxx”

TESTE <Ctrl+Z>
resp. do modem: o modem não responde e qualquer outro comando que eu envio após este não tem responda (travado?).

Da minha experiencia com modem da simens que usa o mesmo AT command que esse Icomsat sugeria te primeiramente tentares enviar a sms usando um cliente de hiperterminal( eu uso o putty mas qualquer outro serve).
Desta forma e mais facil fazeres o debug e evitas a programaçao para ja no arduino.
Entao abres o putty com o baud rate correcto e fazes o seguinte:

Escreves at e enter
Deve te ser devolvido um ok
Depois escreves AT+CMGF=1 e enter (isto coloca o modem em modo texto)
Deves receber outro ok
Depois escreves AT+CMGS=96xxxxxxx e das ENTER (sem as aspas)
Logo de seguida ira te aparecer no ecra o simbolo > Escreves o teu sms logo aqui e no fim das no teclado CTRL+Z (primidas ao mesmo tempo) e desta forma terminas o texto
Deves receber tambem um ok no fim e a mensagem devera ser enviada
Esta e a forma de enviar no siemens mc 35i que apos uma breve analise me parece ter os mesmos AT commands como ja referi
Quando conseguires no hiperterminal enviar a sms entao depois e so pulares para a programaçao no arduino tentando repetir esses comandos via Serial.Write(para CTRL+Z) e para enviares texto Serial.Print
Espero ter ajudado
Bons estudos

Pessoal, obrigado pelas respostas;
Com ajude de você notei que o RogerCom, que é o terminal que estou usando, não envia o comando CTRL+Z por texto.
Foi possível enviar a mensagem configurando o terminal para enviar comandos do teclado e com isto bastou pressionar as teclas CTRL+Z, conforme o coleag HugoPT sugeriu.

Agora vou avançar com o código e de início preciso saber se o meu ARDUINO permite configurar duas portas RX e outras duas TX, sem sim como fica o código para isso?

No site da itead, de onde tiraste esse manual tem uma biblioteca para usares o shield através dos pinos que quiseres. É a newSoftSerial. Pesquisa no google. :slight_smile:

bubulindo: No site da itead, de onde tiraste esse manual tem uma biblioteca para usares o shield através dos pinos que quiseres. É a newSoftSerial. Pesquisa no google. :)

Obrigado, irei pesquisar. Mas na verdade eu não tenho problemas com a RX e TX do módulo GSM SIM900, a minha dúvida é a respeito do ARDUINO UNO. Preciso usar duas portas RX e duas TX no ARDUINO UNO, acretido que seja possível usar 4 portas digitais para fazer isso, sendo que 2 das 8 portas digitais já estão configuras como RX e TX nativas (ao que parece).

Como disse eu não tenho nenhuma familiaridade com o ARDUINO e sua programação, farei mais pesquisas e alguns códigos testes. Ao final, quando atingir meu objetivo vou postar meu projeto completo e este será um RASTREADOR GPS POR SMS, e o funcionamento do dispositivo se dá enviando um SMS para ele com um código de segurança (como gps) e quando este SMS chegar ao Rastreador ele verifica se o código de segurança está correto, se sim ele deve copiar o número do celular que fez a solicitação para uma variavel, em seguida são extraidos copiados os dados da TX do GPS de posição, data e hora para outra variável e um SMS com está informação é enviada para o numero que solicitou.

Parece fácil mas meu caminho até o final disso não será simples. Terei que estudar bastante.

A newsoftserial faz o que pretendes.

bubulindo: A newsoftserial faz o que pretendes.

Consegui usar esta biblioteca, no entanto notei que a SoftSerial já é suficiente para declarar duas portas RX e outras duas TX.

O meu problema mudou, eu estou parado num pedaço do meu código que se resume comparar o texto de um SMS, se este tiver um código o número dele é copiado.

O SMS chega porta na seguinte porta: SoftwareSerial gsm_com(2,3);

E a informação é lida é a seguinte:

AT+CMGR=1

+CMGR: "REC UNREAD","8273xxx","","12/10/19,22:08:18-12" SENHA

OK

Aqui começa meu problema, se esse SMS tiver a palavra SENHA é sinal que o sms é validado;

Se validado quero copiar o número para a seguinte variável

char phone_number[]=

Ao final a minha variável terá o seguinte valor char phone_number[]="8273xxx"

Caso o sms não tenha a senha este não se validado, sendo assim volto a esperar o um novo SMS.

Alguma idéia?

Obrigado a todos.

A newsoftserial, tanto quanto sei, é melhor.

Mais para o fim da manhã vejo a outra dúvida.

bubulindo: A newsoftserial, tanto quanto sei, é melhor.

Mais para o fim da manhã vejo a outra dúvida.

Sem problemas, podemos usar qualquer uma delas.

Irei aguardar a ajuda.

Obrigado amigo.

g7henrique:

bubulindo: A newsoftserial faz o que pretendes.

Consegui usar esta biblioteca, no entanto notei que a SoftSerial já é suficiente para declarar duas portas RX e outras duas TX.

O meu problema mudou, eu estou parado num pedaço do meu código que se resume comparar o texto de um SMS, se este tiver um código o número dele é copiado.

O SMS chega porta na seguinte porta: SoftwareSerial gsm_com(2,3);

E a informação é lida é a seguinte:

AT+CMGR=1

+CMGR: "REC UNREAD","8273xxx","","12/10/19,22:08:18-12" SENHA

OK

Aqui começa meu problema, se esse SMS tiver a palavra SENHA é sinal que o sms é validado;

Se validado quero copiar o número para a seguinte variável

char phone_number[]=

Ao final a minha variável terá o seguinte valor char phone_number[]="8273xxx"

Caso o sms não tenha a senha este não se validado, sendo assim volto a esperar o um novo SMS.

Tens de fazer string parsing. A SENHA, não vem dentro de aspas?

bubulindo:

g7henrique:

bubulindo: A newsoftserial faz o que pretendes.

Consegui usar esta biblioteca, no entanto notei que a SoftSerial já é suficiente para declarar duas portas RX e outras duas TX.

O meu problema mudou, eu estou parado num pedaço do meu código que se resume comparar o texto de um SMS, se este tiver um código o número dele é copiado.

O SMS chega porta na seguinte porta: SoftwareSerial gsm_com(2,3);

E a informação é lida é a seguinte:

AT+CMGR=1

+CMGR: "REC UNREAD","8273xxx","","12/10/19,22:08:18-12" SENHA

OK

Aqui começa meu problema, se esse SMS tiver a palavra SENHA é sinal que o sms é validado;

Se validado quero copiar o número para a seguinte variável

char phone_number[]=

Ao final a minha variável terá o seguinte valor char phone_number[]="8273xxx"

Caso o sms não tenha a senha este não se validado, sendo assim volto a esperar o um novo SMS.

Tens de fazer string parsing. A SENHA, não vem dentro de aspas?

Então, a SENHA não está entre aspas pois esta vem do SMS recebido que é lido na porta gsm_com, acho que o ideal seria colocar a informação do SMS em algum buffer mas eu não sei fazer isso e também não sei se este é o melhor caminho.

Também poderiamos declarar uma constante com a senha e verificar se na informação contém a senha.

Aguardo sua opnião.

Obrigado.

a biblioteca Serial já tem um buffer... O problema é definir exactamente onde começa a password. Se houvesse aspas antes da palavra senha (como acontece com a data e numero de telefone) seria mais simples de detectar isso. ;)

Isso que colocaste é um printout do que o módulo retorna se houver uma SMS?

bubulindo: a biblioteca Serial já tem um buffer... O problema é definir exactamente onde começa a password. Se houvesse aspas antes da palavra senha (como acontece com a data e numero de telefone) seria mais simples de detectar isso. ;)

Isso que colocaste é um printout do que o módulo retorna se houver uma SMS?

Sim, isso é o retorno do módulo na porta quando há SMS.

Dados recebidos na porta gsm_com

AT+CMGR=1

+CMGR: "REC UNREAD","8273xxx","","12/10/19,22:08:18-12" SENHA

OK

E se inserimos um caractér de controle (um @ que é 40 em hexadecimal, não tenho certeza)? A mensagem do SMS ficaria desta forma:

======================================================== AT+CMGR=1

+CMGR: "REC UNREAD","8273xxx","","12/10/19,22:08:18-12" @SENHA@

OK

Desta forma é possível? Não escolhi as aspas por não encontra-las em alguns modelos de celulares, mas pode ser uma opção.

Obrigado.

Ok… bom, podes contar o numero de aspas até à senha… ou ver quando é que é dado um \r ou \n.

while (Serial.read() != ','); //encontrar a virgula. 

for (int i= 0; i <= 7; i++) {
   phone_number[i] = Serial.read(); //passar o numero de telefone para a variavel. 
}

//encontrar o caracter de new line. 
while (Serial.read() != '\n'); //aqui vais ter de experimentar para ver se o telemóvel envia \n ou \r. 

//estamos prontos para testar a palavra passe... 
char temp;

for (int i = 0; i <= 7; i++) { //a senha tem no máximo 8 caracteres. 
   if ((temp = Serial.read()) != '\n') {  //aqui tambëm tens de ver qual e o caracter enviado... 
       senha[i] = temp;
   } else {
      //senha encontrada
      //d\a um termino na string
      senha [i] = '\0';
      break; //sai do for
   }
}

if (strcmp ("SENHA", senha) == 0){
 //password correcta
} else {
//password errada
}

bubulindo:
Ok… bom, podes contar o numero de aspas até à senha… ou ver quando é que é dado um \r ou \n.

while (Serial.read() != ','); //encontrar a virgula. 

for (int i= 0; i <= 7; i++) {
   phone_number[i] = Serial.read(); //passar o numero de telefone para a variavel.
}

//encontrar o caracter de new line.
while (Serial.read() != ‘\n’); //aqui vais ter de experimentar para ver se o telemóvel envia \n ou \r.

//estamos prontos para testar a palavra passe…
char temp;

for (int i = 0; i <= 7; i++) { //a senha tem no máximo 8 caracteres.
   if ((temp = Serial.read()) != ‘\n’) {  //aqui tambëm tens de ver qual e o caracter enviado…
       senha[i] = temp;
   } else {
      //senha encontrada
      //d\a um termino na string
      senha [i] = ‘\0’;
      break; //sai do for
   }
}

if (strcmp (“SENHA”, senha) == 0){
//password correcta
} else {
//password errada
}

Irei testar aqui.
Assim que tiver novidades te retorno.

Obrigado novamente.

bubulindo:
Ok… bom, podes contar o numero de aspas até à senha… ou ver quando é que é dado um \r ou \n.

while (Serial.read() != ','); //encontrar a virgula. 

for (int i= 0; i <= 7; i++) {
   phone_number[i] = Serial.read(); //passar o numero de telefone para a variavel.
}

//encontrar o caracter de new line.
while (Serial.read() != ‘\n’); //aqui vais ter de experimentar para ver se o telemóvel envia \n ou \r.

//estamos prontos para testar a palavra passe…
char temp;

for (int i = 0; i <= 7; i++) { //a senha tem no máximo 8 caracteres.
   if ((temp = Serial.read()) != ‘\n’) {  //aqui tambëm tens de ver qual e o caracter enviado…
       senha[i] = temp;
   } else {
      //senha encontrada
      //d\a um termino na string
      senha [i] = ‘\0’;
      break; //sai do for
   }
}

if (strcmp (“SENHA”, senha) == 0){
//password correcta
} else {
//password errada
}

Modifiquei um código para que o arduino envie comando ‘AT+CMGR=1’ apenas quando a a tx do gsm enviar ‘+CMTI: “SM”,1’, mas qualquer coisa que chega na rx do arduino ele responde enviando ‘AT+CMGR=1’, no código abaixo troquei o comando pelo texto “CHEGOU SMS”,

É possível fazer que uma parte do código espere que o módulo envie o comando ‘+CMTI: “SM”,1’ na porta rx do arduino e quando este comando chegar, e somente este, o código continua executando outra parte de código?

#include <SoftwareSerial.h> //Include the NewSoftSerial library to send serial commands to the cellular module.
#include <string.h>         //Used for string manipulations

char incoming_char=0;       //Will hold the incoming character from the Serial Port.

SoftwareSerial cell(2,3);   //Create a 'fake' serial port. Pin 2 is the Rx pin, pin 3 is the Tx pin.

void setup()
{
//Initialize serial ports for communication.
cell.begin(9600);

//Let's get started!
cell.println("Iniciando...");
}

void loop() {
//If a character comes in from the cellular module...
if(cell.available() >0)
{
if(cell.read() =='+CMTI: "SM",1'); //waiting sms from the cellular serial port. (GOSTARIA DE ESPERAR ESSE COMANDO E SOMENTE QUANDO CHEGAR PASSO A EXECUTAR O RESTO)
{
cell.println("CHEGOU SMS"); //Print text
cell.flush();
}
}
}