Lettura byte da seriale

Buona sera a tutti, ho un problema:

ricevo sulla seriale di Arduino una fila continua di byte. Da questa fila continua devo identificare una serie di 4 byte che contengono il mio comando. Tre byte sono fissi e il 4° cambia a secondo del comando.

I primi tre byte sono 0x55, 0x78, 0x0 e il quarto byte che mi identifica il comando può essere 0xB o 0xB0 o 0xBB ecc. ecc.

Ho fatto parecchie prove ma con la seguente ho visto che se provo a leggere un byte per volta si perde i pezzi:

void loop(void)
{
  if (Serial2.available() > 0)
  {
    inByte = Serial2.read();
    //Serial.println(inByte, HEX);  //<--- qui legge tutti i byte
    
   if (inByte == 0x55)
    {
      indexByteMessaggio = 0;
    }
    messaggio[indexByteMessaggio] = inByte;
    indexByteMessaggio = indexByteMessaggio + 1;
  }
  Serial.print (messaggio[0], HEX); // <--- qui si perde i pezzi
  Serial.print (messaggio[1], HEX); 
  Serial.print (messaggio[2], HEX); 
  Serial.println (messaggio[3], HEX); 

  if (messaggio[0] == 55 && messaggio[1] == 78 && messaggio[2] == 0 && messaggio[3] == 0)
  {
    messaggio[4] = comando;
  
    }

Stavo pensando che se al posto di leggere un byte per volta io leggessi un blocco di 64 byte per poi passare ad analizzarli per estrarre il comando e successivamente andare a rileggere i 64 byte.....e il ciclo si ripete, non dovrei perdere pezzi. La serie di byte che mi interessano e che contengono il comando vengono continuamente inviati dalla sorgente. Qualsiasi consiglio è ben accetto. Grazie

Il baud rate dei due oggetti è lo stesso? Se il baud rate di Arduino è più basso di quello della sorgente rendilo pari ad esso.

Probabilmente i byte arrivano giusti, secondo me manca solo una corretta logica di sincronizzazione. Va benissimo leggere un byte alla volta, ma la ricezione attraversa vari stati che vanno gestiti, solo la sequenza corretta deve “passare”, e deve essere riconosciuta in mezzo a qualsiasi altra sequenza.

Il seguente diagramma rappresenta i quattro stati possibili, ad ogni byte ricevuto va eseguito lo stato corrente (all’avvio sarà impostato a zero):

ricezione-a-stati.png

Potrebbe anche essere un problema di overflow del buffer di ricezione (non so in quanto gira un ciclo di loop). In tal caso basterebbe gestire tutti i byte arrivati finora:

void loop(void)
{
    while(Serial2.available())
    {
        inByte = Serial2.read();
        ....
    }
}

Io sono ancora in ferie, impossibile per me dare consigli operativi Comunque ne posso dare di analitici:

if (messaggio[0] == 55 && messaggio[1] == 78 && messaggio[2] == 0 && messaggio[3] == 0) occhio che 55 non è uguale a 0x55, Perché due volte 0? Se poi ci pensi un attimo, siccome al ricevere un 0x55 tu azzeri l'indice, in posizione 0 troverai sempre 0x55, ci sarà sempre scritto solo quello E da qui discendono due cose La prima condizione scritta nello if sarebbe inutile, se fosse scritta giusta Siccome invece è scritta sbagliata rende impossibile lo if, che non sarà mai eseguito....

messaggio[4] = comando; Semmai sarà l'opposto...

Messaggi lunghi 4 byte, ma array con indice 4? Non sarebbe ora di smetterla di fare questo errore?

Come fai a dire, alla prima riga di stampa, che li perdi pezzi? Se non svuoti mai lo array troverai sempre scritto qualcosa, come fai a dire che hai perso qualcosa che trovi scritto?

E aggiungo: Si tratta di comunicazione su linbus a 4800bps correggo 9600 Occupa una frazione trascurabile della Potenza di calcolo disponibile sulla DUE in uso Il problema non è li, ma nel riconoscimento e interpretazione dei dati

Grazie a tutti per le risposte!

Si, il boud rate è lo stesso, 9600.

Un codice a stati è quello che ho provato a fare però quando ricevo il primo byte 55 devo ricevere subito dopo il secondo 78, non è che devo mettermi in attesa che venga trasmesso perchè sicuramente in altre stringhe potrebbe comprire. Sopratutto con il terzo byte che è uno 0. La cosa funziona se arrivano uno dietro l'altro 55 78 0 e a questo punto leggo il 4° che mi dice il comando. 55 78 0 0 è il comando tutto spento.

Mi scuso per l'esempio che ho postato con vari errori perchè nei vari tentativi che ho fatto provavo a cambiare le variabili da byte a char e i byte da 0x55 a 55 per vedere cosa cambiava nelle letture. Ho provato anche il Serial.read e il Serial.readBytes e tutto quello che ho trovato nelle varie discussioni attinenti del forum.

Quando dico che "perdo i pezzi" è perchè se stampo la variabile inbyte all'inizio del codice trovo le sequenze di byte che mi servono mentre quando vado a stampare l'array non trovo la sequenza che cerco.

Ora ho fatto una cosa più "scientifica" con il codice seguente ho fatto due prove. Prima ho stampato i byte ricevuti sulla serial2 poi ho stampato gli stessi byte ma dentro un array di 12 byte.

int i = 0;
byte inByte [12] = { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0};

void loop()
{
  if (Serial2.available()>0)
  {
    for ( i=0; i<12 ; i++) 
    {
    inByte [i] = Serial2.read ();
    Serial.print ( inByte [i], HEX);   // <--------- PRIMA PROVA
    
/*    Serial.print ( inByte  [0], HEX); //  <--------- SECONDA PROVA
    Serial.print (" ");
    Serial.print ( inByte [1], HEX); <--------- SECONDA PROVA
    Serial.print (" ");
    Serial.print ( inByte [2], HEX); <--------- SECONDA PROVA
    Serial.print (" ");
    Serial.print ( inByte [3], HEX); <--------- SECONDA PROVA
    Serial.print (" ");
    Serial.print ( inByte [4], HEX); <--------- SECONDA PROVA
    Serial.print (" ");
    Serial.print ( inByte [5], HEX); <--------- SECONDA PROVA
    Serial.print (" ");
    Serial.print ( inByte [6], HEX); <--------- SECONDA PROVA
    Serial.print (" "); 
    Serial.print ( inByte [7], HEX); <--------- SECONDA PROVA
    Serial.print (" ");
    Serial.print ( inByte [8], HEX); <--------- SECONDA PROVA
    Serial.print (" ");
    Serial.print ( inByte [9], HEX); <--------- SECONDA PROVA
    Serial.print (" ");
    Serial.print ( inByte [10], HEX); <--------- SECONDA PROVA
    Serial.print (" ");
    Serial.println ( inByte [11], HEX); <--------- SECONDA PROVA
*/
     }

Questo il risultati della 1° prova. Li ho incolonnati io partendo dal 55:

55394004001010005F0
557800000000FFFFFF0
55B4FF0FFFFFFFFFFFF
55B1040003838084CA0
55394004001010005F0FF
55780080000007FFF0
55B4FF0FFFFFFFFFFFF
55B1040003838084CA0
55394004001010005F0FF
55780080000007FFF0
55B403000000FCFFFF0
55B1040003838084CA0
55394004001010005F0FF
55780080000007FFF0
55B403000000FC0FFFF
55B1040003838084CA0
55394004001010005F0FF
55780080000007FFF0
55B403000000FCFFFF0
55B1040003838084CA0
55394004001010005F0
55780080000007FFFFF0
55B403000000FCFFFF0
55B1040003838084CA0
55394004001010005F0
55780080000007FFFFF0
55B403000000FC0FFFF
55B1040003838084CA0
55394004001010005F0
55780080000007FFFFF0
55B403000000FCFFFF0
55B1040003838084CA0
55394004001010005F0
55780080000007FFFFF0
55B403000000FCFFFF0
55B1040003838084CA0
55394004001010005F0
55780080000007FFFFF0
55B403000000FC0FFFF
55B1040003838084CA0
55394004001010005F0
55780080000007FFFFF0
55B403000000FCFFFF0
55B1040003838084CA0
55394004001010005F0
55780080000007FFF0FF
55B403000000FCFFFF0

Questo il risultato della seconda prova:

B1 0 40 0 0 38 38 0 0 4F 0 55
B1 0 40 0 0 38 38 0 0 4F 0 55
B1 0 40 0 0 38 38 0 0 4F 0 55
39 0 40 0 0 38 38 0 0 4F 0 55
39 40 40 0 0 38 38 0 0 4F 0 55
39 40 0 0 0 38 38 0 0 4F 0 55
39 40 0 40 0 38 38 0 0 4F 0 55
39 40 0 40 0 38 38 0 0 4F 0 55
39 40 0 40 0 10 38 0 0 4F 0 55
39 40 0 40 0 10 10 0 0 4F 0 55
39 40 0 40 0 10 10 0 0 4F 0 55
39 40 0 40 0 10 10 0 0 4F 0 55
39 40 0 40 0 10 10 0 0 5F 0 55
39 40 0 40 0 10 10 0 0 5F 0 55
39 40 0 40 0 10 10 0 0 5F 0 55
78 40 0 40 0 10 10 0 0 5F 0 55
78 0 0 40 0 10 10 0 0 5F 0 55
78 0 0 40 0 10 10 0 0 5F 0 55
78 0 0 0 0 10 10 0 0 5F 0 55
78 0 0 0 0 10 10 0 0 5F 0 55
78 0 0 0 0 0 10 0 0 5F 0 55
78 0 0 0 0 0 0 0 0 5F 0 55
78 0 0 0 0 0 0 0 0 5F 0 55
78 0 0 0 0 0 0 0 0 5F 0 55
78 0 0 0 0 0 0 0 0 FF 0 55
78 0 0 0 0 0 0 0 0 FF 0 55
78 0 0 0 0 0 0 0 0 FF 0 55
B4 0 0 0 0 0 0 0 0 FF 0 55
B4 0 0 0 0 0 0 0 0 FF 0 55
B4 0 55 0 0 0 0 0 0 FF 0 55
B4 0 55 B1 0 0 0 0 0 FF 0 55
B4 0 55 B1 0 0 0 0 0 FF 0 55
B4 0 55 B1 0 40 0 0 0 FF 0 55
B4 0 55 B1 0 40 0 0 0 FF 0 55
B4 0 55 B1 0 40 0 0 0 FF 0 55
B4 0 55 B1 0 40 0 0 38 FF 0 55
B4 0 55 B1 0 40 0 0 38 38 0 55
B4 0 55 B1 0 40 0 0 38 38 0 55
B4 0 55 B1 0 40 0 0 38 38 0 84
CA 0 55 B1 0 40 0 0 38 38 0 84
CA 0 55 B1 0 40 0 0 38 38 0 84
CA 0 55 B1 0 40 0 0 38 38 0 84
CA 0 55 39 0 40 0 0 38 38 0 84
CA 0 55 39 40 40 0 0 38 38 0 84
CA 0 55 39 40 0 0 0 38 38 0 84
CA 0 55 39 40 0 40 0 38 38 0 84
CA 0 55 39 40 0 40 0 38 38 0 84
CA 0 55 39 40 0 40 0 10 38 0 84
CA 0 55 39 40 0 40 0 10 10 0 84
CA 0 55 39 40 0 40 0 10 10 0 84
CA 0 55 39 40 0 40 0 10 10 0 0
5F 0 55 39 40 0 40 0 10 10 0 0
5F 0 55 39 40 0 40 0 10 10 0 0
5F 0 55 39 40 0 40 0 10 10 0 0
5F 0 55 78 40 0 40 0 10 10 0 0
5F 0 55 78 0 0 40 0 10 10 0 0
5F 0 55 78 0 0 40 0 10 10 0 0
5F 0 55 78 0 0 80 0 10 10 0 0
5F 0 55 78 0 0 80 0 10 10 0 0
5F 0 55 78 0 0 80 0 0 10 0 0
5F 0 55 78 0 0 80 0 0 0 0 0
5F 0 55 78 0 0 80 0 0 0 0 0
5F 0 55 78 0 0 80 0 0 0 0 0
7F 0 55 78 0 0 80 0 0 0 0 0
7F 0 55 78 0 0 80 0 0 0 0 0
7F 0 55 78 0 0 80 0 0 0 0 0
7F 0 55 B4 0 0 80 0 0 0 0 0
7F 0 55 B4 0 0 80 0 0 0 0 0
7F 0 55 B4 0 3 80 0 0 0 0 0
7F 0 55 B4 0 3 0 0 0 0 0 0
7F 0 55 B4 0 3 0 0 0 0 0 0
7F 0 55 B4 0 3 0 0 0 0 0 0
7F 0 55 B4 0 3 0 0 0 0 0 0
7F 0 55 B4 0 3 0 0 0 0 0 0
7F 0 55 B4 0 3 0 0 0 0 0 0
FC 0 55 B4 0 3 0 0 0 0 0 0
FC 0 55 B4 0 3 0 0 0 0 0 0
FC 0 55 B4 0 3 0 0 0 0 0 0
FC 0 55 B1 0 3 0 0 0 0 0 0
FC 0 55 B1 0 3 0 0 0 0 0 0
FC 0 55 B1 0 40 0 0 0 0 0 0
FC 0 55 B1 0 40 0 0 0 0 0 0
FC 0 55 B1 0 40 0 0 0 0 0 0
FC 0 55 B1 0 40 0 0 38 0 0 0
FC 0 55 B1 0 40 0 0 38 38 0 0
FC 0 55 B1 0 40 0 0 38 38 0 0
FC 0 55 B1 0 40 0 0 38 38 0 84
CA 0 55 B1 0 40 0 0 38 38 0 84
CA 0 55 B1 0 40 0 0 38 38 0 84
CA 0 55 B1 0 40 0 0 38 38 0 84
CA 0 55 39 0 40 0 0 38 38 0 84
CA 0 55 39 40 40 0 0 38 38 0 84
CA 0 55 39 40 0 0 0 38 38 0 84
CA 0 55 39 40 0 40 0 38 38 0 84
CA 0 55 39 40 0 40 0 38 38 0 84
CA 0 55 39 40 0 40 0 10 38 0 84
CA 0 55 39 40 0 40 0 10 10 0 84
CA 0 55 39 40 0 40 0 10 10 0 84
CA 0 55 39 40 0 40 0 10 10 0 0
5F 0 55 39 40 0 40 0 10 10 0 0
5F 0 55 39 40 0 40 0 10 10 0 0
5F 0 55 39 40 0 40 0 10 10 0 0
5F 0 55 78 40 0 40 0 10 10 0 0
5F 0 55 78 0 0 40 0 10 10 0 0
5F 0 55 78 0 0 40 0 10 10 0 0
5F 0 55 78 0 0 80 0 10 10 0 0
5F 0 55 78 0 0 80 0 10 10 0 0
5F 0 55 78 0 0 80 0 0 10 0 0
5F 0 55 78 0 0 80 0 0 0 0 0
5F 0 55 78 0 0 80 0 0 0 0 0
5F 0 55 78 0 0 80 0 0 0 0 0
7F 0 55 78 0 0 80 0 0 0 0 0
7F 0 55 78 0 0 80 0 0 0 0 0
7F 0 55 78 0 0 80 0 0 0 0 0
7F 0 55 B4 0 0 80 0 0 0 0 0
7F 0 55 B4 0 0 80 0 0 0 0 0
7F 0 55 B4 0 3 80 0 0 0 0 0
7F 0 55 B4 0 3 0 0 0 0 0 0
7F 0 55 B4 0 3 0 0 0 0 0 0
7F 0 55 B4 0 3 0 0 0 0 0 0
7F 0 55 B4 0 3 0 0 0 0 0 0
7F 0 55 B4 0 3 0 0 0 0 0 0
7F 0 55 B4 0 3 0 0 0 0 0 40
0 0 55 B4 0 3 0 0 0 0 0 40
0 0 55 B4 0 3 0 0 0 0 0 40
0 0 0 B4 0 3 0 0 0 0 0 40
0 0 0 55 0 3 0 0 0 0 0 40
0 0 0 55 0 3 0 0 0 0 0 40
0 0 0 55 0 0 0 0 0 0 0 40
0 0 0 55 0 0 0 0 0 0 0 40
0 0 0 55 0 0 0 10 0 0 0 40
0 0 0 55 0 0 0 10 55 0 0 40
0 0 0 55 0 0 0 10 55 0 0 40
0 0 0 55 0 0 0 10 55 0 0 40
0 0 0 55 0 0 0 10 55 0 0 55
0 0 0 55 0 0 0 10 55 0 0 55
0 0 0 55 0 0 0 10 55 0 0 55
0 0 55 55 0 0 0 10 55 0 0 55
0 0 55 0 0 0 0 10 55 0 0 55
0 0 55 0 0 0 0 10 55 0 0 55
0 0 55 0 0 55 0 10 55 0 0 55
0 0 55 0 0 55 FC 10 55 0 0 55
0 0 55 0 0 55 FC 0 55 0 0 55
0 0 55 0 0 55 FC 0 0 0 0 55
0 0 55 0 0 55 FC 0 0 CA 0 55
0 0 55 0 0 55 FC 0 0 CA 0 55
0 0 55 0 0 55 FC 0 0 CA 0 0
void loop()
{
  //quando ci sono almeno 12 byte
  if(Serial2.available() >= 12)
  {
    //leggili
    for(i=0; i<12 ; i++) inByte[i] = Serial2.read ();

    //stampali
    for(i=0; i<11 ; i++) Serial.print(inByte[i], HEX);
    Serial.println(inByte[11], HEX);
  }    
}
//affinche'il buffer non si riempia perdendo byte
//il loop deve girare con un ritardo medio
//mai superiore ai 12.5ms

Grazie Claudio, si così leggo correttamente:

C0055B104000383800
4F05539400400101000
5F05578008000000
7F055B403000000
FC055B1040003838084
CA05539400400101000
5F05578008000000
7F055B403000000
FC055B1040003838084
CA05539400400101000
5F05578008000000
7F055B403000000
FC055B1040003838084
CA05539400400101000
5F05578008000000
7F055B403000000
FC055B1040003838084
CA05539400400101000
5F05578008000000
7F055B403000000
FC055B1040003838084
CA05539400400101000

Speravo che il byte 55 fosse sempre alla i=2 e il 78 alla i=3 in modo che il mio comando fosse sempre alla i= 5 ma nell'inserire il tuo codice nel programma definitivo ho visto che i byte cambiano posizione.

Ho provato il codice così ma non mi trova il comando:

void loop()
{
  if (Serial2.available() >= 12)
  {
    for (i = 0; i < 12 ; i++) inByte[i] = Serial2.read ();
    {
      for (i = 0; i < 11 ; i++) Serial.print(inByte[i], HEX);
      Serial.println(inByte[11], HEX); 
      
      if (inByte[i] == 0x55 && inByte [i+1] == 0x78 )
      {
        comando = inByte[i+3], HEX;
        Serial.println(comando, HEX);
      }

Scusate la domanda, dal furbofono e in aeroporto con l'aereo per tornare a casa in ritardo Quindi ve la prendete un po' nuda e cruda: Cosa non vi è chiaro di: in una trasmissione linbus lo start è lo 0x55? Preceduto da almeno 13 bit a zero

Certo che mi è chiaro ma come faccio a iniziare l'array con lo 0x55? Ho provato con :

if (Serial2.available() == 0x55) ecc.ecc.

ma non funziona.

Perché hai sbagliato da altre parti E te le avevo anche indicate

Ora provo. Grazie e buon rientro

Non capisco. Questo è il codice:

void loop()
{
  if (Serial2.available() == 0x55)
  {
    for (i = 0; i < 12 ; i++) inByte[i] = Serial2.read ();
    {
      for (i = 0; i < 11 ; i++) Serial.print(inByte[i], HEX);
      //Serial.println(inByte[11], HEX);                          <-----stampa 1
      if (inByte[2] == 0x55 && inByte [3] == 0x78 )
      {
        comando = inByte[4], HEX;
        Serial.println(comando, HEX);  <------- stampa 2
      }

Questa è la stampa 1

 C0055B104000383800
4F05539400400101000
5F05578008000000
7F055B403000000
FC055B1040003838084
CA05539400400101000
5F05578008000000
7F055B403000000
FC055B1040003838084
CA05539400400101000
5F05578008000000
7F055B403000000
FC055B1040003838084
CA05539400400101000
5F05578008000000
7F055B403000000
FC055B1040003838084
CA05539400400101000

e questa la stampa 2

C0055B104000383804F05539400400101005F05578008000000
7F055B40300000FC055B10400038380CA05539400400101005F05578008000000
7F055B40300000FC055B10400038380CA05539400400101005F05578008000000
7F055B40300000FC055B10400038380CA05539400400101005F05578008000000
7F055B40300000FC055B10400038380CA05539400400101005F05578008000000
7F055B40300000FC055B10400038380CA05539400400101005F05578008000000
7F055B40300000FC055B10400038380CA05539400400101005F05578008000000
7F055B40300000FC055B10400038380CA05539400400101005F05578008000000

PM68: Un codice a stati è quello che ho provato a fare però quando ricevo il primo byte 55 devo ricevere subito dopo il secondo 78, non è che devo mettermi in attesa che venga trasmesso perchè sicuramente in altre stringhe potrebbe comprire. Sopratutto con il terzo byte che è uno 0. La cosa funziona se arrivano uno dietro l'altro 55 78 0 e a questo punto leggo il 4° che mi dice il comando. 55 78 0 0 è il comando tutto spento.

La procedura che ho scritto al post #2 serve appunto a fare tutto questo e senza alcun array (usare l'array è più complesso perché si devono anche gestire gli indici, controllare di non sbordare oltre i limiti ecc).

Quando dico che "perdo i pezzi" è perchè se stampo la variabile inbyte all'inizio del codice trovo le sequenze di byte che mi servono mentre quando vado a stampare l'array non trovo la sequenza che cerco.

I byte vengono ricevuti giusti, è l'array che viene caricato male e (ri)letto peggio.

Speravo che il byte 55 fosse sempre alla i=2 e il 78 alla i=3 in modo che il mio comando fosse sempre alla i= 5 ma nell'inserire il tuo codice nel programma definitivo ho visto che i byte cambiano posizione.

Il mio codice mostra solo come ricevere, scrivere nell'array e rileggere correttamente dall'array 12 byte (e solo quando sono effettivamente stati ricevuti). Non essendoci alcuna sincronizzazione è ovvio che le sequenze possono comparire ovunque, anche spezzate su due array.

Speravo che l'esempio rendesse chiaro l'uso di Serial.available(), ma invece:

Ho provato con : if (Serial2.available() == 0x55) ecc.ecc.

che tradotto vuol dire:

se nel buffer ci sono 85 byte ecc ecc

Consiglio di leggere il reference (in particolare alla voce Returns)

La sincronizzazione per avere il 0x55 sempre al primo posto l'hai già scritta nel post iniziale, però la rilettura/stampa dell'array è errata perché manca la logica a stati per identificare l'avanzamento della sequenza, le sequenze non valide, e il momento di sequenza completamente riconosciuta, logica che è sempre quella del post #2

Il modo più compatto che conosco per esprimerla è questo (anche se non è il più semplice da comprendere):

byte stato = 0;
byte tt[4][4] = { { 1, 0, 0, 0 },
                  { 1, 2, 0, 0 },
                  { 1, 0, 3, 0 },
                  { 1, 0, 0, 0 }  };

void loop()
{
    while(Serial2.available())
    {
        byte rx = Serial2.read();
        if(stato==3 && rx!=0x55) elaboraComando(rx);
        stato = tt[stato][  rx == 0x55 ? 0
                          :(rx == 0x78 ? 1
                          :(rx == 0x00 ? 2 : 3)) ];
    }
}

Ragazzi ma voi dovete capire che io sono un perito meccanico senza basi di informatica che a 50 anni si è messo a giocare con Arduino. Io sto leggendo una marea di guide e forum ma il problema è comprendere. La materia è complessa. Come si dice a Brescia :"Tagliatemela giù fine" altrimenti non capisco.

Claudio, la procedura che hai scritto al post #2 è chiarissima e se mi dici che è più semplice che la strada degli array io proverei a seguire quella. Anche Guglielmo qualche mese fa mi aveva dato lo stesso consiglio. Io poi avevo cercato nei forum qualche informazione ma non avevo compreso bene la differenza tra il codice che ho provato a fare e un codice a stati.

Io in questo momento non so come partire. Provo a cercare nel forum. Se avete qualche indicazione è come sempre ben accetta.

Grazie ancora per il tempo che mi dedicate.

PM68: Io in questo momento non so come partire. Provo a cercare nel forum. Se avete qualche indicazione è come sempre ben accetta.

Questa un'indicazione di massima: http://forum.arduino.cc/index.php?topic=495897.msg3455398#msg3455398

e questa una possibile traduzione:

byte stato = 0;

void loop()
{
    while(Serial2.available())
    {
        byte rx = Serial2.read();
        switch(stato)
        {
            case 0:
                if(rx == 0x55)      stato = 1;
                break;
            case 1:
                if(rx == 0x78)      stato = 2;
                else if(rx != 0x55) stato = 0;
                break;
            case 2:
                if(rx == 0x00)      stato = 3;
                else if(rx == 0x55) stato = 1;
                else                stato = 0;
                break;
            case 3:
                if(rx == 0x55)      stato = 1;
                else { elaboraComando(rx);  stato = 0; }
        }
    }
}

Mon dieu ma è tanto difficile? lo ho scritto mesi fa...... adesso, a casa senza valige, sono profondamente inviperito... ci ho messo 40 minuti, compreso accendere il condizionatore e litigare col gattile per come mi hanno trattato la gatta

// di Nelson "StandardOil"
// Idea da sviluppare: riconoscimento alcuni comandi LINbus
// dichiarazione variabili
byte s[] = {0x78, 0x00};
// adesso, dato che si continua a sbagliare le dimensioni degli array
// la faccio calcolare al compilatore
byte dim = sizeof(s) / sizeof(s[0]);
#define START 0x55 // così facciamo facile a cambiare se serve

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

void loop(void)
{
    byte comando = 0; // variabili locali vanno inizializzate

    if (Serial1.available())
        // serial available restituisce il NUMERO dei byte da leggere, NON I byte letti
    {
        byte comando = tratta((byte)Serial.read());// read restituisce un int, va castato a byte

        // la tratta restituisce il dim+1 byte ricevuto se nella corretta sequenza
        // altrimenti 0
        if (comando)
        {
            // trovato qualcosa
e qui ci metto uno switch o quello che mi serve
        }
        else
        {
            // trovato nulla
        }
    }
}


byte tratta(byte in)
{
    static char indice = -1;
    // indice vale anche come stato
    // -1 fuori sequenza
    // 0 trovato lo start
    // da 1 a N trovato carattere da 1 a N
    // si usa un char perchè vale come intero 8 bit con segno

    // ora si esplicitano i casi
    if (in == START)
    {
        // trovato uno start
        // resetto l'indice
        indice = 0;
        // e mi fermo, senza aver trovato un comando
        return 0;
    }

    // ok, il byte in ingresso non era uno start
    // delle due l'una
    // o abbiamo già trovato uno start, oppure no
    if (indice == -1)
    {
        // non abbiano ancora trovato uno start
        // scarto il byte
        return 0;
    }
    else
    {
        // abbiamo trovato uno start
        // vediamo se siamo arrivati alla fine della sequenza
        if (indice == dim)
        {
            // se indice è arrivato alla dimensione dell'array che descrive la sequenza
            // abbiamo già trovato la sequenza, il byte in trattamento è quello giusto
            // stop al conteggio
            indice=-1;
            return in;
        }

        // NO, non abbiamo ancora finito la sequenza
        // vediamo se almeno l'ingresso corrisponde al byte giusto della sequenza
        if (in == s[indice])
        {
            // corrisponde
            // avanzo di un passo
            indice++;
        }
        else
        {
            // non corrisponde
            // esco dalla sequenza
            indice = -1;
            // scarto il byte
            return 0;
        }
    }
}

eddai, il trucco per programmare è semplice dire in italiano cosa si deve fare e poi tradurlo in C anche in 3 o 4 passate di traduzione qui è semplice: SE abbiamo un byte in ingresso lo mando in trattamento SE il trattamento mi restituisce un numero di comando lo eseguo il lavoro sporco lo fa la tratta SE è uno start comincia a contare SE ha cominciato a contare e c'è corrispondenza byte a byte tra ingresso e array della sequenza da riconoscere avanti un passo ALTRIMENTI esci dal conteggio SE abbiamo trovato tutte le corrispondenze il byte in ingresso è quello che mi serve e fermo il conto dei byte NON E' difficile anche perché è la versione "povera" del primo che avevo scritto, mi sembra che fosse ancora giugno...... Ora è da considerare che esiste il comando 0x00 e che vale "tutto spento" Con il programma appena postato non verrà mai riconosciuto, serve inventare qualcosa, ma non è difficile Esisterebbe anche il caso che sia possibile la presenza di qualche 0x55 anche nei dati, che rovinerebbe la sincronizzazione, speriamo non accada, altrimenti serve per forza rilevare il silenzio nella trasmissione

Grazie ragazzi, siete fantastici!

Claudio, il tuo codice è perfetto! Ho capito tutto, l’ho già testato e funziona. Ho aggiunto la parte di elaborazione del comando e fa perfettamente quello che deve fare. Complimenti!

Nelson, il tuo codice ho solo iniziato a guardarlo. E’ parecchio più complicato.
“tratta” non me lo riconosce? Mi dice “‘tratta’ was not declared in this scope” ma se non erro non è una variabile ma un comando. Giusto?

La maggior complicazione è solo apparente si tratta di una differente implementazione di una macchina a stati io la in-direziono attraverso un array di byte attesi in sequenza, per parametrizzarla Comunque a me compila, se non compila a te avrai commesso l'ennesimo errore, vedi tu dove