20X2 I2C slave with RPi - crashes the I2C bus

Lotus

Member
I have a 20X2 configured as an I2C slave, writing a value to the scratchpad, which I want to retrieve later using python code on the raspberrypi.
There are 2 devices on the bus - the 20X2 and an ADC. Both are powered by 5V but are connected to the RPi I2C through a level converter to match the RPi 3.3V bus.
Both devices are visible to the RPi when I run i2cdetect. I can communicate fine with the ADC. However, as soon as I try to communicate with the 20X2, the I2C bus seems to crash. I am using smbus on the RPi.

When I run i2cdetect on the RPi, it runs very slowly and no devices are detected. The RPi has to be powered down and restarted to recover. I am running the 20X2 at 16MHz as I read somehwere that I2C may may be marginal at 8MHz.

No doubt rather difficult to solve this one from my explanation, but any clues would be appreciated!
 
What speed is the I²C bus running at?

Do you have a Salae (or clone) logic analyser or 'scope to see what's happening at the hardware level?

What is the Picaxe doing, at the time you try and communicate with it? (Although it is supposed to be a background read, my experience is that gibberish often results if the Picaxe is busy doing 'something' else. Can you try with a simple do:loop Picaxe program?).

Does it improve at all with the ADC out of the circuit?
 
Thanks for your reply, its very much appreciated.
Unfortunately I don't have a logic analyser tho I think there may be software for the RPi that can monitor its SCL/SDA lines - will look into that.
I don't have a background in electronics so I rely a lot on forums like this and chatgpt!

My 20X2 is doing nothing - the test code just writes a value to the scratchpad and stops.
I've tried removing the ADC from the circuit altogether but same issue.
RPi can see the PICAXE I2C address but when I run the RPi code I get a timeout error - something like this:
Code:
data = bus.read_word_data(0x50,1)
TimeoutError: [Errno 110 Connection timed out]
As far as I know the RPi default bus speed is 100kHz and I think the 20X2 is same. I've not tried to change those. How can one verify the speed?
 
I've used a 50kHz signal analyser to look at the SDA/SCL lines - its not fast enough to see waveforms, but I can see that when I try to read the PICAXE the RPi SCL/SDA lines go from 3.3V to 45mV/80mV and stay there. They only come back to 3.3V after powering off and restarting the RPi. This is with the ADC removed from the board and only the 20X2 present and connected to the RPi.

When I have the ADC and the 20X2 both on board, I can talk to the ADC and although the analyser is not fast enough, I can sometimes see the SCL/SDA lines rise and fall.

When I talk to the ADC, I'm using the board module eg i2c = board.I2C() per the makers examples (ADS1115 board).
When I talk to the 20X2, I use the smBus module eg bus = smbus.SMbus(1) - which I think was an example on this forum.

Maybe there something wrong with the installation of smBus on the RPi.
Perhaps it would be better if I use the board module to talk to the 20X2 - but I've not worked out how to do that yet.
 
Thanks for your reply, its very much appreciated.
Unfortunately I don't have a logic analyser tho I think there may be software for the RPi that can monitor its SCL/SDA lines - will look into that.
I don't have a background in electronics so I rely a lot on forums like this and chatgpt!

My 20X2 is doing nothing - the test code just writes a value to the scratchpad and stops.
I've tried removing the ADC from the circuit altogether but same issue.
RPi can see the PICAXE I2C address but when I run the RPi code I get a timeout error - something like this:
Code:
data = bus.read_word_data(0x50,1)
TimeoutError: [Errno 110 Connection timed out]
As far as I know the RPi default bus speed is 100kHz and I think the 20X2 is same. I've not tried to change those. How can one verify the speed?
In slave mode, the 20X2 is just that: it is slaved to the master. If the bus clock speed is within the capability of the 20X2 and the address matches, it should resond. The clock signal from the master controls the i2c peripheral in the slave.

"My 20X2 is doing nothing - the test code just writes a value to the scratchpad and stops." Could you post the test code that your 20X2 is running? There are three ways to stop a PICAXE. "End", "Stop" or running a software loop. If your 20X2 executes an "End" statement then it will not respond to external signals. And note that the compiler inserts an "end" statement at the end of a program load - if your code allows execution to "drop through the bottom" then it will execute this implied statement and then fail to respond to external signals.
 
Folks, you are absolute legends! Thank you so much for your assistance, problem solved! (in less than 24 hours!)
My PICAXE program did indeed just write to scratchpad and then stop with an "End".
I put in a loop to keep it busy and - bingo - I can now read the 20X2 scratchpad from the RPi!
My next challenge will be to see if I can read the ADC and the 20X2 in the same program, using two different python I2C bus modules.
Fingers crossed!
 
