[RISOLTO]leggere seriale byte per byte

Salve , un saluto a tutti primo post...
ho la necessita di leggere una sequenza di byte dalla seriale per poi memorizzarle in delle variabili..
questo il procedimento :

arduino deve invia questa sequenza di 6 byte x/x/x/x/x/x -------- ultimo byte =cr
ovvero

int dati_in_uscita [6];
dat_in_uscita = (0x1, 0x2, 0x3, 0x4, 0x5, 0x0D);
-------------------

Serial1.write(dati_in_uscita,sizeof(dati_in_uscita));

attendo la risposta del dispositivo che mi manda indietro 9 byte in sequenza di cui sempre ultimo cr

mi date una mano a leggere sti 9 byte e memorizzarli in una variabile?
Grazie...
joele

Ti invitiamo a presentarti (dicci quali conoscenze hai di elettronica e di programmazione) qui: Presentazioni
e a leggere il regolamento: Regolamento

Puoi usare: reaBytesUntil()

tra le variabili globali dichiari: 
byte bufferIn[10];
...spedizione...
int n=Serial.readBytesUntil('\n',bufferIn, 10);  // legge finchè non arriva CR o \n

Penso che \n sia il cr ma non sono sicuro
Occhio al timeout. se n risulta 0 non ha letto nulla entro il timeout, settabile con Serial.setTimeout()

Ciao ,
grazie della risposta
facendo un compile
mi restituisce

'int n = Serial.readBytesUntil('\n',data, 10);  // legge finchè non arriva CR o \n

invalid conversion from byte* to char*

questo il codice completo:

byte message[] = {0x51, 0x50, 0x49, 0xBE, 0xAC, 0x0D};
byte dataIn[10];
unsigned long prevmillis = 0;
unsigned long currentmillis = 0;
unsigned long intervallo = 5000;
#define DEBUG

void setup() {
Serial.begin(9600);  
Serial3.begin(2400);
Serial3.write(message,sizeof(message));
#ifdef DEBUG
Serial.println("Comando inviato");
#endif
}
void loop() {
currentmillis=millis();
 if(currentmillis - prevmillis > intervallo) {
  prevmillis = currentmillis;

Serial3.write(message,sizeof(message));

#ifdef DEBUG
Serial.println("Comando inviato");
#endif 

 }

  leggi_seriale(); 

 }

void leggi_seriale(){

if (Serial3.available() ) {
 delay(20);
 int n = Serial.readBytesUntil('\n',dataIn, 10);  // legge finchè non arriva CR o \n
 } 
  #ifdef DEBUG
  Serial.println("risposta ====>> ");  
  #endif
delay(1000) ; 
}

Al posto di byte usa char:
char dataIn[10];

Ciao.

Evidentemente il device non risponde con char , vengono visualizzati dei quadratini nel debug..

byte message[] = {0x51, 0x50, 0x49, 0xBE, 0xAC, 0x0D};
char dataIn[10];
unsigned long prevmillis = 0;
unsigned long currentmillis = 0;
unsigned long intervallo = 5000;
#define DEBUG

void setup() {
Serial.begin(9600);  
Serial3.begin(2400);
Serial3.write(message,sizeof(message));
#ifdef DEBUG
Serial.println("Comando inviato");
#endif
}
void loop() {
currentmillis=millis();
 if(currentmillis - prevmillis > intervallo) {
  prevmillis = currentmillis;

Serial3.write(message,sizeof(message));

#ifdef DEBUG
Serial.println("Comando inviato");
#endif 

 }

  leggi_seriale(); 

 }

void leggi_seriale(){

if (Serial3.available() ) {
 delay(20);
 int n = Serial.readBytesUntil('\n',dataIn, 10);  // legge finchè non arriva CR o \n
 } 
  #ifdef DEBUG
  Serial.println("risposta ====>> ");  
  for (int i=0; i < sizeof(dataIn); i++){
  
  Serial.print(dataIn[i]);
    #endif
  }
Serial.println();

delay(1000) ; 
}

Per debug intendi il monitor seriale di arduino?
Penso di si ed è normale. Il codice ascii 0x01 non corrisponde ad un carattere stampabile per cui visualizza il quadratino che indica che qualcosa è arrivato.

Se vuoi leggere i byte grezzi il serial monitor non è adatta.

Ciao.

Allora vediamo un attimo di essere piu' specifici,
si tratta di un regolatore solare , la presa seriale fornisce i valori in realtime .
Ora queste sono le specifiche del protocollo che mi sono state inviate dal produttore:

