Go Down

Topic: conversione numero decimale in byete mediante la funzione byte() (Read 8235 times) previous topic - next topic

ferdinando

Salve come da titolo, ho problemi a convertire un numero decimale in tipo di dato byte (mi serve perchè ho una funzione che riceve solo byte)

sul reference di arduino c'è la funzione byte()

Description
Converts a value to the byte data type.
Syntax
byte(x)
Parameters
x: a value of any type
Returns
byte

che come dice dal reference riceve qualsiasi tipo di dato.

infatti se faccio:
Code: [Select]


int y=4;
byte b= byte(y);
Serial.println(b,DEC);


ottengo proprio quello che voglio



se faccio:

Salve come da titolo, ho problemi a convertire un numero decimale in tipo di dato byte (mi serve perchè ho una funzione che riceve solo byte)

sul reference di arduino c'è la funzione byte()

Description
Converts a value to the byte data type.
Syntax
byte(x)
Parameters
x: a value of any type
Returns
byte

che come dice dal reference riceve qualsiasi tipo di dato.

infatti se faccio:
Code: [Select]


float y=4.3;
byte b= byte(y);
Serial.println(b,DEC);


ottengo solo 4 e nessun numero decimale.
Così con double.

ho cercato sul forum ma non ho trovato niente
Potete aiutarmi?
grazie

Federico_Vanzati

byte è di tipo intero a 8 bit e senza segno, quindi i valori disponibili vanno da 0 a 255 (a passi interi chiaramente).

se ti serve anche la cifra decimale o usi i float o i double oppure sfrutti uno stratagemma con cui in due variabili byte salverai in una la parte intera ed in una la parte decimale. come ottenere la parte decimale?

con l'operatore % che ti da il resto della divisione, qui un esempio: http://arduino.cc/en/Reference/Modulo
F

leo72

Ma... in buona sostanza... qual è il problema? Il post è un po' ingarbugliato...   :smiley-sweat:

ferdinando

Scusa leo, hai ragione.

In sostanza io ho una funziona di scrittura eeprom che riceve byte come tipo di dato.

Ho dei valori con la virgola da scrivere su eeprom quindi come faccio a convertire float in byte?

quello che dice federico è giusto, infatti ho sbagliato a non pensarci prima, ma perchè sul reference c'è scritto che :

byte(x); 

riceve qualsiasi dato e restituisce byte??

Grazie

leo72

Il reference è corretto: la funzione byte() è una funzione di conversione, serve pertanto per convertire un valore da un sistema di rappresentazione ad un altro. Quindi convertendo un float in byte ottieni un numero che risponde ai requisiti di byte, ossia contiene solo la parte intera di un numero e solo nell'intervallo 0-255.
Un float è un numero in virgola mobile contenuto in 4 byte di memoria.

Ho trovato sul forum internazionale qualcosa che forse potrebbe fare al caso tuo:
http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1234477290/3


ferdinando

Come al solito grazie a tutti.

Ho preso ispirazione.

siccome il float è a 2 cifre decimali, moltiplico per 100

e tolgo le due cifre decimali. poi postdivido

astrobeed

#6
Jun 03, 2011, 03:42 pm Last Edit: Jun 03, 2011, 04:18 pm by astrobeed Reason: 1
Esiste un modo semplicissimo per risolvere questo tipo di problemi, sono le unioni.
Basta creare una unione che contiene un float e una stringa di tipo char da quattro elementi:

Code: [Select]

union SCOMP_FLOAT // union per scomporre un float in byte
{
float MyFloat;
char byte_s[4];
} S_FLOAT;



