Go Down

Topic: GSM Shield (Read 1 time) previous topic - next topic

ruivotuga

Olá pessoal.

estou com um problema na programação das minhas necessidades e gostava de alguma ajuda se possível.

o que se passa: estou a montar um "sistema" por SMS em que o arduino comunica uma informação e gostaria que ele parasse até receber um SMS meu para continuar e que o meu número fosse o único autorizado. Isto porque quando ele obtêm a informação de uma fonte, continua a enviar SMS até a mesma fonte voltar ao estado "normal". Tenho um tempo defenido para o envio do SMS através do Arduino, mas passado esse tempo, ele reenvia o SMS.
A solução a meu ver, passa ou por um SMS a mandar parar ou alguma coisa na programação que diga ao Arduino para não voltar a ler aquele contacto até ele mudar de estado.
Vou deixar aqui embaixo o código que compilei até agora.

Obrigado!

#define ledVerm 13
 


 #include <SimpleTimer.h>
 #include <SoftwareSerial.h>
 SoftwareSerial SIM900(7, 8);

 
 int valor = 12;
 
 char incoming_char=0;
 int salir = 0;
 void setup()
    {

 pinMode(valor, INPUT);
 pinMode(ledVerm, OUTPUT);
 digitalWrite(valor, LOW);
 
 
 SIM900.begin(19200);
 delay(20000);
 Serial.begin(19200);
 Serial.println("Arranque Arduino e Modulo GSM com sucesso.");

 
 // MENSAGEM DE INÍCIO DE PROGRAMA CORRECTO
 
 SIM900.print("AT+CMGF=1\r");
 delay(100);
 SIM900.println("AT+CMGS=\"+351*********\""); internacional
 delay(100);
 SIM900.println("HELLO WORLD. Boot com sucesso de Arduino e GSM900.");
 delay(100);
 SIM900.println((char)26); // End AT command with a ^Z, ASCII code 26
 delay(100);
 SIM900.println();
 delay(5000);
 Serial.println("SMS enviada com sucesso.");
 delay(100);
 SIM900.println("AT+CMGS=\"+351*********\"");
 delay(100);
 SIM900.println("*******************************"); // Mensagem a enviar
 delay(100);
 SIM900.println((char)26); // End AT command with a ^Z, ASCII code 26
 delay(100);
 SIM900.println();
 //delay(5000);
 Serial.println("SMS enviada com sucesso.");
 

     }
 
 void loop()

 //FUNÇÃO PARA MANDAR SMS DE NÍVEL BAIXO

    {
    delay(100);
    valor = digitalRead(12);
    if (valor != LOW)
    {
   
     
  Serial.println("Nivel alto!");

 digitalWrite(ledVerm, HIGH);
 
 SIM900.print("AT+CMGF=1\r");
 delay(100);
 SIM900.println("AT+CMGS=\"+351*********\"");
 delay(100);
 SIM900.println("******************************"); // message to send
 delay(100);
 SIM900.println((char)26);
 delay(5000);
 SIM900.println();
 Serial.println("SMS URGENCIA ENVIADA.");
   
  delay(100);
  Serial.println("A aguardar reposicao de nivel");
  digitalWrite(ledVerm, HIGH);
  //while (valor != LOW)
  //{delay(500);


 
  }

  {
    delay(100);
    valor = digitalRead(12);
    if (valor != HIGH)
    digitalWrite(ledVerm, LOW);
    Serial.println("Nivel normal");
    delay(10000);
   
 


 
 
  }}

 // FIM DE PROGRAMA

bubulindo

Tu precisas de detectar o flanco e enviar uma mensagem quando  osinal mudar de estado e não enquanto estiver num certo estado.

Pesquisa nos meus posts que vais ver pelo menos um ou dois posts recentes com uma solução para isto.
This... is a hobby.

ruivotuga

Obrigado pela ajuda no meu problema.

Estive a dar uma espreitadela aos teus posts, e o que encontrei lá foi isto, que até era uma questão posta por mim, mas que não consegui implementar no código, devido à minha falta de conhecimentos.

Isso porque não consigo agora fazer intercalar este código com o meu, como dizer a ele que é o pino 12 que dá a informação?

já tentei #define 12, int 12 e dá sempre erro....


//fora da loop...
unsigned char botaoAntes = 0;
unsigned char botao = 0;

//dentro da loop...

botao = digitalRead(pinoBotao);

if ((botao == 1) && (botao != botaoAntes)) {//contacto activou e anteriormente o botao nao estava activo.
   //mete aqui o teu codigo de envio de mensagem.

}
botaoAntes = botao;

bubulindo

porque não adicionar esta linha em vez do que estavas a tentar fazer?

Code: [Select]
const unsigned int pinoBotao = 12;

Eu não indico os pinos a utilizar porque regra geral as pessoas já sabem os pinos e já viram exemplos de como a digitalRead funciona para perceber o resto.

Vê se funciona e dá notícias.
This... is a hobby.

ruivotuga

Desde já, obrigado pela ajuda tens dado.

Quando se é bastante cru nestes temas, por vezes aparecem dificuldades que não são nada fáceis de superar para quem não tem os conhecimentos que outras pessoas tem.

