Pages: [1]   Go Down
Author Topic: 4 char to 1 float---- problema concat char in stringa  (Read 1191 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Full Member
***
Karma: 1
Posts: 160
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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:
Code:
comando inviato -> :GWAV35
risposta ricevuta -> :#GWAV [byte1][byte2][byte3][byte4]...[byte n-esimo]

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:
Code:
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?
« Last Edit: January 30, 2013, 09:45:30 am by aureliusss » Logged

Rome (Italy)
Offline Offline
Tesla Member
***
Karma: 129
Posts: 9493
"Il Vero Programmatore ha imparato il C sul K&R, qualunque altro testo è inutile e deviante."
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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.
Logged

0
Online Online
Shannon Member
****
Karma: 131
Posts: 10473
:(){:|:&};:
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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
Code:
byte numero[4]={0x3f, 0x00, 0x00, 0x00}; //0x3f = B00111111
float *num;
num=numero;
float val = *nun;

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.
Logged

sei nuovo? non sai da dove partire? leggi qui: http://playground.arduino.cc/Italiano/Newbie

Rome (Italy)
Offline Offline
Tesla Member
***
Karma: 129
Posts: 9493
"Il Vero Programmatore ha imparato il C sul K&R, qualunque altro testo è inutile e deviante."
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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.
Logged

0
Online Online
Shannon Member
****
Karma: 131
Posts: 10473
:(){:|:&};:
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

sisi, è che mi aspetto che funzioni questo:

Code:
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
Logged

sei nuovo? non sai da dove partire? leggi qui: http://playground.arduino.cc/Italiano/Newbie

Rome (Italy)
Offline Offline
Tesla Member
***
Karma: 129
Posts: 9493
"Il Vero Programmatore ha imparato il C sul K&R, qualunque altro testo è inutile e deviante."
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

sisi, è che mi aspetto che funzioni questo:

Non funziona, o meglio ti ritrovi nel float l'equivalente del valore 0x3F000000, cioè 1056964608.00, e non 0.5 come atteso.

Logged

0
Online Online
Shannon Member
****
Karma: 131
Posts: 10473
:(){:|:&};:
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

ok, quindi entra in gioco un autoconversione nascosta.ora mi torna tutto
Logged

sei nuovo? non sai da dove partire? leggi qui: http://playground.arduino.cc/Italiano/Newbie

Offline Offline
Full Member
***
Karma: 1
Posts: 160
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

ragazzi dato che vi vedo appassionati  smiley-razz vi chiedo un'altra cosa.
ho uno strano comportamento con il concatenamento dei caratteri in una stringa:

Code:
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
Logged

Offline Offline
Full Member
***
Karma: 1
Posts: 160
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

sono passato ad arduino due per non avere problemi di memoria e baudrate però ho cambiato il codice in questo:
Code:
while(Serial1.available()){
    inByte = Serial1.read();
    Serial.write(inByte);
    response+=inByte;
  }

  if(inByte == 13){
    char auxiliary[response.length()];
    response.toCharArray(auxiliary,response.length());
    for(int i=0;i<response.length();i++){
      Serial.print(auxiliary[i],HEX);
    }
    for(int i=6;i<response.length();i+=4){
      datum.byteData[3] = char(auxiliary[i]);
      delay(10);
      datum.byteData[2] = char(auxiliary[i+1]);
      delay(10);
      datum.byteData[1] = char(auxiliary[i+2]);
      delay(10);
      datum.byteData[0] = char(auxiliary[i+3]);
      delay(10);
      Serial.println(datum.floatDatum,5);
    }
  }
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?
Logged

Global Moderator
Italy
Offline Offline
Brattain Member
*****
Karma: 332
Posts: 22804
Logic is my way
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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/
Logged


Offline Offline
Full Member
***
Karma: 1
Posts: 160
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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?
Logged

Global Moderator
Italy
Offline Offline
Brattain Member
*****
Karma: 332
Posts: 22804
Logic is my way
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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.
Logged


Rome (Italy)
Offline Offline
Tesla Member
***
Karma: 129
Posts: 9493
"Il Vero Programmatore ha imparato il C sul K&R, qualunque altro testo è inutile e deviante."
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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.
Logged

Offline Offline
Full Member
***
Karma: 1
Posts: 160
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

il discorso è questo:
prima eseguivo la lettura dei caratteri in questa maniera:
Code:
while(Serial.available()){
inByte = Serial.read();
response.concat(char(inByte));
}

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ù
Logged

Pages: [1]   Go Up
Jump to: