ciao a tutti,
ho già scritto nel forum riguardo il mio progetto per la tesi di usare arduino come ponte di comunicazione fra un TDR e un altro terminale di comunicazione.
cmq sono riuscito ad attivare la comunicazione fra il monitor seriale e lo strumento, ora però mi sono bloccato perchè non riesco a far interpretare i dati da arduino:
se allo strumento invio un comando che mi permette di acquisire una waveform esso mi restituisce questo tipo di stringa:
ora dovrei leggere 4 byte alla volta e accorparli per avere un float in formato standard ieee754(così me li trasmette lo strumento).
come faccio a fare un'operazione del genere?
che tipo di codifica usa arduino per i float?
ho tentato con un programma di test se potessi riuscire ad accorpare 4 byte in un'unica informazione di tipo float ma non ci sono riuscito:
questo il codice di prova che ho usato:
void setup(){
Serial.begin(9600);
float a = '?'; // bin = 00111111
float b = 0x00;// bin = 00000000
float c = 0x00;// bin = 00000000
float d = 0x00;// bin = 00000000
// accorpando in 4 bytes in formato ieee754 risulta:
// bin(00111111|00000000|00000000|00000000) = float(0.5)
float a1 = a<<24; //in teoria (00111111) 00000000 00000000 00000000
float b1 = b<<16; //in teoria 00000000 (00000000) 00000000 00000000
float c1 = c<<8; //in teoria 00000000 00000000 (00000000) 00000000
float d1 = d; //in teoria 00000000 00000000 00000000 (00000000)
float risultato = a1 | b1 | c1 | d1
//bitwise or fra i 4 float per ottenere il float "finale"
Serial.println(risultato);
}
void loop(){
}
ma il l'operazione di bitwise mi da errore di compilazione.
mi potete aiutare?
aureliusss:
ma il l'operazione di bitwise mi da errore di compilazione.
mi potete aiutare?
Il problema non è l'errore di compilazione, è la logica che usi ad assere totalmente sbagliata, per via della natura esponenziale dei float non puoi ricostruirli shiftando i singoli byte, questo è applicabile solo per gli interi.
Puoi ricostruirlo con solo due modi, tramite puntatori o tramite una union, argomento che abbiamo trattato molte volte nel forum.
scusa astro ma se i dati in arrivo sono un float "smontato" in byte tramite bitshift (come nel suo caso) dovrebbe essere possibile riscotsruirlo.. magri un pò di magia tipo
ahhhh ora ho capito il suo errore, "a, b, c, d" li ha dichiarati come float e non come byte... quindi quel 0x3F era convertito nella sua rappresentazione float che non è quella che ci aspettiamo.
lesto:
scusa astro ma se i dati in arrivo sono un float "smontato" in byte tramite bitshift (come nel suo caso) dovrebbe essere possibile riscotsruirlo.. magri un pò di magia tipo
E io che ho detto ? Devi usare i puntatori o una union.
long a = 0x3f<<24; // bin = 00111111
long b = 0x00<<16;// bin = 00000000
long c = 0x00<<8;// bin = 00000000
long d = 0x00;// bin = 00000000
float ris = a|b|c|d;
ù
come al solito sono al lavoro, quindi codice non testato
edit: ah ok, forse non funziona propio perchè questo valore viene tentato di essere convertito in notazione ieee754
ragazzi dato che vi vedo appassionati vi chiedo un'altra cosa.
ho uno strano comportamento con il concatenamento dei caratteri in una stringa:
while(tdr.available()){ //il write su Serial è di debug
Serial.write(tdr.peek()); // per debug
char inChar = tdr.read()
response.concat(inChar);
}
confrontando la stringa response con ciò che mi viene che viene scritto sul monitor seriale(so per certo che ciò che sta scritto sul monitor è giusto), allora, sulla stringa mi escono caratteri in più del tipo:
monitor seriale -> :DUMP?000[...]
response -> :DUMP?0P?000[...]
facendo anche altre prove sembra che nella stringa response, ad un certo punto vengano inseriti dei char già letti.
avete idee a riguardo?
P.S. response è un oggetto String
ho dei problemi perchè inByte = Serial.read() mirestituisce il valore decimale del carattere letto giusto? come faccio a trasformarlo in caratteri in maniera tale da far funzionare il for successivo per ottenere i float?
Serial.read restituisce il byte letto dal buffer seriale.
Tale byte va in valore da 0 a 255. Se lo devi convertire in stringa, potresti usare itoa: http://www.cplusplus.com/reference/cstdlib/itoa/
ciò che non mi sembra chiaro è che cmq il valore binario del byte o carattere che sia dovrebbe essere lo stesso, giusto? ma allora perchè quando uso la union per i float mi escono numeri sbagliati?
NOn credo che con la Union ti possa aiutare. Un float occupa 4 byte ed è salvata in notazione mantissa+esponente. Un byte è un unsigned char. Ma recuperando 1 byte, non peschi tutto il valore del float.
leo72:
NOn credo che con la Union ti possa aiutare. Un float occupa 4 byte ed è salvata in notazione mantissa+esponente. Un byte è un unsigned char
La union ti permette di ricostruire un qualunque tipo dato partendo da altri tipi dati, ovviamente devono essere compatibili, è perfetta, oltre che semplice ed elegante, per questo utilizzo.
Se hai i quattro byte che compongono il float tramite la union ottieni nuovamente il valore iniziale, però è indispensabile che l'ordine di caricamento dei singoli byte sull'array della union rispecchi l'ordine con cui è stato scomposta il float, ovvero può arrivarmi come primo valore sia il primo byte del float che l'ultimo, a seguire i restanti tre, se non li ricompongo nello stesso ordine ovviamente il valore della float non può essere corretto.
Altro requisito indispensabile è che lo standard di rappresentazione del float sia indentico tra l'apparato che lo trasmette e quello che lo riceve, in caso contrario si ottengono valori errati dopo la ricostruzione.
e la union funziona alla perfezione, se non fosse che, dovendo ricevere una stringa di 8/9000 caratteri, ricevevo risultati sbagliati, secondo me a causa del fatto che la concatenazione si imputtanasse con la conversione a char.
dunque ho riscritto l'acquisizione per renderla più semplice senza 'castare' la varibile già in lettura, con il codice che ho messo nel post precedente.
ora però la conversione da 4byte a float non funziona più