Já implementei como sugeriste, mas agora aparece-me outra coisa, diz-me que o "Botão" não foi declarado no scope.

Por aquilo que vi e li por aí, imagino que o "botao" tem que ser declarado antes em qualquer lado, mas ao tentar fazê-lo dá erro, e sendo já o "pinoBotao = 12", como posso fazer?

Não há jeito de sair desta?!?

Jeff_85

Quote
... Já implementei como sugeriste, mas agora aparece-me outra coisa, diz-me que o "Botão" não foi declarado no scope.
Acho que seria útil postar seu novo código com a alteração que fez. Poste entre tags </>.

bubulindo

O teu código deveria ter ficado parecido a isto:

Code: [Select]

//fora da loop...
const unsigned int pinoBotao = 12;
unsigned char botaoAntes = 0;
unsigned char botao = 0;

//dentro da loop...

botao = digitalRead(pinoBotao);

if ((botao == 1) && (botao != botaoAntes)) {//contacto activou e anteriormente o botao nao estava activo.
   //mete aqui o teu codigo de envio de mensagem.

}
botaoAntes = botao;



Nota que eu não uso em lado algum uma variável Botão. Uso sim uma variável botao que está definida e tem de de ser definida fora de qualquer função.
Acho que estás a confundir as duas coisas. A variável pinoBotao contém o pino que tu queres ler. A variável botao contém o estado do pino indicado em pinoBotao. Ou seja, pinoBotao será sempre 12, mas o estado do pino indicado na variavel botao pode ser 1 ou 0.

Coloca aqui o teu código como tens agora e a gente indica o que poderá estar mal... mas sinto que estás já perto do que pretendes.
This... is a hobby.

ruivotuga

Mais uma vez, obrigado pela ajuda que me tem prestado.

Tentei implementar o código e não dá erro.

Fiz este pequeno sketch para testes em que desejo que o led da placa do arduino (13) acenda quando pressiono o pushbutton na pino 12.

Tentei incorporar o código que forneceste, mas desta vez não dando erro, também ao testar o pino 12, nda acontece. Tentei adicionar delay porque pensei que fosse algo rápido demais para a vista, mas mesmo assim, nada acontece.

O que estará mal agora?!?


// teste

const int ledVerm = 13;
const unsigned int pinoBotao = 12;
unsigned char botaoAntes = 0;
unsigned char botao = 0;

void setup() {
 
pinMode(botao, INPUT);
pinMode(ledVerm, OUTPUT);
delay(1000);
digitalWrite(ledVerm, LOW);

}

void loop() {
  botao = digitalRead(pinoBotao);

if ((botao == 1) && (botao != botaoAntes)) {//contacto activou e anteriormente o botao nao estava activo.
   //mete aqui o teu codigo de envio de mensagem.
digitalWrite(ledVerm, HIGH);
delay(2000);

}
{
  delay(3000);
  botaoAntes = botao;

}}

ruivotuga

Entretanto ao olhar para o sketch, encontrei o que julgo ter inserido errado, substitui,

pinMode(botao, INPUT);

por

pinMode(pinoBotao, INPUT);

mas continua sem funcionar!

Jeff_85

A sugestão do programa apenas precisava de uns pequenos acertos, que eu presumo, você mesmo poderia ter debugado o código e verificado.

Quote
void loop() {
  botao = digitalRead(pinoBotao);

if ((botao == 1) && (botao != botaoAntes)) {//contacto activou e anteriormente o botao nao estava activo.
   //mete aqui o teu codigo de envio de mensagem.
digitalWrite(ledVerm, HIGH);
delay(2000);

}
{
  delay(3000);
  botaoAntes = botao;

}}
Além do programa ficar preso em 2 Delays, o LED apenas era ligado 01 vez, porque não há um comando para desligá-lo. E também só era ligado quando os 2 delays eram executados primeiros, fazendo você ter que segurar o botão para acionar o LED.

Fiz uma pequena alteração no seu código, logo abaixo segue:

Code: [Select]
const unsigned int  led_do_Arduino = 13; //LED do Arduino
const unsigned int  leitura_do_botao = 12;
unsigned char     estado_anterior_do_botao = 0;
unsigned char     estado_atual_do_botao = 0;

void setup()
{
  pinMode(leitura_do_botao, INPUT);
  pinMode(led_do_Arduino, OUTPUT);
  digitalWrite(led_do_Arduino, LOW);
}

void loop()
{
 
  estado_atual_do_botao = digitalRead(leitura_do_botao); //pino 12

  if ((estado_atual_do_botao == 1) && (estado_atual_do_botao != estado_anterior_do_botao)) //contacto activou e anteriormente o botao nao estava activo.
  {
   
    //mete aqui o teu codigo de envio de mensagem.
       
    digitalWrite(led_do_Arduino, HIGH);
    delay(2000);   
    digitalWrite(led_do_Arduino, LOW);
  }
    estado_anterior_do_botao = estado_atual_do_botao;
}


