Go Down

Topic: float in eeprom esterna (Read 340 times) previous topic - next topic

mixmax122

salve a tutti,
 ho collegato un rtc ds3231 ad Arduino e tramite 3 tasti e un LCD sono riuscito a settare l'ora da tastiera;
fin qui, a parte qualche capata, tutto bene....

lo step successivo sarebbe quella di utilzzare laeeprom presente sullo shield del 3231 per memorizzare i dati (tuti di tipo float)
dopo qualche giorno di documentazione e 5-6 sketch sbagliati, n arrivato a scrivere
Code: [Select]

#include <Wire.h> 
#define disk 0x57  // indirizzo eprom 24lc32
float a= 6.3;         // dato che vorrei memorizzare
float Value;
int address=0;  // cella da cui prtire
float finale;

union ScompF{    // devo scomporre il float in 4 singoli byte
  float Dato;
  byte bytef[4];
} Diviso;
byte f0 = 0;
byte f1 = 0;
byte f2 = 0;
byte f3 = 0; 

void setup(){

Serial.begin(115200);
Wire.begin();
}
void loop()
{
eepromWriteFloat(address, a);

Value = eepromReadFloat(address);
Serial.println(finale);
delay(1999);
}


void eepromWriteFloat(int address, float Value)    //scrivo
{
   
   Diviso.Dato = Value;
   f0 = Diviso.bytef[0];
    f1 = Diviso.bytef[1];
     f2 = Diviso.bytef[2];
      f3 = Diviso.bytef[3];

         Wire.beginTransmission(disk);
         Wire.write((int)(address >> 8));
         Wire.write((int)(address  & 0xFF));
         Wire.write(f0);
         Wire.write(f1);
         Wire.write(f2);
         Wire.write(f3);
         Wire.endTransmission();
           
       
}


float eepromReadFloat(int address){    // leggo

    Wire.beginTransmission(disk);
      Wire.write((int)(address >> 8));
         Wire.write((int)(address  & 0xFF));
     f0 = Wire.read();  // si leggono i byte
      f1 = Wire.read();
      f2 = Wire.read();
      f3 = Wire.read();
       Wire.endTransmission();
      Diviso.bytef[0] = f0; // si ricompone il float
      Diviso.bytef[1] = f1;
      Diviso.bytef[2] = f2;
      Diviso.bytef[3] = f3;
   
      finale = Diviso.Dato;
      return finale;

}


che, con mio stupore, compila correttamente ma dal seriale esce sempre lo stesso valore e cioe 'nan' (se ho capito bene not a number)
ora posto che ho letto e riletto i molti post sull argomento, nn riesco a capire dove sbaglio
qualcuno mi sa illuminare ?
...quanto più forte è la Luce, più nitide sono le Ombre

SukkoPera

#1
Feb 14, 2018, 02:37 pm Last Edit: Feb 14, 2018, 04:19 pm by SukkoPera
Usa questa libreria: https://github.com/JChristensen/extEEPROM.

Potrai fare semplicemente:

Code: [Select]
float f;
eeprom.write (address, &f, sizeof(float));
eeprom.read (address, &f, sizeof(float));


Make your Sega MegaDrive/Genesis region-free with Arduino! https://goo.gl/X7zBcq

Guida rapida a ESP8266: https://goo.gl/kzh62E

mixmax122

Ciao sukkoPera anzitutto grazie per avermi risposto;

ottima libreria, ma l'intento è quello di capire se sbaglio col protocollo wire o cn union
...quanto più forte è la Luce, più nitide sono le Ombre

SukkoPera

#3
Feb 14, 2018, 04:24 pm Last Edit: Feb 14, 2018, 04:24 pm by SukkoPera
Non noto errori particolarmente evidenti, a parte il fatto che fai un sacco di passaggi inutili. L'unica cosa che mi puzza un po' è quel cast a int dell'indirizzo, io farei un cast a byte, al massimo.
Make your Sega MegaDrive/Genesis region-free with Arduino! https://goo.gl/X7zBcq

Guida rapida a ESP8266: https://goo.gl/kzh62E

Claudio_FF