QPI: Device Protocol ID Inquiry
Computer: QPI
Device: (PI
N is an integer number ranging from 0 to 9, 34 used for MPPT-3K-Standard.
Function: To request the device Protocol ID.

questo serve a richiedere l'id del device , e sniffando la seriale mi viene fuori questo :

Richiesta:14/10/2014 00:46:42.20664

51 50 49 BE AC 0D QPI¾¬.

Risposta:14/10/2014 00:46:42.30864 (+0.1026 seconds)

28 50 49 33 34 DA 8F 0D (PI34ڏ.

con il suo programma che gira sotto win...
Quello che vorrei fare io con arduino ...

Nel for prova a scrivere:

Serial.print(dataIn[i],HEX);
Serial.print(" ");

joele:
...e sniffando la seriale mi viene fuori questo :

a che velocità sniffi la seriale 9600 ? Gli altri parametri ?

Allora , la seriale l'ho sniffata sotto win con un programma free ,che intercetta il flusso della com, mentre arduino lo setto a 2400 perche' nelle specifiche del protocollo e' settata a 2400..
cmq con Serial.print(data[],HEX) viene visualizzato correttamente.. ma non sono quelli che mi aspetto....

Protocollo:
1 Communication format
Baud rate
2400
Start bit
1
Data bit
8
Parity bit
N
Stop bit
1

Cosa ti esce?

Comando inviato
risposta ====>> 6D F5 A5 65 19 E5 0
sono 7 byte!!

Mentre mi aspettavo questo:

28 50 49 33 34 DA 8F 0D
che sono 8.

a parte la non corrispondenza , ma lo start byte se lo magna ardino ??
E poi dovrei trovarmi il cr alla fine (0D) e mi trovo solo lo 0.
Non ci capisco una mazda.... che ci entri in qualche modo il crc??
Notte!

Il 0D (CR) non lo legge, il comando usato è leggi fino a CR, ma cr escluso.

6D->0110 1101       F5->1111 0101
28->0010 1000       50->0101 0000

Non ci vedo nessuna logica. Boh. Non pare si perda solo un bit da qualche parte.

Aggiungo anche che , se dallo stesso programma su windows che uso per sniffare la porta scrivo sul terminale QPI¾¬. il regolatore risponde con la giusta sequenza!

verifica bene il fatto della velocita', controlla su questo sw di sniff se puoi verificare la velocita' da qualche parte, perche' se la velocita' e' diversa ti ritropvi con dati tutti sbagliati (stai usando la seriale asincrona)
Volendo puoi anche provare a caso, non e' che siano migliaia le velocita' da provare.

per start byte mangiato da arduino che intendi ?

che modello e' quest'aggeggio che usi ? la seriale e a 5v o 3,3V ?

Arieccoci ,
l'aggeggino e' un regolatore di carica mppt della mppsolar di taiwan , che gentilissimamente hanno mandato le specifiche del protocollo usato per collegarsi con la seriale ed i relativi comandi.(se vuoi posto il pdf).
Sul documento e' riportato :
velocita 2400 baud ,8 n 1.
Il programma fornito da loro (che gira solo su winzozz) non ha alcun settaggio solo il numero della porta.Per collegare win alla seriale ho adattatore usb-serial.
In ogni caso dal terminale dello sniffer se la porta non e' settata a 2400 non comunica in modalita' normale , in modalita' sniff si setta automaticamente a 2400 , per questo sono sicuro della velocita'.
Un'altra cosa che ho notato , sono in possesso di 2 usb-to-serial con chip CH340, uno dei 2 non funziona bene
e infatti non si collega al regolatore in nessun modo neanche con il suo programma , e sniffando i dati mi sono accorto che escono fuori gli stessi valori che visualizza arduino!Ora non saprei dove sbattere la testa.Ho provato tutte e tre le uart di arduino ma non cambia niente.

Saluti.

Edit:
ho fatto questo tentativo .. arduino mega 2560 ,caricato questo sketch :

void setup() {
Serial2.begin(9600,SERIAL_8N1);
}
void loop() {
  Serial2.write(0x51);
  Serial2.write(0x50);
  Serial2.write(0x49);
  Serial2.write(0xBE);
  Serial2.write(0xAC);
  Serial2.write(0x0D);
   
  delay(1000);
 }

Collegato serial 2 aruino con usb-serial su pc con windows (incrociandi rx/tx) , programma advance serial port monitor che monitorizza la usb-serial , questo e' il risultato quando accendo arduino:

57D50D4ECA00
57D50D4ECA00
57D50D4ECA00
57D50D4ECA00
57D50D4ECA00

??

P.S.
Dimenticavo usb.serial settata a 9600 8n1 chiaramente...

c'e' qualcosa che non va ? :slight_smile:

se provi con la print ?

Serial.print(78, HEX)

che quindi dovrebbe darti 4E

8n1 e' sottointeso, puoi anche non passarlo come argomento

Seconda prova:
se invece dell'adattatore usb seriale usi l'usb della Mega va bene ?

Allora , se uso il monitor di arduino serial.print(78, HEX) mi scrive 4E
con l'adattatore usb-serial mi scrive 5917 :astonished:
Sembrerebbe un errore di comunicazione /protocollo..
boo!