collapse

* Posts Recentes

Amplificador - Rockboard HA 1 In-Ear por almamater
[Ontem às 19:13]


O que é isto ? por KammutierSpule
[26 de Março de 2024, 19:35]


Bateria - Portátil por almamater
[25 de Março de 2024, 22:14]


Emulador NES em ESP32 por dropes
[13 de Março de 2024, 21:19]


Escolher Osciloscópio por jm_araujo
[06 de Fevereiro de 2024, 23:07]


TP4056 - Dúvida por dropes
[31 de Janeiro de 2024, 14:13]


Leitura de dados por Porta Serie por jm_araujo
[22 de Janeiro de 2024, 14:00]


Distancia Cabo por jm_araujo
[08 de Janeiro de 2024, 16:30]


Meu novo robô por josecarlos
[06 de Janeiro de 2024, 16:46]


Laser Engraver - Alguém tem? por almamater
[16 de Dezembro de 2023, 14:23]

Autor Tópico: Limpar Serial buffer  (Lida 12485 vezes)

0 Membros e 1 Visitante estão a ver este tópico.

Offline ivitro

  • Mini Robot
  • *
  • Mensagens: 451
Limpar Serial buffer
« em: 14 de Maio de 2013, 15:36 »
Olá a todos,

Preciso de alguma ajuda com a comunicação serie do arduino.

quero receber no arduino uma query deste tipo: @00RD0100000156*

Código: [Seleccione]
if (Serial.available() > 15) {
              for(int i=0; i<16;i++){
                incomingByte = Serial.read();
                string[i] = incomingByte;
              } 
              for(int i=0; i<16;i++){
                Serial.write(string[i]);
              }   
        }

assim já está a funcionar, mas se os dados forem menos que 15 como posso apagar os dados do buffer?


Offline tarquinio

  • Mini Robot
  • *
  • Mensagens: 529
Re: Limpar Serial buffer
« Responder #1 em: 14 de Maio de 2013, 16:37 »
Dantes a função flush() servia para isso, mas na versão 1.0 decidiram usá-la para outra coisa...
Podes fazer fácilmente uma função que faça isso, é sá fazeres reads while Serial.available()>0.

Mas neste tipo de coisas eu faria de modo a ler as coisas para um buffer no meu código, e processar a informação aí, em vez de tentar ler logo os 15 bytes de cada vez. Não sei que tipo de hardware/velocidades estás a usar, mas pode acontecer a mensagem às vezes vir dividida em duas. Basta pensares que se ele executar o serial.available() ao mesmo tempo que os dados estão a ser escritos, a mensagem está a meio logo vai dar menos de 15.

Eu faria algo do tipo (assumindo que o @ e o * são simbolos de inicio e fim de mensagem):
- Ter um buffer meu para ler as mensagens.
- Sempre que vem um byte  diferente de @ e *, escreve-lo no buffer se não estiver já cheio.
- Se vier um @, faz reset da posição do buffer para 0
- Se vier um *, ve se o buffer tem o numero de posições certo. Se tiver, faz o que tiver a fazer com os dados.

Offline ivitro

  • Mini Robot
  • *
  • Mensagens: 451
Re: Limpar Serial buffer
« Responder #2 em: 14 de Maio de 2013, 18:12 »
Olá,

A mensagem vou assumir nesta altura que vem se uma só vez.

Isto é para depois estar ligado a um raspberry 9600 de baudrate chega e sobra.

tou a tentar fazer como disseste mas ainda nao consegui meter alguma coisa de jeito a dar.

Offline tarquinio

  • Mini Robot
  • *
  • Mensagens: 529
Re: Limpar Serial buffer
« Responder #3 em: 14 de Maio de 2013, 19:14 »
Adaptei este código de uma aplicação minha:

Código: [Seleccione]
    char command_received[BUFFER_SIZE+1];
   
    // Isto no setup()
    int read_position = 0;

    // E isto onde for para ler
    if ( Serial.available() > 0 )
    {
        char incoming_byte = Serial.read();
        if (incoming_byte == '@')
        {
            read_position = 0;
        }
        else if (incoming_byte == '*')
        {
            // Fazer o que for para fazer aqui... Podes confirmar se read_position tem o tamanho esperado
        }
        else
        {
            if (read_position<BUFFER_SIZE) command_received[read_position++] = incoming_byte;
            command_received[read_position] = 0;
        }
    }

