lettura di 26 bytes consecutivi

ciao a tutti, ho fatto questa funzione per leggere circa 26 bytes (alcune volte 1 in più) inviati consecutivamente al pin 7 aggiunto come seriale grazie alla libreria SoftwareSerial.

#include <SoftwareSerial.h>
SoftwareSerial programmer (7, 8);
#define trigger 2


void setup() {

  Serial.begin(19200);
  programmer.begin(4800);

  pinMode(trigger, OUTPUT);
  digitalWrite(trigger, LOW);

}

void loop() {

  digitalWrite(trigger, HIGH);   // trigger per l invio dei bytes

  while (programmer.available() == 0) {  // aspetto che li manda
    ;
  }

  while (programmer.available() > 0) {
    byte b = programmer.read();
    Serial.println(b);
  }

  delay(5000);
  digitalWrite(trigger, LOW);
  Serial.println("");
  Serial.println("New Reading:");
  Serial.println("");
  delay(5000);

}

funziona tutto perfettamente ma mi domandavo se c era un altro metodo migliore per farlo, voi che ne pensate?

Dipende da cosa devi fare con quei 26/27 byte.

Personalmente, li avrei raggruppati in un array per gestirli successivamente.

Non mi serve salvarli mi basta “vederli” una volta. volevo solo essere sicuro di stare usando un metodo valido, se sto sbagliando qualcosa rischio di rompere una o piú esc da 7€

Vi spiego a cosa servono, rispondere a scatola chiusa immagino non sia facile. Praticamente ho una programming card per esc che funziona collegandola ai regolatori e lei in automatico li setta sulla base di alcuni jumper presenti sulla stessa

Adesso quello che io vorrei fare, o in veritá ho giá fatto é un pó di reverse engineering:

questo

Se servono 26, si mette un contatore che li conta. Poi potrebbe anche stare a vedere che arrivano in un certo lasso di tempo. Forse si potrebbe usare Serial.readBytesUntil("",buffer,26). Ma non ho provato. Vedi nel Reference.

Il numero di byte é irrilevanta, a prescindere che siano 2 o 30 a me interessa leggerli tutti.

La mia domanda verte di piú sulla logica, io ricevo una lunga sequenza di 0 e 1 e decido di vederli come se fossero una comunicazione seriale, é corretto come approccio? O avrei dovuto fare qualcosa del tipo digitalRead e poi ogni 8 bit creare un byte?

Che ci sia un treno di alti e bassi, per decodificarli ci sono diversi protocolli. Salvo ne vuoi provare uno diverso. Ma come pare il protocollo seriale funziona e riesci ad estrapolare i bytes che intendi usare.

Si mi sa che hai ragione, cioé é la prima volta che provo a fare una cosa del genere quindi volevo essere sicuro di non aver preso un granchio e stare leggendo i byte sbagliati. ma ho fatto decine di prove e ho anche creato la tabella che c é nel link, non credo che se leggevo cose a caso avrei potuto fare una decodifica come quella

Edit: un grosso dubbio, ok ho capito quali sono i byte che mi interessa modificare e adesso per inviarli cosa consigliate? Sempre l uso della seriale giusto? Se si, é sbagliato usare un Serial.println(byte) dovrei farlo senza il capo automatico o va bene anche cosí?

aster94:
ciao a tutti, ho fatto questa funzione per leggere circa 26 bytes (alcune volte 1 in più) inviati consecutivamente al pin 7 aggiunto come seriale grazie alla libreria SoftwareSerial.

#include <SoftwareSerial.h>

SoftwareSerial programmer (7, 8);
#define trigger 2

void setup() {

Serial.begin(19200);
  programmer.begin(4800);

pinMode(trigger, OUTPUT);
  digitalWrite(trigger, LOW);

}

void loop() {

digitalWrite(trigger, HIGH);  // trigger per l invio dei bytes

while (programmer.available() == 0) {  // aspetto che li manda
    ;
  }

while (programmer.available() > 0) {
    byte b = programmer.read();
    Serial.println(b);
  }

delay(5000);
  digitalWrite(trigger, LOW);
  Serial.println("");
  Serial.println(“New Reading:”);
  Serial.println("");
  delay(5000);

}




funziona tutto perfettamente ma mi domandavo se c era un altro metodo migliore per farlo, voi che ne pensate?

