LusoRobótica - Robótica em Português

Sistemas específicos => Arduino / AVR => Tópico iniciado por: FCarvalho5555 em 08 de Abril de 2014, 11:04

Título: Problema leitura trama
Enviado por: FCarvalho5555 em 08 de Abril de 2014, 11:04
Boas pessoal,

Quero enviar uma trama de 4 Bytes para o arduino [coordenadorID, sensorID, comando, fim] mas estou com uns problemas.

Envio da trama:
(https://lusorobotica.com/proxy.php?request=http%3A%2F%2Fi61.tinypic.com%2Faxfyo8.png&hash=8a751cb8e94f64f0e2bf2f01f74960226dbc7d3b)

O que o arduino vê:
(https://lusorobotica.com/proxy.php?request=http%3A%2F%2Fi60.tinypic.com%2F717hi8.png&hash=f79c4e301b5268d839d83e1fb3acf965cef12a9f)

O 0x61 0x62 0x63 0x66 estão correctos, não percebo é porque que aparecem aqueles 0xFF todos.

Código: [Seleccione]
byte idCoordenador = 0x61;
byte myID = 0x62;
byte fimTrama = 0x66;
byte trama[4];

void setup(){
  Serial.begin(9600);
}

void loop(){
  if(Serial.available()){
    for(int i = 0; i < sizeof(trama); i++){
      trama[i] = Serial.read();
    }
   
    for(int i = 0; i < sizeof(trama); i++){
      Serial.print(trama[i], HEX);
    }
  }
}
Título: Re: Problema leitura trama
Enviado por: jm_araujo em 08 de Abril de 2014, 11:48
Porque testas uma só vez o serial available.
Tens de testar para cada byte que sacas.

Edit: corrigir ortografia
Título: Re: Problema leitura trama
Enviado por: Njay em 08 de Abril de 2014, 11:57
Se o tipo byte tiver realmente só 1 byte de tamanho, esses FF é um "problema" do Serial.print na conversão para HEX . Experimenta Serial.print(trama[ i], DEC) para veres se não aparece 97989...
Título: Re: Problema leitura trama
Enviado por: FCarvalho5555 em 08 de Abril de 2014, 13:25
Já troquei para DEC e aparece o seguinte:

972552552559825525525599255255255102255255255
Título: Re: Problema leitura trama
Enviado por: senso em 08 de Abril de 2014, 14:10
Tens de fazer sempre serial.available cada vez que fazes uma leitura.
Título: Re: Problema leitura trama
Enviado por: Njay em 08 de Abril de 2014, 16:47
Faz lá

Serial.print(sizeof(byte), DEC);
Serial.println("");

e reporta o valor.
Título: Re: Problema leitura trama
Enviado por: jm_araujo em 08 de Abril de 2014, 17:28
O senso e eu já demos a solução.
O problema não é do print, é do código.
Título: Re: Problema leitura trama
Enviado por: senso em 08 de Abril de 2014, 17:36
Código: [Seleccione]
int HardwareSerial::read(void)
{
  // if the head isn't ahead of the tail, we don't have any characters
  if (_rx_buffer->head == _rx_buffer->tail) {
    return -1;
  } else {
    unsigned char c = _rx_buffer->buffer[_rx_buffer->tail];
    _rx_buffer->tail = (unsigned int)(_rx_buffer->tail + 1) % SERIAL_BUFFER_SIZE;
    return c;
  }
}

-1 numa variavel unsigned de 8 bits dá que valor?
0xFF

Portanto, é usar o available ver que valor retorna e ler só e apenas o numero de caracters que estão disponiveis, é para isso mesmo que o available existe.
Título: Re: Problema leitura trama
Enviado por: metRo_ em 08 de Abril de 2014, 17:39
O senso e eu já demos a solução.
O problema não é do print, é do código.

Exacto, o erro está no código. Tens que fazer algo deste genero:

Código: [Seleccione]
uint8_t size = 4;
uint8_t bytesRead = 0;
byte trama[size];

void setup(){
  Serial.begin(9600);
}

void loop(){
  if(Serial.available()){
      trama[bytesRead] = Serial.read();
      bytesRead++;
      if(bytesRead==4){
          for(int i = 0; i < size; i++)
             Serial.print(trama[i], HEX);
          bytesRead = 0;
      }
  }
}

Quando fazes o Serial.read() ele devolve o valor recebido e limpa o buffer e só o carrega quando fazes Serial.available().
Nota: o código feito aqui no post por isso é provável que não funciona assim directo.
Título: Re: Problema leitura trama
Enviado por: Njay em 08 de Abril de 2014, 17:54
Ah, pois é, é do available() . Tava a ver 4 "bytes" e isso tava a levar-me a pensar que podia ser do tamanho do tipo de dados, duh.
Título: Re: Problema leitura trama
Enviado por: FCarvalho5555 em 10 de Abril de 2014, 00:20
Com o código do metro consigo detectar a trama correctamente :)

Só que agora queria evoluir mais um bocado e estou com outro problema.
Quero enviar dois tipos de tramas:

Trama comando
Tamanho: 5 bytes
Cada campo corresponde a 1 byte
Campos: Tipo(0x21) | Origem | Destino | Comando | Fim(0x66)

Trama valores
Tamanho: 7 bytes
Cada campo corresponde a 1 byte
Campos: Tipo(0x23) | Origem | Destino | Valor1 | Valor2 | Valor3 | Fim(0x66)

O meu problema é que quando mando qualquer uma das tramas a primeira vez não tenho problema (Imprime que a trama x foi recebida), mas depois tento enviar de novo e já não funciona, ou seja, apenas funciona a primeira vez.

Código: [Seleccione]
byte tramaComando[5];
byte tramaValores[7];
int byteCounter = 0;
boolean flagComando = 0, flagValores = 0;
byte byteRead;

void setup(){
  Serial.begin(9600);
}

void loop(){
  if(Serial.available()){
    byteRead = Serial.read();
   
    if(byteRead == 0x21 && byteCounter == 0)
      flagComando = 1;
    else if(byteRead == 0x23 && byteCounter == 0)
      flagValores = 1;
   
    if(flagComando)
      tramaComando[byteCounter] = byteRead;
    else if(flagValores)
      tramaValores[byteCounter] = byteRead;
    byteCounter++;
   
    if(flagComando && byteCounter == 4){
      Serial.println("Trama comando recebida");
      flagComando = 0;
      byteCounter = 0;
    }
    else if(flagValores && byteCounter == 7){
      Serial.println("Trama valores recebida");
      flagValores = 0;
      byteCounter = 0;
    }
  }
}
Título: Re: Problema leitura trama
Enviado por: metRo_ em 10 de Abril de 2014, 01:36
faz um print do byteread e dos valores das flags para cada serial.read(). envia duas vezes a trama e coloca aqui o log
Título: Re: Problema leitura trama
Enviado por: jm_araujo em 10 de Abril de 2014, 10:53
Detetei alguns erros no código:


A trama comando é de 5 bytes e não 4 (segundo a tua especificação):
Código: [Seleccione]
if(flagComando && byteCounter == 4){
2º erro (e que causa o comportamento que vês se enviares uma trama de comando, por causa do 1º erro):
O código não está preparado para o primeiro byte a receber não ser comando ou valores (0x21 ou 0x23). Quando o primeiro byte que recebes é diferente, incrementas o byteCounter na mesma e ficas num estado sem saída.
Se mudares o:
Código: [Seleccione]
    byteCounter++;para:
Código: [Seleccione]
    if(flagComando || flagValores) byteCounter++;deve resolver.



Título: Re: Problema leitura trama
Enviado por: FCarvalho5555 em 11 de Abril de 2014, 00:40
Com a ajuda do jm_araujo o código já está a funcionar :)

Vou aproveitar e tirar mais uma dúvida, se eu quiser limpar o buffer da porta serie e visto que a função Serial.flush() foi alterado posso utilizar o seguinte código ?

Código: [Seleccione]
void limpaBuffer(){
  while(Serial.available() > 0){
    lixo = Serial.read();
  }
}
Título: Re: Problema leitura trama
Enviado por: FCarvalho5555 em 11 de Abril de 2014, 02:00
Mais uma dúvida, será possível pegar no inteiro que a função analogRead() devolve e passar aquilo para um byte (8 bits), visto também que a resolução da ADC do arduino é de 10bits
Título: Re: Problema leitura trama
Enviado por: senso em 11 de Abril de 2014, 13:12
uint8_t adc8bits = analogRead(canal) >> 2;

O >>2 é um shift right de 2 bits, o que isto quer dizer é que move o valor de 10 bits duas casas para o lado direito, ficando assim com 8 bits.
Título: Re: Problema leitura trama
Enviado por: FCarvalho5555 em 12 de Abril de 2014, 11:27
Ao fazer esta operação apenas vou perde resolução da minha ADC, ou seja, a ler o valor de determinado sensor o meu resultado não vai ser tão aproximado do real, correto?
Título: Re: Problema leitura trama
Enviado por: tarquinio em 12 de Abril de 2014, 14:29
Sim passas a ter um valor no intervalo [0, 255] em vez do intervalo [0, 1023].

Aquele bit shift de duas casas matemáticamente é o mesmo que dividir o valor por 4 e ignorar as casas decimais.