ATENÇÃO:
Escreva esse código numa folha de papel e vá com a caneta preenchendo ao lado os valores das variáveis e simule mentalmente o funcionamento. Dessa forma você vai entender e facilitará seu aprendizado.


ruivotuga

Obrigado pela ajuda que tem dado.

Testei este código no arduino, mas não faz nada, ou seja, o led do pin 13 permanece apagado.....

Não estou mesmo a perceber o que se passa!

Jeff_85

Eu testei e funcionou.

O programa é upado para o Arduino? Dá algum erro? Se você jogar o exemplo Blink funciona?

Você está usando um botão na entada correta ? Se não tiver um botão, use um resistor de pull down de 10k conectado no pino do botão (pino 12) para GND. Depois pegue um jumper do 5V e conecte rapidamente na entrada do botão para ver o led acender.

Teste e retorne aqui informando COM DETALHES.

Piscar LED (LED da placa do Arduino - pino 13):

Code: [Select]
// the setup function runs once when you press reset or power the board
void setup() {
  // initialize digital pin LED_BUILTIN as an output.
  pinMode(LED_BUILTIN, OUTPUT);
}

// the loop function runs over and over again forever
void loop() {
  digitalWrite(LED_BUILTIN, HIGH);   // turn the LED on (HIGH is the voltage level)
  delay(1000);                       // wait for a second
  digitalWrite(LED_BUILTIN, LOW);    // turn the LED off by making the voltage LOW
  delay(1000);                       // wait for a second
}

bubulindo

E se ele usar esta instrução

Code: [Select]
pinMode(leitura_do_botao, INPUT_PULLUP);


em vez de

Code: [Select]
pinMode(leitura_do_botao, INPUT);?

só tem de ligar um botão do pino 12 ao GND e usar este if

Code: [Select]

if ((estado_atual_do_botao == 0) && (estado_atual_do_botao != estado_anterior_do_botao))


Não sabemos como está tudo ligado e pode mesmo ser o botão que está no ar... ou pode ser uma polaridade errada.
This... is a hobby.

Jeff_85

E se ele usar esta instrução

Code: [Select]
pinMode(leitura_do_botao, INPUT_PULLUP);


em vez de

Code: [Select]
pinMode(leitura_do_botao, INPUT);?

só tem de ligar um botão do pino 12 ao GND e usar este if

Code: [Select]

if ((estado_atual_do_botao == 0) && (estado_atual_do_botao != estado_anterior_do_botao))


Não sabemos como está tudo ligado e pode mesmo ser o botão que está no ar... ou pode ser uma polaridade errada.

Sim, vai trabalhar para ele. Quis seguir a linha de pensamento dele, mas sua direção o conduzirá.

ruivotuga

Mais uma vez agradeço o auxilio que me tem dado na resolução deste meu quebra-cabeças. Eu sei que para algumas pessoas aqui no fórum, este que é um problema para mim, não o é para outras pessoas. E agradeço a quem se presta a ajudar, porque também eu espero ajudar no que puder, talvez muito pouco por agora, mas penso que no futuro possa contribuir com alguma coisa de construtivo, pelo menos com a dedicação e com algo que vá aprendendo pelo caminho da vida. Digo isto o jeff_85, porque em momento algum pedi seja a quem fosse para trabalhar para mim, apenas estou aqui para partilhar as minhas dúvidas, as minhas opiniões e como disse acima, a experiência que vá ganhando. Se fosse para alguém trabalhar para mim, não estava aqui há espera da disponibilidade de quem fosse, contratava e pronto. Acho que não é esse o objectivo de um fórum sobre este tema ou outros, mas mais uma vez digo que é essa a minha opinião.
Mas mesmo assim agradeço jeff_85 pelo auxilio prestado e nas minhas parcas capacidades, espero algum dia retribuir de algum modo.

Quanto à situação/problema que me afectava, está resolvido, não existia nenhum problema aparente com a minha placa arduino, porque testei em 2 Mega e em uma Uno e acontecia o mesmo. Mas com o auxilio do bubulindo, o qual agradeço a "paciência" e contributo em auxiliar com o conhecimento de quem ainda é mais que verde nestas andanças, consegui resolver o problema e ter a função que desejava. Muito obrigado bubulindo e jeff_85 pelo auxilio. A alteração do código de "pinMode(leitura_do_botao, INPUT);" para "pinMode(leitura_do_botao, INPUT_PULLUP); e alterando para "if ((estado_atual_do_botao == 0) && (estado_atual_do_botao != estado_anterior_do_botao))" resolveu de uma vez por todas.

Muito obrigado aos dois e podem ter a certeza que vou tentar ser um menbro assíduo deste fórum, mais que não seja comentando o que achar que deve ser comentado por mim.

Como tinha dito acima, sou muito novo nestas andanças do arduino, e admito com humildade que os conhecimentos são muito poucos como podem constatar, mas acho interessante, desafiador, e muito bom, comunidades como a que venho conhecendo por aqui, uma partilha de conhecimentos, de dúvidas e a prontidão de se tentar ajudar a quem caminha por aquilo que gosta e se apaixona.

Uma boa noite a todos, e a continuidade de bom sucesso nos vossos projectos.

Go Up