Isto faz a leitura dos comandos certinhos e se houver algum problema no envio de algum comando as coisas ficam certas outra vez logo no inicio do comando seguinte.
Não sei se o teu programa está a fazer mais coisas, mas se estiver apenas em loop à espera de comandos é fácil ele comecar a ler os dados quando ainda não foram todos transmitidos e não ler tudo do uma vez. O código que eu coloquei foi adaptado de um projecto em que acontecia precisamente isso.
« Última modificação: 14 de Maio de 2013, 19:18 por tarquinio »

Offline ivitro

  • Mini Robot
  • *
  • Mensagens: 451
Re: Limpar Serial buffer
« Responder #4 em: 15 de Maio de 2013, 15:00 »
Olá,

Segui mais ou menos o teu raciocínio e lá consegui meter isto a dar.. neste momento até estou a usar o bluetooth do telemóvel.


Código: [Seleccione]
void loop(){

  if(Serial.available()>0){
    incomingByte = Serial.read();
    if(incomingByte == '@' || index == 31)index = 0;
    inDataBuffer[index] = incomingByte;
    Serial.println(index);
    if(incomingByte == '*' && index ==15){
      index = 0;
      resposta();
    }
    index++;
  }
}

void resposta(){
  for(int i=0; i<=15;i++){
    Serial.print(inDataBuffer[i]);
  }
}

agora vou ver como meter o que recebo no serial.read() para um inteiro.

Offline tarquinio

  • Mini Robot
  • *
  • Mensagens: 529
Re: Limpar Serial buffer
« Responder #5 em: 15 de Maio de 2013, 23:25 »
Fazer as conversões não é difícil... O que é que representam os valores que vem na mensagem?
Uma coisa que tens de ter cuidado é garantir que as strings tem um zero no fim, senão as coisas podem correr mal... O codigo que eu coloquei acrescenta um zero no fim, mas o teu não... Isso pode causar problemas mais à frente.

Offline ivitro

  • Mini Robot
  • *
  • Mensagens: 451
Re: Limpar Serial buffer
« Responder #6 em: 16 de Maio de 2013, 10:50 »
Olá,

@00RD1234567812*

@00 -> é o endereço da máquina
RD, WR etc -> são os comandos
1234 -> endereço da operação
4568 -> depende do comando
12-> FCS (é o XOR de tudo o resto)
*-> Terminador

pode ser consultado aqui: http://www.tri-plc.com/HostlinkE10.pdf

para fazer o XOR dos 13 primeiros bytes basta fazer

Código: [Seleccione]
for(int i=0; i<=12;i++){
        XOR ^= inDataBuffer[i];
      }

está me a dar um valor diferente do que estou à espera. já tá corrigido!

como posso comparar o valor que obtenho no XOR com o valor que vem em ASCII?
« Última modificação: 16 de Maio de 2013, 11:53 por ivitro »

Offline tarquinio

  • Mini Robot
  • *
  • Mensagens: 529
Re: Limpar Serial buffer
« Responder #7 em: 16 de Maio de 2013, 11:59 »
Quanto é que dá e quanto é que estavas à espera?
Estás a considerar as bases? EU li o pfd um bocado na diagonal, mas pelo que vi aquilo calcula o XOR dos primeiros bytes e depois escreve o valor em base 16, não em decimal.

Offline ivitro

  • Mini Robot
  • *
  • Mensagens: 451
Re: Limpar Serial buffer
« Responder #8 em: 16 de Maio de 2013, 13:14 »
Exemplo:

Mando o seguinte @00RD0101772054*

ele faz o xor e dá 54 em base 16.
Só que o 54 que eu envio vai em ascii logo é 35 e 34 em hex.

os outro valores tambem queria passar para inteiros decimais tipo 0101 ser mesmo cento e um para eu poder fazer comparações.

Do lado do raspberry ainda não testei o comportamento porque só comecei a fazer agora o script.

Offline tarquinio

  • Mini Robot
  • *
  • Mensagens: 529
Re: Limpar Serial buffer
« Responder #9 em: 16 de Maio de 2013, 14:51 »
Para passares para inteiros é so copiares os caracteres para um buffer, por ex com strcpy() e depois fazeres atoi() desse buffer.
Quanto Às bases, acho ue fizeste praí alguma confusão...
Se é 54 em base 16 então terás de mandar o código ascii do 5 e do 4, mas isto costuma ser já em base 10.
Como é que estás a fazer o codigo exactamente para essa parte?

Offline ivitro

  • Mini Robot
  • *
  • Mensagens: 451
Re: Limpar Serial buffer
« Responder #10 em: 20 de Maio de 2013, 10:57 »
Não foi preciso fazer isso usei a uma função para passar para hex e depois fiz o resto de forma transparente.