- Labornetzteil AliExpress         
Ergebnis 1 bis 3 von 3

Thema: uint8_t[4] -> float ergibt komische Rundungen

  1. #1
    Erfahrener Benutzer Begeisterter Techniker Avatar von PCMan
    Registriert seit
    05.08.2006
    Ort
    Munich
    Beiträge
    311

    uint8_t[4] -> float ergibt komische Rundungen

    Anzeige

    LiFePo4 Akku selber bauen - Video
    Hallo Leute,
    also im Moment funktioniert bei mir irgendwie garnix gescheit, ist mal ein Problem gelöst kommt gleich das nächste sinnlose Problem daher.


    Okay zum Problem: ich habe Messwerte, die typischerweise als floats vorliegen. Diese Floats sollen in ein seperates EEPROM. Die schnittstelle ist per IIC realisiert (mit p. fleuries library).

    Wenn ich einen float Wert auf einen Chip speichern möchte habe ich folgende Funktion geschrieben:
    Code:
    void write_f(uint16_t adress, float f32)
    {
    	union {
         	float r;
          	uint8_t i[sizeof(float)];
       	} u;
       	u.r = f32;
    
    	adress*=4; //in welche 4 zellen die einzelnen bytes kommen...
    	i2c_start_wait(EEPROM_CHIP_V+I2C_WRITE);
    	i2c_write(HIGHBYTE(adress));	//übertrage speicheradresse
        	i2c_write(LOWBYTE(adress));
        	i2c_write(u.i[3]); //schreibe 4 bytes
    	i2c_write(u.i[2]);
        	i2c_write(u.i[1]); 
    	i2c_write(u.i[0]);
    	
    	i2c_stop();
    	return;
    }
    Zum abrufen der Bytes auf dem Chip und für die Konversion zurück zu float habe ich folgende Funktion:

    Code:
    float read_f(uint16_t adress)
    {
    	union
    	{
    		float f;
    		uint8_t i[sizeof(float)];	
    	} u;
    
    	adress*=4;
    	i2c_start_wait(EEPROM_CHIP_V+I2C_WRITE);
    	i2c_write(HIGHBYTE(adress));	//übertrage speicheradresse
        	i2c_write(LOWBYTE(adress));
    	i2c_rep_start(EEPROM_CHIP_V+I2C_READ);
    	
    	u.i[3] = i2c_readAck(); //schreibe die 4 bytes
    	u.i[2] = i2c_readNak();
    	u.i[1] = i2c_readNak();
    	u.i[0] = i2c_readNak();
    	
    	i2c_stop();
    	return u.f;
    
    }
    Gut, wenn ich nun folgenden Aufruf tätige:

    Code:
    	char str[16];
    	union
    	{
    		float f;
    		uint8_t i[sizeof(float)];
    	} u1;
    
    	union
    	{
    		float f;
    		uint8_t i[sizeof(float)];
    	} u2;
    
    	u1.f = 2.22;
    
    	u2.i[3] = u1.i[3];
    	u2.i[2] = u1.i[2];
    	u2.i[1] = u1.i[1];
    	u2.i[0] = u1.i[0];
    
    	dtostrf(u2.f,4,2,(char*)str);
    	lcd_puts(str);
    ... erhalte ich wie gewünscht 2.22 auf dem Display. Soll ja auch so sein.

    Wenn ich aber die Bytes über das EEPROM abhole:

    Code:
    	char str[16];
    	write_f(0, 2.22);
    	dtostrf(read_f(0),4,2,(char*)str);
    	lcd_puts(str);
    Dann erhalte ich 2.23 auf's Display.
    Kann mir bitte jemand erklären, wie es zu dieser Rundung kommt? Ich habe schon allesmögliche probiert, finde aber den Fehler nicht raus...
    Ich meine, der einzige Unterschied ist doch nur, dass einmal die Daten per IIC auf nen externen Speicher übertragen werden, beim anderen Fall bleibt halt alles im RAM. Das Phänomen ist übrigens Speicherzellenunabhängig.

    Viele Grüße und danke schön mal wieder,
    Simon

  2. #2
    Erfahrener Benutzer Robotik Visionär
    Registriert seit
    26.11.2005
    Ort
    bei Uelzen (Niedersachsen)
    Beiträge
    7.942
    Sieht nach einem sehr komischen Fehler aus. Ich würde mal vermuten, das die daten nicht ganz richtig ins EEPROM geschreibenw erden oder gelesen werden. Ein Test wo die 4 Bytes einzeln statt einer float ausgegeben werden sollte da helfen.

  3. #3
    Erfahrener Benutzer Begeisterter Techniker Avatar von PCMan
    Registriert seit
    05.08.2006
    Ort
    Munich
    Beiträge
    311
    Hi.
    Ja das habe ich auch schon getestet, aber da kam mir die Unterbringung der Bytes wie erwünscht vor. Ich habe mal versucht nich 4 Bytes auf einmal zu "Pagen" sondern 2*2 Bytes zu schicken mit einer StopBedingung dazwischen. Das funktioniert dann komischerweise so wie gewünscht. Der EEPROM Baustein 32LC24 unterstützt laut Datenblatt aber ein Pagen von 8 Bytes * 8 Pages sogar. Kann mir das nich erklären.
    Grüße Simon

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •  

Labornetzteil AliExpress