Dichiarata l'unione in testa al programma, quindi al di fuori di setup() e loop(), basta caricare il valore decimale che vogliamo scomporre in byte dentro S_FLOAT.MyFloat, p.e. "S_FLOAT.MyFloat = 123.123", dopo di che all'interno dei singoli elementi dell'array S_FLOAT.byte_s[n] (n compreso tra 0 e 3) troviamo i quattro byte che compongono il float pronti per essere memorizzati sulla EEPROM o essere inviati tramite un canale di comunicazione.
Per riavere il float partendo dai byte basta fare l'operazione inversa, cioè caricare in S_FLOAT.byte_s[n] i quattro byte nello stesso ordine in cui sono stati estratti e riavremo il nostro decimale all'interno di S_FLOAT.MyFloat.
Scientia potentia est

leo72


astrobeed

Questo è solo un piccolo esempio di quello che permette di fare il C, quello vero, quando lo si conosce  :D
C'è pure un altro metodo per fare la stessa cosa, ma non credo sia utilizzabile direttamente in wiring come le unioni.
Creare una variabile float e un puntatore char, assegnare con l'operatore & al puntatore l'indirizzo di memoria della variabile float, a questo punto utilizzando la matematica dei puntatori è possibile leggere byte a byte la variabile float.

Sintetizzando il tutto:

char byte1,byte2,byte3,byte4;
float myFloat; // ho una var float
char *myBuffer; // ho un puntatore a char

//Float to byte

myBuffer = (char *)(&myFloat); // assegno il puntatore della var float al puntatore a char con cast
                                                   // ora myBuffer punta al primo byte della variabile float
byte1= *myBuffer;
myBuffer++;                               // mi sposto sul byte successivo, cioe' il secondo della variabile float
byte2=*myBuffer;
myBuffer++; 
byte3=*myBuffer;
myBuffer++;
byte4=*myBuffer;

// ora byte1-4 contengono i 4 byte che compongono il float
*-----------------------------*

// byte to float
myBuffer = (char *)(&myFloat);
*myBuffer=byte1;
myBuffer++;
*myBuffer=byte2;
myBuffer++;
*myBuffer=byte3;
myBuffer++;
*myBuffer=byte4;

// ora in myFloat c'è il numero ricomposto
Scientia potentia est

uwefed

#9
Jun 03, 2011, 04:54 pm Last Edit: Jun 03, 2011, 04:56 pm by uwefed Reason: 1

Come al solito grazie a tutti.
Ho preso ispirazione.
siccome il float è a 2 cifre decimali, moltiplico per 100
e tolgo le due cifre decimali. poi postdivido

Quanto grande é la cifra. Moltiplicando il valore con 100, con un byte puoi avere cifre da 0 fino a 2,55.

Teoria dei tipi di variabili:
solo numeri interi senza decimali.
byte: 1 Byte cifra a 8 bit  ( 0 fino a 255)
int: 2 Byte; cifra a 15 bit con segno con il bit piú alto funge da segno (da -32,768 a 32,767)
unsigned int: 2 byte; cifra con 16 bit  (da 0 a 65,535)
long: 4 byte cifra con 31 bit con il bit piú alto funge da segno (-2,147,483,648 a 2,147,483,647)
unsigned long: 4 Byte; cifra con 32 bit (da 0 a 4,294,967,295)

con decimali:
float: 4 Byte cifra con esponente dove 1 bit funge da segno, 23 Bit da mantissa e 8 bit da l'esponente (da  -3.4028235E+38 a 3.4028235E+38) precisione solo da 6 a 7 decimali.  

Con il metodo segnato da astrobeed prendi i 4 Byte della variabile float e li metti in 4 variabili a 1 Byte e li memorizzi.

Se hai un int puoi ricavare il 2 byte anche con lowByte() e highByte() e unirli di nuovo con word();  

altri variabili
Il char e string sono rapresentazioni per memorizzare caratteri o stringhe che comunque sono numeri che rapresentano il codice ashii del carattere.
boolean é una variabile a 1 bit.

@astrobeed: anche a me mi veniva piú intuitivo lavorare con i puntatori. Ma come forse giá detto: I puntatori sono niente di megalattico ma  uno deve averli capito per poterli usare.

Ciao Uwe

Go Up