Float über i²C zwischen zwei Arduinos austauschen

Hallo zusammen,

ich möchte einen float Wert von einem Arduino zu einem anderen über i²c schicken. Sinn des ganzen ist im Endergebnis ein sog. DRO (neu Deutsch "Digital Read Out"). Dieses zeigt im Normalfall ein paar Verfahrwege einer Werkzeugmaschine (z. B. Drehbank oder Fräsmaschine an). In meinem Fall basiert das ganze auf einem Polymerband und einem Chip von Austria Microsystems. Dazu habe ich bereits vor ein paar Jahren ein Anzeigemodul im folgenden (Arduino) Empfänger genannt gebaut das in der Vergangenheit alles gemacht hat was ich wollte. Der jetzt neu hinzugekommene, im folgenden (Arduino) Sender genannte Aufbau soll per Tastenfeld Vorgabewerte an den Empfänger per i²C schicken. Langer Rede, kurzer Sinn: Ich möchte einen float Wert (drei Vorkomma Stellen, drei Nachkomma Stellen) vom Sender zum Empfänger schicken.

Das ganze funktioniert im Prinzip auch. Ich lasse mal Kot folgen. Zuerst der Sender der die negative float Zahl "-123.123" an den Empfänger schickt:

#include <Wire.h>

union Converter {
  float floatValue;
  byte byteValue[sizeof(floatValue)];
};


Converter x;

void setup() {
  // Start the I2C Bus as Master
  Wire.begin();
  Serial.begin(9600);
}

void loop() {
  Wire.beginTransmission(9);
  x.floatValue = -123.123;
  Serial.println("----------------------------");
  for (int i = 0; i < sizeof(x.byteValue); i++) {
    Serial.print("Gesendeter Wert Nr. ");
    Serial.print(i);
    Serial.print(" :");
    Serial.println(x.byteValue[i]);
    Wire.write(x.byteValue[i]);
  }
  Wire.endTransmission();
  Serial.println("----------------------------");
  Serial.print("Wert als float: ");
  Serial.println(x.floatValue);
  Serial.println("----------------------------");
}

Das gleiche für den Empfänger:

#include <Wire.h>

union Converter {
  float floatValue;
  byte byteValue[sizeof(floatValue)];
};

Converter x;

Converter test;

void setup() {
  // i²C Adresse des Sklaven 9
  Wire.begin(9);
  Wire.onReceive(receiveEvent);
  Serial.begin(9600);
}

void receiveEvent(int bytes) {
  for (int i = 0; i < sizeof(x.byteValue); i++) {
    x.byteValue[i] = Wire.read();
  }
}

void loop() {

  for (int i = 0; i < sizeof(x.byteValue); i++) {
    Serial.print("Empfangener Wert Nr. ");
    Serial.print(i);
    Serial.print(" :");
    Serial.println(x.byteValue[i]);
  }
  Serial.println("---------------------");
  Serial.print("Double Wert: ");
  Serial.println(x.floatValue);
  Serial.println("---------------------");
  delay(500);
}


Blöd ist jetzt nur, das die letzte Nachkommastelle also eine "3" fehlt. Ich erhalte statt "-123.123" nur "-123.12"! Was mache ich falsch? Kann mir jemand weiter helfen?

Vielen lieben Dank für eure Hilfe

Warum benutzt Du nicht die Variante von write mit der Längenangabe und sendest den Float am Stück?

Wire.write(data, length)

Gruß Tommy

Das kann an der Umwandlung von binär nach Text liegen. Dabei gibt es keine Zuordnung von irgendwelchen Stellen.

Ich glaube dir nicht!
Nirgendwo bekommst du: -123.123
Auch nicht beim Sender.
Es sei denn, du sorgst dafür.

Vielleicht hast du auch nur nicht die Doku gelesen.
Warum nicht?

Die Standardeinstellung ist zwei Dezimalstellen.

Aus: https://docs.arduino.cc/language-reference/de/funktionen/communication/serial/print/

Serial.println(x.floatValue, 3);

und lies dir das durch zum Thema Type punning:

@combie: Mir egal, ob du das glaubst. Sorry auf so eine Antwort verzichte ich gerne.
@noiasca: Danke für den Link, ich schaue mir das an.
@Tommy56: Ich wußte nicht das das möglich ist. Ich schaue mir das an, danke

@Tommy56, noiasca, DrDiettrich: Danke für eure Hilfe.

Das liegt an deiner evtl. chronischen DokuLeseVerweigerung.

Tipp:
Ewas weniger jammern, dafür mehr lesen.
Dann wirds für uns alle leichter/schöner.

Du strotzt vor Arroganz! Ein Forum ist da um Fragen zu stellen. Ich glaube du weist gar nicht was du für einen Mist du schreibst. Chronisch bedeutet: "dauernd, ständig". Schau mal in den Duden da kannst du deinen Bildungshorizont erweitern. Woher willst du denn wissen das ich ständig "DokuLeseVerweigerung" betreibe? Was ist das für eine sinnlose Wortkonstruktion!

"ständig"?

Nunja, 8 Jahre dabei und noch nicht die Print/Serial und auch nicht die Wire Doku gelesen, obwohl du sie benutzt.
Sehr sehr eigenartig.
Fällt dir das nicht selber auf?

Is klar..
Und Dolus sind zum lesen da.

Tipp:
Manchmal ist es gar nicht so leicht Kompetenz und Arroganz zu unterscheiden.
Insbesondere, wenn....

ja, ja, diese bösen langweiligen und unverständlichen DoLus! :wink: :wink:

(konnte es mir nicht verkneifen).
Grüße Uwe

Ja, die Dokumentationen sind langweilig....
Es ist viel spannender, Stunden lang im Nebel zu stochern und von Hürde zu Hürde zu stolpern. Oder 4 Leute 2 Tage lang in Foren zu beschäftigen, weil man selber zu faul ist die Doku zu lesen.

Es gibt min. 2 Sorten von Egoisten!

  1. Die unbedingt wissen wollen, wie es geht und was alles geht, sich dafür lesend kundig machen
  2. Die welche sich gerne die Doku vorlesen lassen wollen

Jetzt darf jeder raten, wer von beiden, bei der Kompetenzstufenentwicklung fixer vorwärts kommt. Bzw. ein tieferes Verständnis erreicht.

PS:
Vertippseler kannst du dir bei mir abschauen, soviel, wie du möchtest.

Nach dem Motto:
"Nobody is perfect", und selbst der nicht zu 100%

Oder:
Wie doch ein einzelner Buchstabendreher, einen ganzen Sinnzusammenhang urinieren kann.

Und, hast du es dir angesehen? Was ist nun besser, type punning via union oder via reinterpret_cast<byte*> :question:

Oder doch lieber static_cast :question: