As the title says, I encountered a strange issue while doing a PoC using an Arduino UNO R2 as the I2C master and an ESP32 as the I2C slave.
I initially found ESP32 documentation suggesting the use of Wire.slaveWrite, but the sample code they provided seemed certified retarded. I replaced all Wire.write calls with Wire.slaveWrite in my Wire.onRequest handler, but it did not solve the issue.
The order of events shown in the slave’s serial console debug output looked correct. However, the master’s serial console—and even the I2C oscilloscope—showed the previous response from the slave.
Interestingly, when I moved the Wire.onRequest logic to execute immediately after Wire.onReceive, it magically fixed the stale slave response seen by the master. Now I’m scratching my head trying to understand why.
AI suggestions didn’t help either—it proposed many incorrect solutions, and none of them fixed the problem.
#include <Wire.h>
#define I2C_SLAVE_ADDR 0x55
#define SDA_PIN 16
#define SCL_PIN 17
uint8_t volatile receivedValue = 0;
void setup() {
Serial.begin(9600);
Wire.begin(I2C_SLAVE_ADDR, SDA_PIN, SCL_PIN, 0);
Wire.onReceive(receiveEvent);
Wire.onRequest(requestEvent);
Serial.println("Simple I2C Slave Ready");
}
void loop() {
delay(100);
}
void receiveEvent(int numBytes) {
if (Wire.available()) {
receivedValue = Wire.read();
Serial.print("[SLAVE] Received: 0x");
Serial.println(receivedValue, HEX);
//
// Move from requestEvent
//
uint8_t responseValue = receivedValue + 0x50;
//Wire.write(responseValue);
Wire.slaveWrite(&responseValue, 1);
Serial.print("[SLAVE] Sending back: 0x");
Serial.print(receivedValue, HEX);
Serial.print(" + 0x50 = 0x");
Serial.println(responseValue, HEX);
// Clear any remaining bytes
while (Wire.available()) {
Wire.read();
}
}
}
void requestEvent() {
// move to receiveEvent!!!
}
Boring I2C master in UNO R2
#include <Wire.h>
// Arduino UNO I2C pins:
// SDA: Pin A4
// SCL: Pin A5
const int SLAVE_ADDRESS = 0x55;
int counter = 1;
void setup() {
Serial.begin(9600);
Wire.begin(); // Initialize as I2C master
Serial.println("Arduino UNO I2C Master Started");
Serial.println("Sending counter 1-100 to slave at address 0x55");
Serial.println("--------------------------------------------");
}
void loop() {
if (counter <= 100) {
// Send counter value to slave
Wire.beginTransmission(SLAVE_ADDRESS);
Wire.write(counter);
Wire.endTransmission();
delay(50); // Small delay to allow slave to process
// Request echo back from slave
Wire.requestFrom(SLAVE_ADDRESS, 1);
if (Wire.available()) {
int echo = Wire.read();
Serial.print("[MASTER] Sent: 0x");
Serial.print(counter, HEX);
Serial.print(" | [SLAVE] Echo: 0x");
Serial.println(echo, HEX);
} else {
Serial.print("[MASTER] Sent: 0x");
Serial.print(counter, HEX);
Serial.println(" | [SLAVE] No response");
}
counter++;
} else {
// Reset counter after reaching 100
counter = 1;
Serial.println("--------------------------------------------");
Serial.println("Counter reset to 1");
Serial.println("--------------------------------------------");
}
delay(100); // Wait 500ms between transmissions
}
