Comunicação serial com arduino, convertendo o dado como inteiro, gera erro estranho a partir de 5 dígitos...

 Oi pessoal! estou com um probleminha em transformar a entrada serial em um numero int utilizável, li vários post aqui do fórum sobre isso, mas parece que meu problema é diferente, como um bug...
 Montei um programa teste que recebe a mensagem serial, delimitada por ''<'' e ''>'' e imprime no LCD 3 valores:

 1- numero recebido pela serial 
 2- numero recebido pela serial e transformado para int (não usei nada alem do ''='' por isso talvez esteja dando erro) 
 3- a soma do numero transformado para int + outro valor int (no caso 10) descrito no programa 

 O terceiro valor é um teste, para ver se o valor int esta mesmo sendo valido pelo arduino... 


 O problema, o terceiro valor sempre varia, parece randômico até! 
 O segundo valor parece estar tudo certo, até exceder 5 dígitos, depois disso ele fica negativo e parece randômico tbm...

 Por exemplo:


Se envio <1234> o que aparece no LCD é
  valor 1 é 1234
  valor 2 é 1234
  valor 3 é 12355

Se envio <12345> o que aparece no LCD é
  valor 1 é 12345
  valor 2 é 12345
  valor 3 é 1244

Se envio <123456> o que aparece no LCD é
  valor 1 é 123456
  valor 2 é -7616
  valor 3 é 12355


Se envio <9999> o que aparece no LCD é
  valor 1 é 9999
  valor 2 é 9999
  valor 3 é -7606

Se envio <99999> o que aparece no LCD é
  valor 1 é 99999
  valor 2 é -31073
  valor 3 é 10009

 Se alguém souber o que posso fazer para solucionar isso e transformar o valor que chega na serial valido para operações, agradeço muito! 
 
Segue o código:






#include <LiquidCrystal.h>
LiquidCrystal lcd(7, 6, 5, 4, 3, 2);

const char inicioNumero = '<';
const char finalNumero = '>';
int soma = 10;
int numero = 0;
int numeroObjetivos = 0;


void setup ()
{
lcd.begin(16, 2);
Serial.begin (9600);
lcd.setCursor(0, 0);
lcd.print("Aguardando");
lcd.setCursor(0, 1);
lcd.print("Numero");
}


void processoSoma()
{
numeroObjetivos = (numero + soma);
}


void processaNumero (const long n)
{
numero = (n); //aqui converto o numero recebido em int
lcd.clear();
lcd.setCursor(0, 0);
lcd.print (n); //imprime o numero recebido
lcd.setCursor(0, 1);
lcd.print (numero); //imprime o numero recebido transformado em int
lcd.setCursor(9, 1);
lcd.print (numeroObjetivos); //imprime o resultado da soma do numero
//transformado em int + 10 (apenas para testar uma operaçao em cima do valor)

}

void processInput ()
{
static long numeroRecebido = 0;


byte c = Serial.read ();

switch (c)
{

case finalNumero: //Manda o numero processado caso receba final de numeroo ''>''
processoSoma ();
processaNumero (numeroRecebido);

case inicioNumero: //Zera o numero se receber inicio de numero ''<''
numeroRecebido = 0;
break;

case '0' ... '9': //transforma ASCII em caracter valido
numeroRecebido *= 10;
numeroRecebido += c - '0';
break;

}
}

void loop ()
{

if (Serial.available ())
processInput ();

}

   

Exibições: 373

Responder esta

Respostas a este tópico

Quando insere o seu código no tópico, fica difícil para entender :


Sugestões de como "postar" no LdG por Rui Viana

O melhor jeito de descobrir um erro, é entender o que cada linha do seu programa faz e inserir comentários dessa explicação. 

Para que serve essa função ?

void processoSoma()
{
numeroObjetivos = (numero + soma);
}

Essa função esta correta ?

case '0' ... '9': //transforma ASCII em caracter valido
numeroRecebido *= 10;
numeroRecebido += c - '0';

O problema não está no código, vc está tentando colocar valores acima da capacidade dos inteiros. No arduino o tipo int tem 2 bytes, ou seja, 16 bits, sendo que 1 bit é reservado pra sinal, então o maior valor absoluto que vc consegue guardar em um int é 2^15, ou seja, 32768. Qualquer valor acima disso vai dar overflow. Troque todas as declarações de int por long que funciona.

Sugestão de código:

long numToSend = 1234567; // numero a enviar

byte buf[4]; // buffer para envio

buf= (byte*)&numToSend;

// agora vc tem em buf um array de 4 bytes, envie esse array

// do outro lado:

byte buf[4]; // receba os bytes na mesma sequencia que foram enviados

long numToRec, ptLong*;

ptLong= (long*)buf;

numToRec= *ptLong; // Agora numToRec armazena o mesmo valor que foi enviado.

RSS

© 2024   Criado por Marcelo Rodrigues.   Ativado por

Badges  |  Relatar um incidente  |  Termos de serviço