arduino / arduino/ArduinoCore-mbed
Missing data and significant delay between end of I2C data reception and firing of onReceive interrupt handler
- Dominant language
- C
- Stars
- 411
- Forks
- 225
- PR merge metrics
- No merged PRs in 30d
Description
### **Background:**
I have been having trouble setting up reliable communications between 2 Pico boards using i2c
I started off using Earle Philhower's Arduino-Pico RP2040 core for testing this as having previously had issues with random delays using interrupts on input pins with ArduinoCore-MBED I had to abandon it for a previous use case.
I have been unable to achieve reliable i2c communications between the 2 Pico boards, the wires are short and I went from 4.7k pull-ups to 1k pull-ups with no difference.
I created a test harness project for this and replicated a minimal version of the circuit on a breadboard using 2 brand new Pico's. I have tried many things and so far been unable to get a zero failure rate. My scope confirms that all the data is always being sent correctly, the errors occur when the receiving Pico reports less than expected number of bytes in the onReceive interrupt.
The errors occur randomly, I have tried different i2c clock speeds, 100KHz, 400KHz default and 1MHz, each speed has an impact on the failure rate. Other factors such as if the serial port is transmitting data during i2c data reception also makes a difference. I substituted a Teensy4.0 in place of the receiving Pico using the exact same code and managed to achieve a zero failure rate, even at 1MHz.
Everything I have tried so far is described over on the Arduino-Pico repo:
https://github.com/earlephilhower/arduino-pico/issues/979
By now I am quite convinced this is a hardware issue but still have some work to do in order to rule out a software issue.
Short of using the Pico SDK directly (next item on the list) to help rule out a software issue, I thought I would try out my test code on ArduinoCore-MBED, so after some minor tweaks to the i2c receiver code to make it compile I updated the receiver Pico and found that it just didn't work at all.
### **Having now explained how I got to this point, here is the separate issue I am logging in relation to ArduinoCore-MBED:**
I was sending the data to the receiving Pico at 10 Hz, the data consists of 2 blocks of data separated by a 1mS delay. I slowed this down to 1Hz to help discover what was going on and found that the delay between the end of the pair of i2c transmissions and the start of the onReceive interrupt is 264 mS !!
**In this highly zoomed out scope trace below covering several seconds, purple is the i2c clock at 400KHz firing every second, blue is the onReceive interrupt, green is some processing, yellow is the error marker. the purple cursors are measuring the time between the i2clock ending and the start of the interrupt:**

The gap between each pair of transmissions is 1mS, flowed by a 1 second gap and then another pair of transmissions and so on. The Arduino-Pico core can handle this no problem with the interrupt firing within around 20 microseconds of the the end of the first transmission, as would be expected as it is running on "bare metal", or more like "bare-silicon" with only the Pico SDK in-between.
For ArduinoCore-MBED, I would expect an RTOS to add a delay to this but certainly not over a quarter of a second, this is hardly "real time" for a "Real Time Operating System". This restricts the receive frequency to only 3 times per second.
This long delay means that the assumptions made in the i2c-receiver for testing purposes are not valid for ArduinoCore-MBED because in theory the data for both transmissions should be available inside the onReceive interrupt. If it is not all read, which is what is happening with the code as it is now then presumably there will be data left over in the buffer for the next interrupt and hence result in random numbers for the subsequent byte counts.
I intend to update the code to make it work with this large interrupt delay as I want to find out if the missing data issue still exists for ArduinoCore-MBED, although it is going to take quite some time to gather test results if it can only run at a 3Hz reception rate.
My test harness is here (PlatformIO project):
https://github.com/chrisckc/TestHarness-I2C
The i2c-receiver project has been updated to also compile for ArduinoCore-MBED
Details of the wiring etc. can be seen on the issue here:
https://github.com/earlephilhower/arduino-pico/issues/979
It would be great if someone could attempt to recreate this issue.
Contributor guide
No contributing guide indexed for this repository
Research direction
Start by reproducing the reported delay with the PlatformIO test harness and its i2c-receiver project, using the wiring and timing described here and in the linked Arduino-Pico issue. Inspect the ArduinoCore-MBED onReceive path and compare the end of the I2C transmissions with interrupt timing. Done means determining whether the delay and missing-byte behavior are reproducible and identifying the affected behavior.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- c
- Domain
- embedded-iot
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Needs clarification
- Newbie friendliness
- 25/100