Restarting I2C without reboot
-
I am struggling with a error on the arduino dock 2 where after a couple of hours of flawless communication between onion and arduino, the I2C port locks up and returns a random single value between 0x63 and 0x99 for any command value sent without sending anything out on the port.
In short - onion says it's receiving a value but there is no further comms between it and the dock. This happens with both python and using i2cset/i2cget and it only affects the dock - other I2C devices keep functioning.
The only way I have managed so far to recover from this is to reboot which is not ideal as it resets the arduino as well. I do not know enough about how the drivers are loaded - Can anyone suggest a way to reset the onion I2C without rebooting?
-
@Paul-Cousins said in Restarting I2C without reboot:
The only way I have managed so far to recover from this is to reboot which is not ideal as it resets the arduino as well. I do not know enough about how the drivers are loaded - Can anyone suggest a way to reset the onion I2C without rebooting?
I dont think I can help but I have a question, Are there any pullups on the i2c lines?
You communicate between an Arduino using i2C and not RX/TX ?
-
@brolly759 said in Restarting I2C without reboot:
Are there any pullups on the i2c lines?
There are 4.7kOhm pull-up resistors on the I2C lines of Omega2(+)'s PCB.
-
@Paul-Cousins Does it happen on your nice IoT ONE board or a genuine Arduino Dock 2?
If the on board ATmega is an I2C slave - is its (well debugged program / sketch running?
For Arduino Dock 2 vs Omega 2(+) troubleshooting:
- you should put a jumper between GPIO19 and the 1kOhm serial base resistor of the 'MCU RESET' transistor and left it open
- you could "cut" all the rest connections between Omega2 and the Dock if you tie to GND the 1kOhm pull-up resistor at pin 10 of the TXS0108E level shifter
- you could halt ATmega and put its all lines to high impedance state if you tie its RESET pin to GND (eg. with pin3 of Arduino 'POWER' header or with the MCU_RESET button)
-
@György-Farkas said in Restarting I2C without reboot:
IoT ONE board or a genuine Arduino Dock 2?
My IoT ONE board contains a genuine arduino dock 2. This happens when running the dock standalone too. The sketch is running fine as I am watching regular data updates on it's serial port which shows that it stops receiving any i2c request from the omega when this fault occurs
@brolly759 I have additional pullups as well through the level shifting circuit. It's not likely to be hardware as the RTC and OLED still update fine
-
@Paul-Cousins You have a fairly complicated HW. You are running a program on it and we know practically nothing about your SW.
So hard to say something because anything can happen.What does this mean precisely? (For example this "the I2C port locks up" ???)
... after a couple of hours of flawless communication between onion and arduino, the I2C port locks up and returns a random single value between 0x63 and 0x99 for any command value sent without sending anything out on the port.
And this:
Can anyone suggest a way to reset the onion I2C without rebooting?
As you know the Omega2's I2C bus is a single master bus and there's no repeated START. So all transactions begin with a START and are terminated by a STOP. START and STOP conditions (and the SCL signal) are always generated by the master. In Standard Mode after the STOP condition + 4.7usec the bus is considered to be free - ie. both SDA and SCL are HIGH / should be HIGH (is this your 'I2C reset' state ?) - if not you have some SW or HW bug.
Formerly you want to reboot Omega without reset the Arduino. If this workaround satisfies you then put a jumper between GPIO19 and the base of the 'MCU RESET' transistor and left it open. This is definitely simpler than @Zheng-Han's idea
-
@György-Farkas said in Restarting I2C without reboot:
What does this mean precisely? (For example this "the I2C port locks up" ???)
Simplified Software flow:
while True:
size = 1
addr = 0x0E ## this is my control register - set to 1 when arduino has data to share
update_flag = i2c.readBytes(devAddres, addr, size)
if update_flag[0] > 0 or first_run_flag > 0:
first_run_flag = 0
addr = 0x20
counter_1_val = i2c.readBytes(devAddres, addr, size)... then i read through a whole bunch of other data registers and write to sql db. Once the last register is read then the arduino clears the update flag and we cycle through every 300ms or so
This runs perfectly for many hours and then no matter which register is read i still get the last value of the last register read no matter which address i get or set. Nothing is sent to the arduino on the i2c bus but there is still a response on the i2c.readBytes() function.
At this point even i2cset and i2cget return the same value as python call does. Resetting the arduino at this time does not help either
This only happens with the arduino dock address 0x08 - the oled and RTC still work fine.
Can anyone suggest a way to reset the onion I2C without rebooting? <-- i would like to restart /dev/i2c-0 to see if this module is stuck
A lot of grey hair and some worry about the reliabilty of my product...
-
@Paul-Cousins Let's suppose the Arduino Dock 2 and its HW environment on your IoT ONE board are perfect.
So your Arduino SW - almost certainly - has some bug(s).
You should debug it instead of restart the Omega's I2C master from time to time - I think.