It looked like I was home and dry but...

I managed to get the RPi to read the ADC and 20X2 through i2c. The Python code was able to collect data for an hour at a time but I'm now finding the 20X2 seems to crash the bus after a few seconds. I've removed the i2c ADC and gone back to simple test programs to try reading the 20X2 scratchpad from the RPi with nothing else happening and nothing else connected (eg serial GPS and 1-wire DS18B20's all removed from the board and software), but I get a timeout error on the RPi i2c bus quite quickly, and the I2C pins both stay low. The 20X2 is still running because it continues to print messages to the serial port regularly. All the components are on a board on top of the RPi so track and wire lengths are 10-20cm. RPi is running at the standard speed so not overclocked. Last thing I can think of is to check my soldering, and perhaps try to set a slower bus speed in the RPi.

Does anyone have any other suggestions I could look into?
 
With the 20X2 integrated so closely with the RPi, it might not be easy to tell - but how is the fault cleared? (by rebooting the RPi or rebooting the Picaxe?) This might give a clue as to which end is misbehaving.
 
Hi,
When I talk to the 20X2, I use the smBus module eg bus = smbus.SMbus(1) - which I think was an example on this forum.
Although similar, the SMBus and I2C protocols are not identical , for example I2C does not support "Packet Error Checking". Could that be related to your comment in #7: "I get a timeout error on the RPi i2c bus quite quickly, and the I2C pins both stay low." ? Does a software module exist for the RPi that is specifically intended for an I2C Bus ?

Cheers, Alan.
 
With the 20X2 integrated so closely with the RPi, it might not be easy to tell - but how is the fault cleared? (by rebooting the RPi or rebooting the Picaxe?) This might give a clue as to which end is misbehaving.
It looks like its the 20X2 rather than the other I2C device (the ADC) is causing the problem. I've not been able to power down the RPi and 20X2 separately but when both are powered down and rebooted, the fault clears.
However I have found a work-around - in my 20X2 code I was initialising the PICAXE once as a slave
Code:
hi2csetup i2cslave, %10100000
and then running the loop. I have moved that statement into the loop and so it continually clears the fault. I was going to run the loop at about 1Hz and the RPi code runs at 10Hz but that means the RPi can't read the ADC when the 20X2 has faulted. So I've sped up the 20X2 loop to run at about 10Hz to match. That means I only miss the occasional ADC read. I was concerned that the life of the 20X2 may become an issue, as I am writing to it 10 times more often than I need to. But I as far as I can establish think this should not reduce the life of the 20X2. 🤞
 
Hi,

Although similar, the SMBus and I2C protocols are not identical , for example I2C does not support "Packet Error Checking". Could that be related to your comment in #7: "I get a timeout error on the RPi i2c bus quite quickly, and the I2C pins both stay low." ? Does a software module exist for the RPi that is specifically intended for an I2C Bus ?

Cheers, Alan.
I'm very much a Python/RPi/I2C novice, but this is my understanding:
  • the ADC (ADS1115) has a Python library to configure and query the ADC. The examples for the ADC use a Python library called Board to access the RPi I2C bus.
  • SMBus is another Python module that is also for the RPi I2C bus - the example I saw for the PICAXE uses SMBus.
  • Both modules are for the I2C bus, but I think it is possible that they get in the way of each other, and maybe that is what is going on.
I'm not proficient enough to work this out, but maybe I could access both devices using the same I2C bus library. I will look into this.

As a matter of interest, my RPi Python code was written entirely by ChatGPT - totally amazed me. It ran successfully virtually the first time, after I corrected one minor error. Quite incredible. I wrote a 5-page description of what I wanted, included some snippets of code that I had tested piecemeal and it produced about 600 lines of code - a lot of which I cannot follow! I've not had to write any code myself, all I've had to do since the initial version is go back and forth to tweak things, mainly that were misinterpreted from my original spec.
 
There is a situation where I2C busses can lock up. Read here, it might be a cure for you : https://www.picaxeforum.co.uk/threa...bus-after-hardware-reset-of-the-picaxe.18654/
Had a look at that, thank you. My problem seems a bit different - in my case everything works fine initially, but at some random point the bus locks up. Re-issuing the hi2csetup clears the fault. There does not seem to be any problem with re-issuing h2csetup inside the loop, except that I am still missing the odd sample here and there.
 
Back
Top