Se non sbaglio la lettura della EEPROM esterna dovrebbe essere così:
Code: [Select]
Wire.beginTransmission(disk);
Wire.write((int)(address >> 8));
Wire.write((int)(address  & 0xFF));
Wire.endTransmission();
Wire.requestFrom(disk, 4);
f0 = Wire.read();
f1 = Wire.read();
f2 = Wire.read();
f3 = Wire.read();
Formattare sempre il codice (CTRL+T sull'IDE) prima di postarlo sul forum:
l'indentazione errata fa perdere tempo e rende difficile trovare gli errori.

Silente

Salve,
Mi scusi una domanda strana. Potrebbe esserle comodo, per esempio, trattare i nuneri come array composti da cifre? Scrivere tali cifre in eeprom, usando magari un carattere separatore tra i vari numeri, e gestirli usando la libreria bignum (credo si scriva così). Personalmente non la ho mai usata, ma so che il suo scopo é operare su numeri sottoforma di array. Questo metodo richiede molto più spazio in memoria (che ammetto può essere un problema) ma semplifica la lettura, la scrittura, ed elude limiti in cifre

SukkoPera

Io direi che non è proprio il caso... Mentre appoggio il suggerimento di Claudio, mi era effettivamente sfuggito.
Make your Sega MegaDrive/Genesis region-free with Arduino! https://goo.gl/X7zBcq

Guida rapida a ESP8266: https://goo.gl/kzh62E

mixmax122

Io direi che non è proprio il caso... Mentre appoggio il suggerimento di Claudio, mi era effettivamente sfuggito.
condivido, la mem non ci bastera mai XD

per completezza posto il codice aggiornato con i suggerimenti di claudio e SukkoPera(funzionante)
Code: [Select]

#include <Wire.h>
#define disk 0x57     //24xx32 eeprom

float a = 5.8;
float Value;
uint8_t address = 0;  // 256 / 4( ibyte necessari x un float) indirizzi sfruttabili (giusto ?)
float Composto;

union ScompF{        // scompongo float in 4 byte
  float Dato;
  byte bytef[4];
} Diviso;


void setup(){

Serial.begin(115200);
Wire.begin();
}
void loop()
{
eepromWriteFloat(address, a);

Composto = eepromReadFloat(address);
Serial.println(Composto);
delay(1000);
}


void eepromWriteFloat(int address, float Value)
{
   
            Diviso.Dato = Value;
Serial.print(" a è ");                     //debug seriale
Serial.println(Value);


         Wire.beginTransmission(disk);
         Wire.write((byte)(address >> 8));       //indirizzo cella iniziale (cast a byte grazie a sukkopera)
         Wire.write((byte)(address  & 0xFF));
       
         Wire.write(Diviso.bytef[0]);             // salvo i 4 byte   
         Wire.write(Diviso.bytef[1]);
         Wire.write(Diviso.bytef[2]);
         Wire.write(Diviso.bytef[3]);
         Wire.endTransmission();
        delay(200);
}


float eepromReadFloat(int address){
 
    Wire.beginTransmission(disk);               
      Wire.write((byte)(address >> 8));
         Wire.write((byte)(address  & 0xFF));
         Wire.endTransmission();
         Wire.requestFrom(disk, 4);      //grazie Claudio ;)
         Diviso.bytef[0] = Wire.read();
         Diviso.bytef[1] = Wire.read();
         Diviso.bytef[2] = Wire.read();
         Diviso.bytef[3] = Wire.read();
     
    return Diviso.Dato;
}





l'errore era in
 byte f0 = 0;
byte f1 = 0;
byte f2 = 0;
byte f3 = 0;
che forzava i byte della union = 0
...quanto più forte è la Luce, più nitide sono le Ombre

SukkoPera

Non credo che l'errore fosse quello, era piuttosto quello che ha suggerito Claudio!
Make your Sega MegaDrive/Genesis region-free with Arduino! https://goo.gl/X7zBcq

Guida rapida a ESP8266: https://goo.gl/kzh62E

mixmax122

Non credo che l'errore fosse quello, era piuttosto quello che ha suggerito Claudio!
di certo quello era determinante;
ma l'ho provato e ho fatto un passo avati... da NAN a 0.00 il che mi ha fatto intuire che l'errore doveva essere ANCHE nella union e infatti qui qui astrobeed spiega la  sintassi di union;
...quanto più forte è la Luce, più nitide sono le Ombre

SukkoPera

#10
Feb 15, 2018, 10:30 am Last Edit: Feb 15, 2018, 10:32 am by SukkoPera
Credimi, so come funziona una union.
Code: [Select]
byte f0 = 0;
byte f1 = 0;
byte f2 = 0;
byte f3 = 0;


Questo codice inizializza solo il valore iniziale delle variabili, che tra l'altro sono solo di appoggio ed inutili, come hai intuito anche tu. Non lavorano direttamente sulla union, quindi non potevano causare il problema. Piuttosto è plausibile che Wire.read() ritorni 0 se prima non hai fatto Wire.requestFrom().
Make your Sega MegaDrive/Genesis region-free with Arduino! https://goo.gl/X7zBcq

Guida rapida a ESP8266: https://goo.gl/kzh62E

mixmax122

no no ti credo Tantissimo :)  :)  :)  :)  !!!!

riportavo il mero dato "statistico";
 probabilmente è come dici tu.

se posso approfittare....
 al posto di 4 singole chiamate Wire.write scrivere
Code: [Select]

for (int i =0 ; i<4 ; i++){
        Wire.write(Diviso.bytef[i];
}

  sarebbe corretto ??
...quanto più forte è la Luce, più nitide sono le Ombre

SukkoPera

#12
Feb 15, 2018, 10:41 am Last Edit: Feb 15, 2018, 10:42 am by SukkoPera
Certo! Meglio ancora se dichiari i di tipo byte.
Make your Sega MegaDrive/Genesis region-free with Arduino! https://goo.gl/X7zBcq

Guida rapida a ESP8266: https://goo.gl/kzh62E

Go Up