Page 1 of 1

I2C delayed ACKs and delay between functions

Posted: Mon Mar 11, 2024 11:07 pm
by kerkhofsward
Hi,

I'm having some trouble getting my I2C communication to work correctly. This project was ported over from an Arduino project, because of the higher communication rates of the ESP32 WROOM32. But I do know the project is working on an Arduino Uno R3.

It seems like the ACK to a command, be it a read/write/start, only gets 'checked' at the start of the next command. This causes large delays between commands, as well as some write commands not being 'saved' in the slave at the right moment.
This can be clearly seen in the first image, with the top waveform being SLC, the bottom being SDA, (function shown is i2c_master_write_read_device, also used i2c_master_write_to_device with the same issue). There is a large gap between the start and the first ACK, and this happens for nearly all operations (I think it doesn't happen for the address write, since those bytes get sent by the same command).
ESP1.PNG
ESP1.PNG (12.35 KiB) Viewed 930 times
The next image also shows this, the ACK does not seem to be checked until the next block.
ESP2.PNG
ESP2.PNG (2.38 KiB) Viewed 930 times
Does anyone know why this might happen? Or how to fix this? I have searched through the forums but couldn't find someone with the same issue, this problem did not appear on the Arduino.

Thanks in advance,
Ward

Re: I2C delayed ACKs and delay between functions

Posted: Tue Jun 11, 2024 11:40 am
by eriksl
What I am seeing is that the clock signal (which, primarily is driven by the master, the ESP32) is held for some time, which is unusual, indeed. It may be though, that I2C slave is actually pulling it down (a technique called "clock stretching"). An I2C master is required to detect this and simply wait until the clock (SCL) is released. I am not seeing clock stretching very often anymore, as most devices have an I2C slave state machine completely in hardware and they can respond instantaneously, even at higher speeds. But especially with devices that run on a microcontroller (I have a few environment sensoring modules that have this), the slave may not be able to keep up and stretch the clock.

For next steps I'd recommend:
- have another look at the scope output and see what's the maximum (!) clock rate actually used (SCL line). This is probably quite a bit higher than on your Arduino setup, unless specifically addressed. A higher clock rate may not always result in faster communication using I2C.
- check (if possible) if your device employs clock stretching
- check using another slave device that's known to be a 100% hardware implementation (most temperature sensors will do).