Open JorgeMALopes opened 2 months ago
I got a pc based logic analyzer and an ESP32 S3 devkitc devboard and using the same code the same issue happens.
The ESP32's Slave works differently than all other chips we have. ESP32 needs data to be PRELOADED before the request is received. Fore reference are these lines in the slave example. That is why there is no delay between the address and the data. All other chips wait for the request to be handled and data written to the fifo, which is then returned.
In the code above, ESP32 returns the previous Wire.write
.
The issue i am having is with the ESP32-S3 as a slave.
The first byte that the S3 slave sends is the slave address and not the data that was requested and it is trying to write with
Wire.write(batata.b, 4);
in the onRequest()
.
This happens even when the master is an STM arm based flight controller.
This is also happening if i program the S3 with IDF.
I tried the code. the only change I made was to write two bytes, because that is how many you read in your master sketch and the result is as expected
requestFrom: 2
0x06, 0x03, // ..
Thank you. I have noticed that works in this case. The code i put here is a very simplified version of what i am making and in that sometimes the data comes clean and sometimes it comes contaminated with a random byte. What confuses me is that the random byte that appears is the slave address byte. Is this a normal thing?
As a further experiment into this, if you request 5 bytes and the slave writes 4 bytes the response fluctuates:
requestFrom: 5 0x61, 0x61, 0x06, 0x03, 0x03, // aa... requestFrom: 5 0x06, 0x03, 0x03, 0x03, 0x03, // ..... requestFrom: 5 0x06, 0x03, 0x03, 0x03, 0x03, // ..... requestFrom: 5 0x06, 0x03, 0x03, 0x03, 0x03, // ..... requestFrom: 5 0x06, 0x03, 0x03, 0x03, 0x03, // ..... requestFrom: 5 0x06, 0x03, 0x03, 0x03, 0x03, // ..... requestFrom: 5 0x06, 0x03, 0x03, 0x03, 0x03, // ..... requestFrom: 5 0x06, 0x03, 0x03, 0x03, 0x03, // ..... requestFrom: 5 0x06, 0x03, 0x03, 0x03, 0x03, // ..... requestFrom: 5 0x61, 0x61, 0x61, 0x61, 0x61, // aaaaa requestFrom: 5
Why is the slave address appearing in the data?
where is it appearing? the slave address is 0x30
not 0x03
Please make sure that you write as many bytes as will be read. That is important, else you are reading random bytes in the fifo
The slave address is 0x30, if you bit shift it left once and put in the read bit it becomes 0x61. This follows when i change the slave address, 0x10 becomes 0x21. This is the data that is poluting the response.
Here is a capture of the data, notice that the first byte that is received as data is the same as the address byte plus the read bit.
Also I got it to get that random byte to appear even when i request the same size of data that the slave is writing.
I did one request for 1 byte, uploaded to the esp32 master and then changed the code and requested 4 bytes and uploaded to esp32 master, now it is locked in this situation. It comes out of this situation when i reset the S3.
Also it is kind of weird that if i place 4 known bytes in the fifo and read 3 bytes the first byte is the device address bit shifted left once plus the read bit.
After some playing around i noticed that if the ESP32 S3 slave does not write to the fifo then what is read by the ESP32 master is the left bit shifted address of the slave + 1.
Does this mean that on the previous examples the ESP32 S3 slave is to slow to populate the fifo?
I hope i am not being annoying, am truly trying to figure this out. I am trying to avoid having to replace the ESP32 S3 with something else that is more stable.
Thanks for all the help.
You must read as many bytes as you wrote. That is all. No other tricks are necessary
I will try that. Thank you.
Same issue happens irregularly.
Master code:
#include "Wire.h"
#define I2C_DEV_ADDR 0x30
typedef union { // union for sending int via i2c
int i;
byte b[4];
} Dados_I;
typedef union { // union for sending float via i2c
float f;
byte b[4];
} Dados_F;
typedef union { // union for sending a boolean via i2c
bool bo;
byte b[1];
} Dados_Bool;
// values that are requested from the smart battery
const int req_health = 1; // battery health
const int req_voltage = 2; // total battery voltage
const int req_cell_count = 3; // cell count
const int req_rem_capacity_pct = 4; // remaining capacity in percentage
const int req_cycle_count = 5; // cycle count
const int req_current = 6; // battery current
const int req_consumed_mah = 7; // consumed capacity in mah
const int req_consumed_wh = 8; // consumed capacity in wh
const int req_temperature = 9; // battery temperature
const int req_cell_voltage_1 = 11; // cell voltages for each of the cells
const int req_cell_voltage_2 = 12;
const int req_cell_voltage_3 = 13;
const int req_cell_voltage_4 = 14;
const int req_cell_voltage_5 = 15;
const int req_cell_voltage_6 = 16;
const int req_cell_voltage_7 = 17;
const int req_cell_voltage_8 = 18;
const int req_cell_voltage_9 = 19;
const int req_cell_voltage_10 = 20;
const int req_cell_voltage_11 = 21;
const int req_cell_voltage_12 = 22;
const int req_cell_voltage_13 = 23;
const int req_cell_voltage_14 = 24;
const int req_cell_voltage_15 = 25;
const int req_cell_voltage_16 = 26;
const int req_cell_voltage_17 = 27;
const int req_cell_voltage_18 = 28;
const int req_cell_voltage_19 = 29;
const int req_cell_voltage_20 = 30;
const int req_cell_voltage_21 = 31;
const int req_cell_voltage_22 = 32;
const int req_cell_voltage_23 = 33;
const int req_cell_voltage_24 = 34;
Dados_Bool health; // local variable where the batttery health is stored
Dados_F voltage; // local variable where the batttery voltage is stored (V)
Dados_I cell_count; // local variable where the batttery cell count is stored
Dados_I rem_capacity_pct; // local variable where the batttery capacity is stored (%)
Dados_I cycle_count; // local variable where the batttery cycle count is stored
Dados_F current; // local variable where the batttery current count is stored (A)
Dados_F consumed_mah; // local variable where the batttery consumed mah is stored (mah)
Dados_F consumed_wh; // local variable where the batttery consumed wh is stored (wh)
Dados_F temperature; // local variable where the batttery temperature is stored (c)
Dados_I cell_voltage_1; // local variables where the batttery cell voltages are stored (mv)
Dados_I cell_voltage_2;
Dados_I cell_voltage_3;
Dados_I cell_voltage_4;
Dados_I cell_voltage_5;
Dados_I cell_voltage_6;
Dados_I cell_voltage_7;
Dados_I cell_voltage_8;
Dados_I cell_voltage_9;
Dados_I cell_voltage_10;
Dados_I cell_voltage_11;
Dados_I cell_voltage_12;
Dados_I cell_voltage_13;
Dados_I cell_voltage_14;
Dados_I cell_voltage_15;
Dados_I cell_voltage_16;
Dados_I cell_voltage_17;
Dados_I cell_voltage_18;
Dados_I cell_voltage_19;
Dados_I cell_voltage_20;
Dados_I cell_voltage_21;
Dados_I cell_voltage_22;
Dados_I cell_voltage_23;
Dados_I cell_voltage_24;
void setup() {
Serial.begin(115200);
Serial.setDebugOutput(true);
Wire.begin();
}
void loop() {
delay(500);
health.b[0] = i2cBoolGet(req_health);
voltage.f = i2cFloatGet(req_voltage);
cell_count.i = i2cIntGet(req_cell_count);
rem_capacity_pct.i = i2cIntGet(req_rem_capacity_pct);
cycle_count.i = i2cIntGet(req_cycle_count);
current.f = i2cFloatGet(req_current);
consumed_mah.f = i2cFloatGet(req_consumed_mah);
consumed_wh.f = i2cFloatGet(req_consumed_wh);
temperature.f = i2cFloatGet(req_temperature);
cell_voltage_1.i = i2cIntGet(req_cell_voltage_1);
cell_voltage_2.i = i2cIntGet(req_cell_voltage_2);
cell_voltage_3.i = i2cIntGet(req_cell_voltage_3);
cell_voltage_4.i = i2cIntGet(req_cell_voltage_4);
cell_voltage_5.i = i2cIntGet(req_cell_voltage_5);
cell_voltage_6.i = i2cIntGet(req_cell_voltage_6);
cell_voltage_7.i = i2cIntGet(req_cell_voltage_7);
cell_voltage_8.i = i2cIntGet(req_cell_voltage_8);
cell_voltage_9.i = i2cIntGet(req_cell_voltage_9);
cell_voltage_10.i = i2cIntGet(req_cell_voltage_10);
cell_voltage_11.i = i2cIntGet(req_cell_voltage_11);
cell_voltage_12.i = i2cIntGet(req_cell_voltage_12);
cell_voltage_13.i = i2cIntGet(req_cell_voltage_13);
cell_voltage_14.i = i2cIntGet(req_cell_voltage_14);
cell_voltage_15.i = i2cIntGet(req_cell_voltage_15);
cell_voltage_16.i = i2cIntGet(req_cell_voltage_16);
cell_voltage_17.i = i2cIntGet(req_cell_voltage_17);
cell_voltage_18.i = i2cIntGet(req_cell_voltage_18);
cell_voltage_19.i = i2cIntGet(req_cell_voltage_19);
cell_voltage_20.i = i2cIntGet(req_cell_voltage_20);
cell_voltage_21.i = i2cIntGet(req_cell_voltage_21);
cell_voltage_22.i = i2cIntGet(req_cell_voltage_22);
cell_voltage_23.i = i2cIntGet(req_cell_voltage_23);
cell_voltage_24.i = i2cIntGet(req_cell_voltage_24);
Serial.println("=====================");
Serial.print("health.bo = "); Serial.println(health.b[0]);
Serial.print("voltage.f = "); Serial.println(voltage.f);
Serial.print("cell_count.i = "); Serial.println(cell_count.i);
Serial.print("rem_capacity_pct.i = "); Serial.println(rem_capacity_pct.i);
Serial.print("cycle_count.i = "); Serial.println(cycle_count.i);
Serial.print("current.f = "); Serial.println(current.f);
Serial.print("consumed_mah.f = "); Serial.println(consumed_mah.f);
Serial.print("consumed_wh.f = "); Serial.println(consumed_wh.f);
Serial.print("temperature.f = "); Serial.println(temperature.f);
Serial.print("cell_voltage_1.i = "); Serial.println(cell_voltage_1.i);
Serial.print("cell_voltage_2.i = "); Serial.println(cell_voltage_2.i);
Serial.print("cell_voltage_3.i = "); Serial.println(cell_voltage_3.i);
Serial.print("cell_voltage_4.i = "); Serial.println(cell_voltage_4.i);
Serial.print("cell_voltage_5.i = "); Serial.println(cell_voltage_5.i);
Serial.print("cell_voltage_6.i = "); Serial.println(cell_voltage_6.i);
Serial.print("cell_voltage_7.i = "); Serial.println(cell_voltage_7.i);
Serial.print("cell_voltage_8.i = "); Serial.println(cell_voltage_8.i);
Serial.print("cell_voltage_9.i = "); Serial.println(cell_voltage_9.i);
Serial.print("cell_voltage_10.i = "); Serial.println(cell_voltage_10.i);
Serial.print("cell_voltage_11.i = "); Serial.println(cell_voltage_11.i);
Serial.print("cell_voltage_12.i = "); Serial.println(cell_voltage_12.i);
Serial.print("cell_voltage_13.i = "); Serial.println(cell_voltage_13.i);
Serial.print("cell_voltage_14.i = "); Serial.println(cell_voltage_14.i);
Serial.print("cell_voltage_15.i = "); Serial.println(cell_voltage_15.i);
Serial.print("cell_voltage_16.i = "); Serial.println(cell_voltage_16.i);
Serial.print("cell_voltage_17.i = "); Serial.println(cell_voltage_17.i);
Serial.print("cell_voltage_18.i = "); Serial.println(cell_voltage_18.i);
Serial.print("cell_voltage_19.i = "); Serial.println(cell_voltage_19.i);
Serial.print("cell_voltage_20.i = "); Serial.println(cell_voltage_20.i);
Serial.print("cell_voltage_21.i = "); Serial.println(cell_voltage_21.i);
Serial.print("cell_voltage_22.i = "); Serial.println(cell_voltage_22.i);
Serial.print("cell_voltage_23.i = "); Serial.println(cell_voltage_23.i);
Serial.print("cell_voltage_24.i = "); Serial.println(cell_voltage_24.i);
Serial.println();
}
byte i2cBoolGet(int command) {
Wire.beginTransmission(I2C_DEV_ADDR); // transmit to device #4
Wire.write(command); // sends one byte
Wire.endTransmission(); // stop transmitting
byte value[1];
Wire.requestFrom(I2C_DEV_ADDR, 1);
Wire.readBytes(value, 1);
return value[0];
}
int i2cIntGet(int command) {
Wire.beginTransmission(I2C_DEV_ADDR); // transmit to device #4
Wire.write(command); // sends one byte
Wire.endTransmission(); // stop transmitting
Dados_I value;
Wire.requestFrom(I2C_DEV_ADDR, 4);
Wire.readBytes(value.b, 4);
return value.i;
}
float i2cFloatGet(int command) {
Wire.beginTransmission(I2C_DEV_ADDR); // transmit to device #4
Wire.write(command); // sends one byte
Wire.endTransmission(); // stop transmitting
Dados_F value;
Wire.requestFrom(I2C_DEV_ADDR, 4);
Wire.readBytes(value.b, 4);
return value.f;
}
Slave code:
#include "Wire.h" // i2c library
#define I2C_DEV_ADDR 0x30 // i2c adress, needs to be the same as in the lua script
int opcode = 0; // received operation code
int i2cCommand = 0; // received i2c command
typedef union { // union for sending int via i2c
int i;
byte b[4];
} Dados_I;
typedef union { // union for sending float via i2c
float f;
byte b[4];
} Dados_F;
typedef union { // union for sending a boolean via i2c
bool bo;
byte b[1];
} Dados_Bool;
// values that are requested from the smart battery
const int req_health = 1; // battery health
const int req_voltage = 2; // total battery voltage
const int req_cell_count = 3; // cell count
const int req_rem_capacity_pct = 4; // remaining capacity in percentage
const int req_cycle_count = 5; // cycle count
const int req_current = 6; // battery current
const int req_consumed_mah = 7; // consumed capacity in mah
const int req_consumed_wh = 8; // consumed capacity in wh
const int req_temperature = 9; // battery temperature
const int req_cell_voltage_1 = 11; // cell voltages for each of the cells
const int req_cell_voltage_2 = 12;
const int req_cell_voltage_3 = 13;
const int req_cell_voltage_4 = 14;
const int req_cell_voltage_5 = 15;
const int req_cell_voltage_6 = 16;
const int req_cell_voltage_7 = 17;
const int req_cell_voltage_8 = 18;
const int req_cell_voltage_9 = 19;
const int req_cell_voltage_10 = 20;
const int req_cell_voltage_11 = 21;
const int req_cell_voltage_12 = 22;
const int req_cell_voltage_13 = 23;
const int req_cell_voltage_14 = 24;
const int req_cell_voltage_15 = 25;
const int req_cell_voltage_16 = 26;
const int req_cell_voltage_17 = 27;
const int req_cell_voltage_18 = 28;
const int req_cell_voltage_19 = 29;
const int req_cell_voltage_20 = 30;
const int req_cell_voltage_21 = 31;
const int req_cell_voltage_22 = 32;
const int req_cell_voltage_23 = 33;
const int req_cell_voltage_24 = 34;
Dados_Bool health; // local variable where the batttery health is stored
Dados_F voltage; // local variable where the batttery voltage is stored (V)
Dados_I cell_count; // local variable where the batttery cell count is stored
Dados_I rem_capacity_pct; // local variable where the batttery capacity is stored (%)
Dados_I cycle_count; // local variable where the batttery cycle count is stored
Dados_F current; // local variable where the batttery current count is stored (A)
Dados_F consumed_mah; // local variable where the batttery consumed mah is stored (mah)
Dados_F consumed_wh; // local variable where the batttery consumed wh is stored (wh)
Dados_F temperature; // local variable where the batttery temperature is stored (c)
Dados_I cell_voltage_1; // local variables where the batttery cell voltages are stored (mv)
Dados_I cell_voltage_2;
Dados_I cell_voltage_3;
Dados_I cell_voltage_4;
Dados_I cell_voltage_5;
Dados_I cell_voltage_6;
Dados_I cell_voltage_7;
Dados_I cell_voltage_8;
Dados_I cell_voltage_9;
Dados_I cell_voltage_10;
Dados_I cell_voltage_11;
Dados_I cell_voltage_12;
Dados_I cell_voltage_13;
Dados_I cell_voltage_14;
Dados_I cell_voltage_15;
Dados_I cell_voltage_16;
Dados_I cell_voltage_17;
Dados_I cell_voltage_18;
Dados_I cell_voltage_19;
Dados_I cell_voltage_20;
Dados_I cell_voltage_21;
Dados_I cell_voltage_22;
Dados_I cell_voltage_23;
Dados_I cell_voltage_24;
void setup() {
Serial.begin(115200); // start the serial port, used for debuging
Serial.setDebugOutput(true);
Wire.begin(I2C_DEV_ADDR, 42, 41, 0 ); // start the i2c channel with the I2C_DEV_ADDR adress
Wire.onReceive(onReceive); // if there is a i2c receive call then onReceive function is called
Wire.onRequest(onRequest); // if there is a i2c request call then onRequest function is called
Serial.println("setup");
}
void loop() {
setValues();
}
void onReceive(int len) { // on receive function, used to update local variables or activate local functions
Serial.print("receive[");
Serial.print(len);
Serial.print("]: ");
i2cCommand = 0; // resets the command
opcode = Wire.read(); // reads the operation code
Serial.print(opcode);
if (len == 2) { // if there are 2 bytes
i2cCommand = Wire.read(); // the second byte is the command
Serial.print(", ");
Serial.print(i2cCommand);
}
Serial.println();
}
void onRequest() { // on request function, sends data via i2c depeding on the request
Serial.print("request: ");
Serial.println(opcode);
loadValues();
}
void setValues(){
health.bo = true;
voltage.f = 35.5;
cell_count.i = 10;
rem_capacity_pct.i = 55;
cycle_count.i = 10;
current.f = 40.35;
consumed_mah.f = 20.2;
consumed_wh.f = 11.3;
temperature.f = 30.2;
cell_voltage_1.i = 3000;
cell_voltage_2.i = 3000;
cell_voltage_3.i = 3000;
cell_voltage_4.i = 3000;
cell_voltage_5.i = 3000;
cell_voltage_6.i = 3000;
cell_voltage_7.i = 3000;
cell_voltage_8.i = 3000;
cell_voltage_9.i = 3000;
cell_voltage_10.i = 3000;
cell_voltage_11.i = 4;
cell_voltage_12.i = 4;
cell_voltage_13.i = 4;
cell_voltage_14.i = 4;
cell_voltage_15.i = 4;
cell_voltage_16.i = 4;
cell_voltage_17.i = 4;
cell_voltage_18.i = 4;
cell_voltage_19.i = 4;
cell_voltage_20.i = 4;
cell_voltage_21.i = 4;
cell_voltage_22.i = 4;
cell_voltage_23.i = 4;
cell_voltage_24.i = 4;
}
void loadValues(){
switch (opcode) {
case req_health:
Wire.write(health.b, 1);
break;
case req_voltage:
Wire.write(voltage.b, 4);
break;
case req_cell_count:
Wire.write(cell_count.b, 4);
break;
case req_rem_capacity_pct:
Wire.write(rem_capacity_pct.b, 4);
break;
case req_cycle_count:
Wire.write(cycle_count.b, 4);
break;
case req_current:
Wire.write(current.b, 4);
break;
case req_consumed_mah:
Wire.write(consumed_mah.b, 4);
break;
case req_consumed_wh:
Wire.write(consumed_wh.b, 4);
break;
case req_temperature:
Wire.write(temperature.b, 4);
break;
case req_cell_voltage_1:
Wire.write(cell_voltage_1.b, 4);
break;
case req_cell_voltage_2:
Wire.write(cell_voltage_2.b, 4);
break;
case req_cell_voltage_3:
Wire.write(cell_voltage_3.b, 4);
break;
case req_cell_voltage_4:
Wire.write(cell_voltage_4.b, 4);
break;
case req_cell_voltage_5:
Wire.write(cell_voltage_5.b, 4);
break;
case req_cell_voltage_6:
Wire.write(cell_voltage_6.b, 4);
break;
case req_cell_voltage_7:
Wire.write(cell_voltage_7.b, 4);
break;
case req_cell_voltage_8:
Wire.write(cell_voltage_8.b, 4);
break;
case req_cell_voltage_9:
Wire.write(cell_voltage_9.b, 4);
break;
case req_cell_voltage_10:
Wire.write(cell_voltage_10.b, 4);
break;
case req_cell_voltage_11:
Wire.write(cell_voltage_11.b, 4);
break;
case req_cell_voltage_12:
Wire.write(cell_voltage_12.b, 4);
break;
case req_cell_voltage_13:
Wire.write(cell_voltage_13.b, 4);
break;
case req_cell_voltage_14:
Wire.write(cell_voltage_14.b, 4);
break;
case req_cell_voltage_15:
Wire.write(cell_voltage_15.b, 4);
break;
case req_cell_voltage_16:
Wire.write(cell_voltage_16.b, 4);
break;
case req_cell_voltage_17:
Wire.write(cell_voltage_17.b, 4);
break;
case req_cell_voltage_18:
Wire.write(cell_voltage_18.b, 4);
break;
case req_cell_voltage_19:
Wire.write(cell_voltage_19.b, 4);
break;
case req_cell_voltage_20:
Wire.write(cell_voltage_20.b, 4);
break;
case req_cell_voltage_21:
Wire.write(cell_voltage_21.b, 4);
break;
case req_cell_voltage_22:
Wire.write(cell_voltage_22.b, 4);
break;
case req_cell_voltage_23:
Wire.write(cell_voltage_23.b, 4);
break;
case req_cell_voltage_24:
Wire.write(cell_voltage_24.b, 4);
break;
default:
break;
}
}
What i should be getting is:
I am getting this:
Notice the decimal 97 =0x61 when i request the health byte and the 768097 value, if you convert it into hex you get 0x0B, 0xB8 and 0x61, the value that is the slave adress bit shifted left + 1.
There are no tricks, I send the same amount of bytes that are requested.
It fixes itself if i reset the slave. This is not optimal.
I don't know why the code breaks when i paste it into the code tags. I'm sorry for that.
I have slightly revised your example above. Mostly prints and it's functionally the same. I use the same pins and all.
One suggestion for your use case. Use Wire.slaveWrite(data, len)
instead of Wire.write(data, len)
. Then you can load the values directly in the onReceive
callback. That will make communication faster too. Also do not print inside the callbacks. It takes time and slows things down.
void onReceive(int len) { // on receive function, used to update local variables or activate local functions
i2cCommand = 0; // resets the command
opcode = Wire.read(); // reads the operation code
if (len == 2) { // if there are 2 bytes
i2cCommand = Wire.read(); // the second byte is the command
}
loadValues(); // load the values here
}
void onRequest() {
}
void loadValues(){
switch (opcode) {
case req_health:
Wire.slaveWrite(health.b, 1);
break;
case req_voltage:
Wire.slaveWrite(voltage.b, 4);
break;
............
Wonderful. Thank you. I will try it now.
@JorgeMALopes any news?
It worked with the code as is. But stops working when i add the rest. In the device i am making the ESP32S3 is an interpreter for a BQ769142. The S3 controls and gets the data from the BQ769142, via I2C as a master, does some simple calculations and then feeds it via I2C to a flight controller as slave.
As soon as i add the BQ769142 code to it the communication with the flight controller breaks. I am going to desolder the S3 from the board and wire up a standard ESP32 and try that. If i have success i will inform. For now i think the S3 is not a viable device for an i2c slave.
Thanks for all the help.
Still no success with the regular ESP32. I have a question but i am unsure if i should create a new thread elsewhere or ask here so i can figure out how to fix this or if this is fixable.
Can an ESP32 be an i2c master on one bus and obtain data from a bunch of sensors, do some calculations and then have it available as a slave on a separate bus?
Thanks for all the help.
yes it can
Ok, going to try and figure that out. Thanks for everything.
Figured it out. Tried it with a S3, it works.
Modified my main code, did not work with either esp32 or S3. Start hunting down the culprit. Found it. It was trying to write to a position outside of an array.
There is no bug in the I2C bus on the S3, it just behaves differently when compared to the regular ESP32, but still works fine as long as you ask as many bytes as you write on the other side.
I think i can finish the rest of the code.
I think this thread can be closed now. Thanks for all the help!!
Board
ESP32 S3 wroom 1
Device Description
Just an USB port, and a TI battery monitor.
Hardware Configuration
Currently only working with just the CPU, but has a TI battery monitor connected to the other I2C port.
Version
v3.0.3
IDE Name
Arduino IDE
Operating System
windows 10
Flash frequency
80MHz
PSRAM enabled
no
Upload speed
921600
Description
When i connect an ESP32S3 as an I2C slave to an ESP32 or a drone flight controller, as a master, the data comes out wrong. When i reverse the code and the S3 is the master and the ESP32 is the slave then the data comes out correct.
I made a simple sketch where the slave returns 4 bytes when there is a request, 0x01FF0306 or 0x01FF03FF. The master requests a variable amount of bytes, sometimes more, sometimes less. When the S3 is the slave the first byte received from it is the slave address followed by part of the slave data. When the ESP32 is the slave then only data is returned.
I have asked a friend to lend me his oscilloscope so i can check the data lines for each case.
These are the lines for the S3 as a slave, notice the long time after the request and the repetition of the slave address.
This is the lines for ESP32 as slave, the delay is minimal and there is no repetition of the slave address.
The most stable case was then the returned bytes where of the same quantity as the requested ones, but sometimes the device address appears in the beginning and the only way to fix it is to reset the S3 which is not a viable solution.
I have tested with wire and wire1 and tested with other connections on the S3.
Sketch
Debug Message
Other Steps to Reproduce
No response
I have checked existing issues, online documentation and the Troubleshooting Guide