Ciao a tutti.
Ricevo sulla seriale di Arduino da un microcontrollore collegato tante sequenze di byte formato hex.
Devo inviare una risposta solo quando ricevo la seguente:0x82 0x82 0x01 0x01 0x00 0x00 0x00 0x00 0x00. La risposta sarà: 0xc2 0xc2 0xff 0x00 0x00 0x40 0x40 0x00 0x00 0x00 0x00.
Le sequenze in entrata sono tutte della stessa lunghezza, il baurate è 9600.
Qualcuno mi può aiutare gentilmente.
grazie
Buongiorno,
essendo il tuo primo post, nel rispetto del regolamento della sezione Italiana del forum (… punto 13, primo capoverso), ti chiedo cortesemente di presentarti IN QUESTO THREAD (spiegando bene quali conoscenze hai di elettronica e di programmazione ... possibilmente evitando di scrivere solo una riga di saluto) e di leggere con molta attenzione tutto il succitato REGOLAMENTO ... Grazie.
Guglielmo
P.S.: Ti ricordo che, purtroppo, fino a quando non sarà fatta la presentazione nell’apposito thread, nel rispetto del suddetto regolamento nessuno ti risponderà (eventuali risposte verrebbero temporaneamente nascoste), quindi ti consiglio di farla al più presto.
P.P.S.: Altra cosa in merito alla tua domanda ... mi raccomando, leggi attentamente il REGOLAMENTO al punto 16.1. Grazie.
Che genere di aiuto esattamente? Dove stai trovando difficoltà? Metti il codice che hai scritto sino ad ora e vediamo dove è il problema ...
Guglielmo
I byte non possono essere in formato hex, può invece essere hex la loro rappresentazione a video o su carta. O in alternativa possono essere i codici ASCII di una stringa di caratteri che rappresenta valori hex, ma non mi sembra questo il caso. Da quanto riportato ricevi una sequenza di 9 byte con i valori: 130 130 1 1 0 0 0 0 0
Non abbiamo informazioni su come questa sequenza di byte sia sincronizzata (pause temporali? Preamboli/headers?).
Il problema è quindi immagazzinare e riconoscere questi nove valori? Corretto?
Ciao Guglielmo, grazie intanto di avermi risposto sei gentile. Riesco ad inviare la sequenza hex e a verificarla con un analizzatore logico ma non riesco a rispondere a quel determinato messaggio che mi arriva dal microcontrollore collegato al mio arduino. Arduino in pratica dovrebbe generare una risposta ogni volta che riceve quel determinato messaggio o chiamata. In pratica è un punto di partenza per sviluppare qualcosa di più complesso e se riesco a fare questo il resto vien da se. Non sono a casa quindi al momento non posso inviare il codice con cui stavo lavorando. Pensi le info fornite possono rendere l'idea o c'è bisogno di ulteriori dettagli?
Bah ... usi semplicemente la classe Serial per la gestione della seriale, usi i metodi read() e write() per legge e trasmettere bytes, accumuli i bytes ricevuti in un array di byte e poi fai la comparazione per riconoscere la sequenza ... una volta che l'hai riconosciuta ... trasmetti i bytes che devi trasmettere ...
Guglielmo
io direi che i dettagli che hai dato sono sufficienti per cominciare
si tratta fondamentalmente di una macchina a stati, nella quale gli stati sono definiti da un'array di caratteri
e che risponde con un altro array di caratteri
purtroppo non puoi usare funzioni stringa, ne oggetti stringa ne stringhe di C, dato che i caratteri descrittivi la richiesta e la risposta contengono zeri binari nel loro mezzo
per @gpb01
dato che non può usare la strcmp() e comunque non ha certezza di leggere dal primo byte trasmesso gli conviene trattare byte a byte in una macchina a stati piuttosto che confrontare stringhe
conviene che faccia un giro su "grep non vuol dire greppia"
che fa esattamente questo, anche se usa stringhe convenzionali e può riconoscere più sequenze, ma come ispirazione....
Ecco, casomai, come giustamente dice Claudio_FF, al limite il problema sarà ... come riconosci quando inizia la sequenza e quando finisce? Hai dei tempi ben determinati? Hai un carattere di inizio sequenza ed uno di fine?
Insomma ... come identifichi quando inizia la sequenza ?
Guglielmo
io direi che due 0x82 consecutivi siano un buon indice
Dove hai letto che io abbia parlato di stringhe e di confrontare stringhe ? ? ?
Ho parlato di leggere byte (e NON char) e di confontare byte a byte ... e NON serve complicarsi la vita con "macchine a stati" (mi sembra che siete un po' tutti fissati co' sta' cosa) ... basta capire quando inizia (c'è un tempo? un periodo di silenzio? un identificatore?) e leggere la sequenza o per N bytes o per timeout e poi confrontare.
Guglielmo
Potrebbe essere, ma magari c'è un qualche altra cosa ... magari ci sono altre sequenze a cui NON deve rispondere e che contengono anche loro 0x82 0x82, chi lo sa ...vediamo se ci da più indicazioni.
Guglielmo
Potrebbe non essere necessario un marker di inizio o fine
se vuoi reagire alla ricezione
0x82, 0x82, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00
quindi accumuli semplicemente ogni byte che arriva, ad esempio in un buffer circolare, e confronti l'array con l'array noto. Quando ottieni un successo, bingo, spari la risposta.
const byte expected[] = {0x82, 0x82, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00};
const byte answer[] = {0xc2, 0xc2, 0xff, 0x00, 0x00, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00};
const byte bufferSize = sizeof expected;
byte buffer[bufferSize];
byte nextSlot = 0;
bool bingo() {
bool correct = true;
// ... da fare
return correct;
}
void listen() {
int r = Serial.read();
if (r != -1) {
buffer[nextSlot++] = r;
if (nextSlot >= bufferSize) nextSlot = 0;
if (bingo()) Serial.write( /* ...da fare ...*/ );
}
}
void setup() {
Serial.begin(9600);
}
void loop() {
listen();
}
(completamente non testato)
@J-M-L: Debbo sempre ricordarti il ns. REGOLAMENTO ... specie il punto 16.13 ?
dimenticavo (di nuovo!)
Ho rimosso parte del codice
PS= dura lex sed lex
Invece di "scrivere codice" è molto più utile spiegare i passi da fare ... certo, è più impegnativo
Solo come esempio, guarda QUESTO post di Claudio_FF (... e molti altri dei suoi)
Guglielmo
Grazie dei consigli, lunedì faccio provo e vi tengo aggiornati. Rispondo a Guglielmo che chiedeva ulteriori dettagli sulla sequenza che segue quella in questione. Ebbene si segue un'altra sequenza di byte della stessa lunghezza che inizia sempre con 0x82 0x82 ma invece di 0x01 0x01 è 0x06 0x06. Questo perché ad essa vengono collegate più periferiche e ogni periferica deve rispondere al messaggio di chiamata al momento giusto.
Stamattina ho fatto un po di prove solo che non sono riuscito a confront
Dicevo non sono riuscito a confrontare i byte che passano per l'array con la mia sequenza nota. Posso postare il codice per condividerlo con voi?
CVD significa Come Volevasi Dimostrare...
Quindi una macchina a stati innescata da due 0x82...
È più semplice così che ogni altra soluzione, anche hard coded
Come ho detto "grep non vuol dire greppia"
sì, il mio C++ è migliore del mio italiano
Direi che è l'unico modo per capire di cosa si parla.
Ma se ogni byte che arriva viene inserito in fondo all'array di 9 facendo scorrere gli altri elementi verso l'inizio (ovviamente perdendo il primo), a un certo punto deve per forza esserci il match.