RESOLVIDO: Receber e tratar dados?

Boas cara amigos,

Tenho ja alguma experiência com PICs ( pic basic pro ) mas a pouco e pouco esta a me render a estes "bixinhos" :slight_smile: leia-se arduinos, espero a vossa melhor compreensão nas minhas duvidas de iniciante.
Gostaria da vossa ajuda (pequeno código exemplo desde o inicio) para guardar e tratar dados provenientes do serial monitor no ide do arduino.

Exemplo:

Envio do s.m. ;1234;5678 guardar o recebido e depois tratar ou seja saber que números estão nas 4 premiras posições, detectar o ";" como separação e inicio dos dados e depois tipo se os primeiros 4 numeros recebidos for 1234 envia para o s.m. um "OK".

( Eu sei fazer tudo isto em pic basic pro )

Muito obrigado a todos

Paulo

Exemplo 1;

void loop() {


if (Serial.available() > 3) {//temos dados que chegue: 
   if (Serial.read () == '1') {
      if (Serial.read () == '2') {
          if (Serial.read () == '3') {
             if (Serial.read () == '4') {
                 LCD.print("OK");
             }
          }
      }
   }
}
}

segundo exemplo

char pass [5];
int data; 
void loop() {

if (Serial.available() >8) { //assumir que o outro byte vem a caminho. 
    for (int i = 0; i<4; i ++) {
      pass[i] = Serial.read();
    }
    pas[4] = '\0'; //end string
    if ((strcmp(pass, "1234" == 0) && (Serial.read() == ';')) {//equal and the separator is good
       for (i = 0; i< 4; i++) {
           pass[i] = Serial.read(); } //get the number. 
       data = atoi(pass); 
       LCD.print( "OK "); 
       LCD.print(data); 

    } else {
        LCD.print("FAIL");
        }
   
}

Existem mais maneiras e maneiras mais eficientes de enviar dados... mas dão mais trabalho em ambos os lados da comunicacão.

Boas,

Antes de mais muito obrigado pela rápida resposta, o exemplo 2 é de facto o que necessito.
Tenho alguns erros ao compilar:

pas[4] = '\0'; //end string modifiquei para
pass[4] = '\0'; //end string julgo ser um lapso de escrita??

if ((strcmp(pass, "1234" == 0) && (Serial.read() == ';')) {//equal and the separator is good modifiquei para
if ((strcmp(pass, "1234" == 0) && (Serial.read() == ';'))) {//equal and the separator is good apenas julgo que faltava mais um )

for (i = 0; i< 4; i++) { agora este erro não sei como resolver ??

Peço uma vez mais aos Gurus ajuda.

Obrigado

Paulo

Eu respondi à pressa.... desculpa:

if ((strcmp(pass, "1234") == 0) && (Serial.read() == ';')) {
for (int i = 0; i< 4; i++) {

É assim que resolves o problema.

Boas,

Antes de mais muito obg pela atenção. O código não esta a funcionar e é pouco preciso ao inserir os números no terminal do arduino (ou seja nem sempre responde com o "FAIL" ) o "PASS OK!" que deveria sair quando eu enviasse ;1234 nao sai mesmo tentei enviar de varias formas ex. 1234 ou 1234; ou ;1234 ou ;1234;5678 mas nada aqui fica o codigo completo por favor alguem o teste para ver o que fiz de errado.

char pass [5];
int data; 

void setup()
{
  //Create Serial Object
  Serial.begin(9600);
  Serial.println("ARDUINO ON!");
}

void loop() {
  
 if (Serial.available() >8) { //assumir que o outro byte vem a caminho. 
    for (int i = 0; i<4; i ++) {
      pass[i] = Serial.read();
    }
    pass[4] = '\0'; //end string
    if ((strcmp(pass, "1234") == 0) && (Serial.read() == ';')) {//equal and the separator is good
  
       for (int i = 0; i< 4; i++) {
           pass[i] = Serial.read(); } //get the number. 
       data = atoi(pass); 
       Serial.println("PASS OK!");
       Serial.println(data); 
    } else {
       Serial.println("FAIL");
        }
   }  
}

Obrigado

Paulo

Esta linha:

 if (Serial.available() >8) { //assumir que o outro byte vem a caminho.

Indica que precisas de ter 8 bytes disponíveis no buffer para o programa funcionar. O programa vai bloquear e falhar se não tiver 9 bytes no buffer... ou seja, o que tu especificaste no início... 1234;2345. Envia uma string no formato XXXX;YYYY toda seguida e vais ver que funciona. Outra coisa a teres em atencão é se o Arduino enviar um indicador de fim de linha ,isso também vai confundir o código e apenas funcionar uma vez.

if (Serial.available() >8) { //assumir que o outro byte vem a caminho.
Você está mandando 1234; ou ;1234 e esperando que haja 8 caracteres disponíveis para entrar no IF.
Tente mandar 1234;000 ou mude para 4 ou 5 se pretende mandar o ; também

Boas,

O bug é quando insiro uma pass errada ex: 2222;4444 o código fica "bloqueado" e ao inserir a pass correcta 1234;5678 ele devolve "FAIL" , por favor testem.

Obrigado,

Paulo

Bom acho que entendi o problema, falta você remover todos os caracteres que recebeu da serial no primeiro envio e quando há "fail".
Pois se no segundo if do seu código se der "fail" os caracteres recebidos restantes, ficaram no buffer, criando lixo para a próxima vez que ler o buffer.
Bom, não tenho o Arduino para testar aqui, mas acho q após o "fail" você faz:

   .
   .
   .
else {
       Serial.println("FAIL");
       while(serial.avalaible()>0)
              {
              serial.read(); // Tira todos os caracteres do buffer.
              }
       }

ou

   .
   .
   .
else {
       Serial.println("FAIL");
       Serial.flush();
       }

Eu acho que o flush(), não é a função certa, mas fica como referência, a primeira opção é a que eu confiaria mais.

Obrigado amigo mas nao funciona =( . Mais alguma ideia amigos?

Bom, se não resolver até eu consertar meu arduino, eu testo isso.

Verificaste, como disse anteriormente, se é enviado um caracter de fim de linha? Na porta série do Arduino dá para escolher entre enviar caracteres ou não enviar nada. Escolhe não enviar nada.

Amigo, antes de TRATAR os dados no IF, manda para a serial o conteúdo da variável PASS, e verifica se está com o valor que você espera, se não estiver, vai saber o que está contido na variável e saber porque está dando erro...

bubulindo:
Verificaste, como disse anteriormente, se é enviado um caracter de fim de linha? Na porta série do Arduino dá para escolher entre enviar caracteres ou não enviar nada. Escolhe não enviar nada.

Boas amigo,

Eu tenho enviado como "no line ending" é assim? mas da erro apos meter uma vez a pass errada.
Tou tramado com isto lol

mmoscz:
Amigo, antes de TRATAR os dados no IF, manda para a serial o conteúdo da variável PASS, e verifica se está com o valor que você espera, se não estiver, vai saber o que está contido na variável e saber porque está dando erro...

Boas amigo,

ARDUINO ON!

1234  // meti a pass correcta e como esperado deu ok
PASS OK!
5667  

4444  // meti a pass errada e como esperado deu fail
FAIL

;888 // aqui voltei a meter pass correcta e sempre a dar erro
FAIL
8123
FAIL

depois de meter uma pass errada ele n volta a fazer a leitura correcta

Mas tens de mandar tudo junto...

1234;XXXX

Foi assim que explicaste. Não disseste que ias enviar a pass e depois numa trama completamente diferente ias enviar um valor que querias alterar.

Bom, aparentemente você não está limpando o buffer da serial do ARDUINO.
Tente mandar os testes assim
Senha correta: 1234;0000
Senha Incorreta: 1111;2222
E veja o que retorna quando mandar novamente 1234;0000

Assim você tem uma sistemática para os testes.
Eu assumo que
Quando mandou a senha CORRETA, mandou 1234;5667
Quando mandou a senha INCORRETA, mandou 4444;8888
Quando mandou a senha CORRETA novamente mandou 1234;5667

Então, quando fez o FOR para pegar novamente 4 caracteres, achando que ia pegar da senha correta, pegou os quatro caracteres subsequentes aos quatro caracteres da senha incorreta que eram ;888, e não a nova senha 1234.

bubulindo:
Mas tens de mandar tudo junto...

1234;XXXX

Foi assim que explicaste. Não disseste que ias enviar a pass e depois numa trama completamente diferente ias enviar um valor que querias alterar.

Boas amigo,

Eu tenho sempre mandado tudo junto 1234;XXXX mas n worka se tu propio exprimentares veras isso.

Obg.

mmoscz:
Bom, aparentemente você não está limpando o buffer da serial do ARDUINO.
Tente mandar os testes assim
Senha correta: 1234;0000
Senha Incorreta: 1111;2222
E veja o que retorna quando mandar novamente 1234;0000

Assim você tem uma sistemática para os testes.
Eu assumo que
Quando mandou a senha CORRETA, mandou 1234;5667
Quando mandou a senha INCORRETA, mandou 4444;8888
Quando mandou a senha CORRETA novamente mandou 1234;5667

Então, quando fez o FOR para pegar novamente 4 caracteres, achando que ia pegar da senha correta, pegou os quatro caracteres subsequentes aos quatro caracteres da senha incorreta que eram ;888, e não a nova senha 1234.

Boas amigo,

Como tenho de fazer para limpar o bufer?

obg

Obg

Eu já tinha mandado a unica forma que há para limpar o buffer.

else {
       Serial.println("FAIL");
       while(serial.avalaible()>0)
              {
              serial.read(); // Tira todos os caracteres do buffer.
              }
       }

Insira esse while após o seu Serial.println("FAIL"), isso vai retirar todos os caracteres disponíveis no buffer da serial.