mah io lo “complicherei” un po di più almeno un qualche specie di controllo (bit di parità) se uno “SALTA”

Rospo non posso! La cosa da cui sto prendendo i dati é un prodotto già configurato e pronto non lo posso programmare

Scusatemi se ripropongo questa domanda:

Edit: un grosso dubbio, ok ho capito quali sono i byte che mi interessa modificare e adesso per inviarli cosa consigliate? Sempre l uso della seriale giusto? Se si, é sbagliato usare un Serial.println(byte) dovrei farlo senza il capo automatico o va bene anche cosí?

E aggiungo, la scelta migliore nel mio caso forse é la Serial.write o sbaglio?

print invia un testo e non un byte, ovvero print(65) invia il char '6' e poi '5' println invia anche 2 byte (andata a capo e ritorno carrello ovvero i valori 13 e poi 10, non visibili come ascii) write invia dati in byte quindi write(65) invia il byte 65 (che letto come ascii= lettera 'A')

ok codice modificato con il write

Solo a scopo didattico visto che mi interessa capirlo bene e sono un pò confuso: la seriale di arduino o qualsiasi altra come putty, riceve 0 e 1 e poi visualizza ogni 8 bit un carattere ASCII in base alla sequenza ricevuta? giusto?

avrei ottenuto lo stesso risultato con il Serial.print(3,BIN) ? credo di no giusto? il BIN è una sorta di presa in giro che io faccio, perchè veramente non mando il 3 come binario, cioè non invio 0x11, ma invio il carattere in ASCII per visualizzare l 1 sulla seriale.

mi potete confermare questi due dubbi?

Serial.print(3,BIN) è composto da 2 bytes di valore 49 decimale. Che in ascii corrisponde a 11.

Esattamente ciò che pensavo grazie Experiment :D

Ma esiste un modo per far combaciare perfettamente seriale sul computer e output di un qualsiasi MCU? Cioè c è un modo per inviare B101 e ricevere B101 senza conversioni in ascii o altri rimaneggiamneti di dati

Nessun "magheggiamento" sono solo modi diversi di visualizzare la STESSA cifra.

non sono d accordo, anche se dipende che accezione si da alla parola "stessa", perchè a te ti sembra che è la stessa cifra ma così non è.

Se spedisci con print(3) invii il carattere con valore 3 (non visibile a video)

no, invece si vede, proprio perchè sicuramente nella funzione .print() o dal lato della seriale del computer ci sarà un +48 quindi a riprova del fatto che non è la stessa cifra, però alla persona sembra la "stessa" cifra ma non è esattamente così se si vuole essere precisi

comunque è tutto chiaro grazie lo stesso!

Si, su print(3) ho scritto di fretta una cavolata, sorry.

Di base - la write fa trasmissione seriale a byte. - la print/println fa sempre una trasmissione a caratteri Quindi la write e la print fanno la stessa cosa se spedisci delle frasi ma cambia totalmente se spedisci numeri; per i numeri la write spedisce solo un byte alla volta mentre la print spedisce il numero come testo ovvero spedisce ogni singola cifra come letterale ascii corrispondente (se vogliamo potremmo dire che fa una "trasformazione").

quindi val=65 write(val) spedisce il byte 65 print(val) spedisce la cifra '6' e poi '5' print(val,BIN) spedisce la cifra '1' '0' '0' '0' '0' '0' '1' (non so se aggiunge la lettera B)

Se vuoi spedire i bit del byte DEVI usare la write perchè la write(val) spedisce il valore 65 (che poi dentro è 1000001)

Inoltre OCCHIO alla write, perchè se guardi dentro al core il file HardwareSerial.h vedrai le varie versioni di write() e noterai che spedisce sempre solo un byte anche se gli passi numeri più grandi. Se per esempio hai un int, prima viene fatto una conversione da int a byte (e quindi lo castra) e poi spedisce.

P.S. La write però può anche spedire un vettore/array di byte

“print spedisce il numero come testo ovvero spedisce ogni singola cifra come letterale ascii corrispondente (se vogliamo potremmo dire che fa una “trasformazione””

Esatto adesso siamo d accordo, come ti dicevo non sono la “stessa” cifra, penso che ció che hai scritto verrà utile per chi nel futuro avrà dubbi simili
Aggiungo per chi avesse necessità di inviare due byte con write: https://www.arduino.cc/en/Reference/LowByte e la relativa highByte