New: the AI firewall watches the whole platform and explains each incident in plain words. See how it works

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

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.
Accepted solution♥ 4