Neu: Die KI-Firewall überwacht die gesamte Plattform und erklärt jeden Vorfall in einfachen Worten. So funktioniert es

Floats come out as garbage when my Uno reads a Nano over I2C

Floats come out as garbage when my Uno reads a Nano over I2C

Gelöst 6 5

Greenhouse controller, two boards: a Nano reads soil probes and a DS18B20 and acts as I2C slave at 0x08; an Uno is master, collects from the Nano and passes everything over serial to an ESP32 that publishes to Hermetry. The ints (moisture raw, 0-1023) come through fine. The temperature float arrives as nonsense like -2.3e-38 or nan, and Hermetry refuses the key whenever it’s NaN, so the chart has holes.

Slave side:

void onRequest() {
  Wire.write(moisture1 >> 8); Wire.write(moisture1 & 0xFF);
  Wire.write(moisture2 >> 8); Wire.write(moisture2 & 0xFF);
  Wire.write((byte)tempC);     // tried this first, lost decimals
  Wire.write((byte*)&tempC, 4);
}

Master does Wire.requestFrom(8, 9) and reads bytes back into the same variables.

Timestamps in UTC or it didn't happen.
♥ 0

Could you send it as a string and parse it on the other end? That’s what I did for serial.

Still waiting for the gateway to reconnect.
♥ 0

Strings over I2C waste bytes and you only get 32 per transfer. Show the master side, I bet that’s where it breaks.

Measure twice, poll once.
♥ 2

master side, sorry, should have included it:

Wire.requestFrom(8, 9);
m1 = (Wire.read() << 8) | Wire.read();
m2 = (Wire.read() << 8) | Wire.read();
Wire.read();                       // the old byte
for (int i = 0; i < 4; i++) ((byte*)&t)[i] = Wire.read();
Timestamps in UTC or it didn't happen.
♥ 1

Following, I have a similar setup planned for our hotel greenhouse.

♥ 0

Two bugs, and a third waiting to happen. I did nearly this exact thing on a test rig years ago.

1. On the slave, each Wire.write() inside onRequest on AVR replaces the buffer instead of adding to it in some library versions, and the order of evaluation in (Wire.read() << 8) | Wire.read() on the master isn’t defined in C++, so the bytes can come out swapped.

2. The stray single byte shifts everything if the counts ever disagree.

Do it with one struct on both sides and one write:

struct __attribute__((packed)) Packet {
  uint16_t m1, m2;
  int16_t  t_x100;      // 23.47 C -> 2347, no float on the wire
  uint8_t  seq;
};
// slave
void onRequest() { Wire.write((uint8_t*)&pkt, sizeof(pkt)); }
// master
Packet p;
if (Wire.requestFrom(8, sizeof(p)) == sizeof(p))
  Wire.readBytes((uint8_t*)&p, sizeof(p));
float t = p.t_x100 / 100.0;

Scaled integers avoid any float layout question if the slave ever becomes an ESP or an STM32. The seq byte tells you if you’re reading a stale packet. And on the ESP32 side, skip the key entirely if a reading is invalid instead of sending NaN, NaN isn’t valid JSON anyway.

Ground loops are my cardio.
Akzeptierte Lösung♥ 4

Struct with scaled int fixed it. Temperature has been clean since yesterday afternoon, no gaps on the chart. The evaluation order thing was news to me.

Timestamps in UTC or it didn't happen.
♥ 0
Ansicht von 7 Beiträgen – 1 bis 7 (von insgesamt 7)
  • Du musst angemeldet sein, um auf dieses Thema antworten zu können.

Mitdiskutieren

Melde dich an, um Fragen zu stellen und zu beantworten, hilfreiche Beiträge mit „Gefällt mir“ zu markieren und die Antwort zu kennzeichnen, die dein Problem gelöst hat. Jeder Beitrag bringt Punkte und Stufen.

Teilen