Description
Board
nodemcu-32s
Device Description
Two nodemcu-32s boards with 2 wires connecting them.
Hardware Configuration
SDA: 21
SCL: 22
Version
v2.0.1
IDE Name
PlatformIO
Operating System
Windows
Flash frequency
40Mhz
PSRAM enabled
no
Upload speed
115200
Description
Two esp's are connected using i2c and communicate with each other. One is set to be slave, the other as master.
I slightly modified the example codes provided at https://espressif-docs.readthedocs-hosted.com/projects/arduino-esp32/en/latest/api/i2c.html. The difference is that the master will only make requests and that the slave will reply with an incrementing number.
What I found is that when the slave gets to number 171, it returns error "[951709][E][esp32-hal-i2c-slave.c:406] i2cSlaveWrite(): TX IDLE WAIT TIMEOUT!".
I was able to track it down to the following piece of code in file framework-arduinoespressif32@3.20001.0\cores\esp32\esp32-hal-i2c-slave.c. On line 406, this error is called when a time-out occurs when i2c_ll_slave_addressed(i2c->dev) && i2c_ll_slave_rw(i2c->dev) stay true. The second expression should be false in this case, since the master released the bus (just like when I send 170 or 172), but it stays true.
It turned out that when I changed the address of the slave to 0x56, number 171 could be send, but now the error occured while sending number 173. What probably happens is the following:
The binary representation of address 0x55 is 01010101 and of address 0x56 is 01010110.
The binary representation of number 171 is 10101011 and of number 173 is 10101101.
What I found is that the numbers can be converted to the corresponding address by doing a left bit-shift on the address and next adding 1 (01010101 -bit-shift->10101010-add 1->10101011 = 171 dec).
This actually corresponds with the way I2C represents their addresses: it takes the 7 LSBs and the last bit is a r/w bit, so in case of address 0x55 and r/w-bit being one this would become: 1010101 for the address and then 1 for the r/w-bit = 10101011 = 171.
Could it be that the slave reads its own message and handles it as if the master is saying it is in read mode?
Sketch
On master ESP:
#include "Wire.h"
#define SLAVE_ADDR 0x55
#define I2C_Freq 100000
#define SDA_0 21
#define SCL_0 22
uint8_t i = 0;
void setup() {
Serial.begin(115200);
Serial.setDebugOutput(true);
Wire.begin(SDA_0 , SCL_0 , (uint32_t) I2C_Freq);
}
void loop() {
delay(1000);
char reading[64];
memset(reading, 0, sizeof(reading));
uint8_t error = 0;
error = Wire.requestFrom(SLAVE_ADDR, 1);
Serial.printf("requestFrom: %u\n", error);
if(error){
delay(10);
Wire.readBytes(reading, error);
Serial.printf("data: %u\n", reading[0]);
} else {
Serial.printf("Request failed.");
}
Serial.flush();
}
On slave ESP:
#include "Wire.h"
#define SLAVE_ADDR 0x55
#define I2C_Freq 100000
#define SDA_1 21
#define SCL_2 22
uint32_t i = 0;
void onRequest(){
Wire.print("Hello World");
Serial.println("onRequest");
}
void onReceive(int len){
char out[1];
out[0] = i;
Serial.printf("PL: %d\n", out[0]);
Wire.write(out);
i++;
}
void setup() {
Serial.begin(115200);
Serial.setDebugOutput(true);
Wire.onReceive(onReceive);
Wire.onRequest(onRequest);
Wire.begin((uint8_t) SLAVE_ADDR, SDA_1, SCL_2, (uint32_t) I2C_Freq);
}
void loop() {
}
Debug Message
[951709][E][esp32-hal-i2c-slave.c:406] i2cSlaveWrite(): TX IDLE WAIT TIMEOUT!
Other Steps to Reproduce
No response
I have checked existing issues, online documentation and the Troubleshooting Guide
- I confirm I have checked existing issues, online documentation and Troubleshooting guide.
Metadata
Metadata
Assignees
Labels
Type
Projects
Status