This code catches I2C communication by running on an ESP32 board that are conected to I2C BUS lines as a passive listener.
The code was used to reverse engineer a tool that uses a I2C comunication between main unit and temperature measure board. The task was to catch the communication between the units.
The board that runs the program is a ESP32 board, because it works on 240MHz. This allows to execute a few command in one cycle of an I2C data commonication, even the communication goes on 400kHz. Any slower board cannot work, because it cannot execute enough commands between comming bits.
This is not connecting to the BUS as an I2C device. It is neither a Master, nor a Slave and never puts data on any line. It just listens and logs the communication. The application does not interrupt the I2C communication.
Two pins of the ESP32 panel (GPIO12 for SDA, GPIO13 for SCL) as definet input in the code are attached to SDC and SDA lines of the observed unit. Since the I2C communication usually operates on 400kHz so, the tool that runs this program should be fast. This was tested on an ESP32 bord Heltec WiFi Lora32 v2. ESP32 core runs on 240MHz. It means there are about 600 ESP32 cycles during one I2C clock tick.
The code uses interrupts to detect the changes of SDA and SCL lines.
In the interrupt routines there are just a few lines of code that mainly sets the status and stores the incoming bits. Otherwise the program gets timeout panic in interrupt handler and restarts the CPU. In the main loop the program checks if there is anything in the incoming buffer and prints it out to the Serial console. Meaning of characters:
Output example:
S1101101W+00110000+00001000+s
In case of continuous I2C communication the program may show improper data after a while or even crash.
The reason is that the program uses a fix sized array to store the incoming I2C bits. If it gets overloaded then bits from the communication may be missed. The display mechanism reads the content from the array and resets the array writing mechanism.
If the incoming data comes faster than the display mechanism deletes the content of the array, then the array will be overwritten after a while. Since the overload situation is not handled it may crash the application too. In my case this solution was acceptable, because I2C communication was not continuous, but measure unit sends data in every 10sec or so only.
Workaround should be to increase the size of the array. It works if the data flow is not continuous, just longer then the original size of the buffer and the display period.
Another simple solution could be to prevent the crash is to detect the overwrite situation by checking the writing position of the buffer and stop the writing, or even the whole program.
If you connect the pins directly to the I2C BUS in operation you may harm either the unit you observe or your ESP32 device (anything can go wrong, like mismatching lines, volt levels, inputs or outputs, etc.). Being on the safe side a simple solution can save your devices when you isolate your tool from the observed device. For this purpose I highly recommend the IC that I also use ISO154x Low-Power Bidirectional I2C Isolators. One side you connects the ground, power and I2C lines that you want to listen and to the other side you connects your independent ESP32 based board that runs the code with its own ground, power and I2C lines.