wmaniac
Posts: 1
Joined: Tue Oct 12, 2021 5:20 am

I2C read_block_data Error121

Tue Oct 12, 2021 6:42 am

Hi this is my first post, cause I don't know where I could still look.
I try to communicatate with an flow sensor via I2C with the following components.
Hardware Like shown in the application notes https://posifatech.com/wp-content/uploa ... n-Note.pdf the pi had to read 5 bytes on block and this is whrer the problem begins.
I tried it with the following code:

Code: Select all

#!/usr/bin/env python3
import time
import smbus2 as smbus
class PMF2013:
    def __init__(self, *args, **kwargs):
        self.flowmeter=smbus.SMBus(1)
        time.sleep(2)
        self.address = 0x50
        checksum=[]
        reading=self.flowmeter.read_i2c_block_data(self.address,0,5)
        print(reading)
        #try:
        #self.flowmeter.write_quick(self.address)
        #checksum=self.flowmeter.read_byte(self.address) # read 8Bit checksum => works => 193
        #checksum=self.flowmeter.read_block_data(self.address,ading=i2c0x00) # read <=32 bytes register=0
        #checksum=self.flowmeter.read_i2c_block_data(self.address,0,3, force=True) # ==> gibt auf Scope richtige Werte + ACK
        #checksum=self.flowmeter.read_word_data(self.address,0)
        #print(checksum)
        #while True:
        #    checksum=self.flowmeter.read_byte(self.address) # = 193 0xC1 i2c
        #    print(checksum)
        #    time.sleep(1)
        #except Exception:
            #print('Error init PMF2014')
            #print(Exception)
flowmeter=PMF2013()
If i read a single byte I got an response, but if I try to read 5 bytes on block I got an error 121.
What I have tried so far: Attached you can see the picture from the oscilloscope.The sensor is responding the correct 5 Bytes and also an ACK but it seems that the Pi doesn't recognize it.
I am glad about every kind of help how to proceed.
Attachments
Scope.png
Scope.png (245.4 KiB) Viewed 343 times

cdsteinkuehler
Posts: 14
Joined: Thu Feb 11, 2021 2:24 am
Contact: Website

Re: I2C read_block_data Error121

Tue Oct 12, 2021 1:01 pm

Based on your 'scope trace, either you have bus contention on your I2C lines, or the sensor is extending the I2C transaction using clock stretching and isn't pulling the SCK/SDA lines low particularly hard. It looks like the latter to me, and I expect you are encountering the well known RPi I2C clock stretching bug: http://www.advamation.com/knowhow/raspb ... c-bug.html

It appears the sensor holds the clock line low at multiple points during the transfer which results in several "runt" clock pulses (eg: preceeding the first two "Data - 00" and the "Data - 4B" bytes). If the short clock pulses are not recognized by the sensor, the I2C communication can get out of sync and you will get corrupt data. However what appears to be happening in your case is the RPi I2C hardware is reading the ACK state when it first releases the SCK line and not when the sensor releases the SCK line (after a significant delay and then driving SDA low). So to the RPi, the sensor did not ACK the transaction and doesn't appear to be on the bus.

Sadly, there is no simple way to get the buggy Broadcom I2C hardware to work properly with this sort of I2C clock stretching device. If you can afford the overhead, the best option would probably be to use a software "bit-bang" implementation of I2C such as the i2c-gpio driver.

6by9
Raspberry Pi Engineer & Forum Moderator
Raspberry Pi Engineer & Forum Moderator
Posts: 11783
Joined: Wed Dec 04, 2013 11:27 am
Location: ZZ9 Plural Z Alpha, aka just outside Cambridge.

Re: I2C read_block_data Error121

Tue Oct 12, 2021 2:17 pm

cdsteinkuehler wrote:
Tue Oct 12, 2021 1:01 pm
Sadly, there is no simple way to get the buggy Broadcom I2C hardware to work properly with this sort of I2C clock stretching device. If you can afford the overhead, the best option would probably be to use a software "bit-bang" implementation of I2C such as the i2c-gpio driver.
OP says they're on Pi4. Memory says the additional I2C interfaces on Pi4 (ie i2c3 to i2c6) have the clock stretching bug fixed.
Software Engineer at Raspberry Pi Trading. Views expressed are still personal views.
I'm not interested in doing contracts for bespoke functionality - please don't ask.

FlynnTheAvatar
Posts: 11
Joined: Wed Apr 07, 2021 6:23 pm

Re: I2C read_block_data Error121

Tue Oct 12, 2021 5:56 pm

6by9 wrote:
Tue Oct 12, 2021 2:17 pm
OP says they're on Pi4. Memory says the additional I2C interfaces on Pi4 (ie i2c3 to i2c6) have the clock stretching bug fixed.
Sadly not. Just tested i2c5 (pins 12 and 13) with Spark SerLCD 20x4. Still throws Error 121 after a few seconds like on i2c1. The only option is still using "bit-banging" (i2c-gpio).

trejan
Posts: 3706
Joined: Tue Jul 02, 2019 2:28 pm

Re: I2C read_block_data Error121

Tue Oct 12, 2021 6:07 pm

FlynnTheAvatar wrote:
Tue Oct 12, 2021 5:56 pm
6by9 wrote:
Tue Oct 12, 2021 2:17 pm
OP says they're on Pi4. Memory says the additional I2C interfaces on Pi4 (ie i2c3 to i2c6) have the clock stretching bug fixed.
Sadly not. Just tested i2c5 (pins 12 and 13) with Spark SerLCD 20x4. Still throws Error 121 after a few seconds like on i2c1. The only option is still using "bit-banging" (i2c-gpio).
The additional I2C controllers do have working clock stretching. I used it before with an IMU module that needed it. It would fail on the original I2C controllers.

I think you've got a different issue anyway. I doubt that the Sparkfun I2C LCD needs clock stretching.

FlynnTheAvatar
Posts: 11
Joined: Wed Apr 07, 2021 6:23 pm

Re: I2C read_block_data Error121

Tue Oct 12, 2021 6:23 pm

trejan wrote:
Tue Oct 12, 2021 6:07 pm
FlynnTheAvatar wrote:
Tue Oct 12, 2021 5:56 pm
6by9 wrote:
Tue Oct 12, 2021 2:17 pm
OP says they're on Pi4. Memory says the additional I2C interfaces on Pi4 (ie i2c3 to i2c6) have the clock stretching bug fixed.
Sadly not. Just tested i2c5 (pins 12 and 13) with Spark SerLCD 20x4. Still throws Error 121 after a few seconds like on i2c1. The only option is still using "bit-banging" (i2c-gpio).
The additional I2C controllers do have working clock stretching. I used it before with an IMU module that needed it. It would fail on the original I2C controllers.

I think you've got a different issue anyway. I doubt that the Sparkfun I2C LCD needs clock stretching.
I am pretty sure that it does. I could capture the bug on my osci: https://forum.sparkfun.com/viewtopic.ph ... ry#p225327

Or it is a different issue with the Raspberry Pi's I2C implementation.

trejan
Posts: 3706
Joined: Tue Jul 02, 2019 2:28 pm

Re: I2C read_block_data Error121

Tue Oct 12, 2021 6:50 pm

FlynnTheAvatar wrote:
Tue Oct 12, 2021 6:23 pm
I am pretty sure that it does. I could capture the bug on my osci: https://forum.sparkfun.com/viewtopic.ph ... ry#p225327
I don't know what your issue is there but the additional I2C controllers definitely do support clock stretching. I was using a Pi 4 with a Bosch BNO055 which requires it. On the original controllers, you had to greatly slow down the I2C clock so it wouldn't need to clock stretch. It works with no issues on the new controllers. If there is some other compatibility issue then I don't know.

I'm surprised that the SerLCD firmware is so busy doing other things that it can't service the peripheral interrupt fast enough. What happens if you slow down the I2C clock even more? If it is a clock stretching issue then eventually the clock will get slow enough that it will work.

FlynnTheAvatar
Posts: 11
Joined: Wed Apr 07, 2021 6:23 pm

Re: I2C read_block_data Error121

Tue Oct 12, 2021 6:56 pm

trejan wrote:
Tue Oct 12, 2021 6:50 pm
FlynnTheAvatar wrote:
Tue Oct 12, 2021 6:23 pm
I am pretty sure that it does. I could capture the bug on my osci: https://forum.sparkfun.com/viewtopic.ph ... ry#p225327
I don't know what your issue is there but the additional I2C controllers definitely do support clock stretching. I was using a Pi 4 with a Bosch BNO055 which requires it. On the original controllers, you had to greatly slow down the I2C clock so it wouldn't need to clock stretch. It works with no issues on the new controllers. If there is some other compatibility issue then I don't know.

I'm surprised that the SerLCD firmware is so busy doing other things that it can't service the peripheral interrupt fast enough. What happens if you slow down the I2C clock even more? If it is a clock stretching issue then eventually the clock will get slow enough that it will work.
Lowering the I2C clock does help, but it never completely prevented the issue from appearing. If I have time I will try to capture the issue again with my Osci using i2c5.

trejan
Posts: 3706
Joined: Tue Jul 02, 2019 2:28 pm

Re: I2C read_block_data Error121

Tue Oct 12, 2021 7:06 pm

FlynnTheAvatar wrote:
Tue Oct 12, 2021 6:56 pm
Lowering the I2C clock does help, but it never completely prevented the issue from appearing. If I have time I will try to capture the issue again with my Osci using i2c5.
How slow did you go? Default is 100000 but I needed under 50000 for the BNO055. Some people recommended even lower and to use 10000 instead. Maybe there is still an issue but its speed related?

I've had the misfortune to need to debug something which had a SerLCD in UART mode. It has some non-intuitive behaviour like forcing factory defaults if the RX line is low at startup. This is still better than the old SerLCD which would force factory defaults if it received anything in the first 1s after startup.

FlynnTheAvatar
Posts: 11
Joined: Wed Apr 07, 2021 6:23 pm

Re: I2C read_block_data Error121

Tue Oct 12, 2021 7:25 pm

trejan wrote:
Tue Oct 12, 2021 7:06 pm
FlynnTheAvatar wrote:
Tue Oct 12, 2021 6:56 pm
Lowering the I2C clock does help, but it never completely prevented the issue from appearing. If I have time I will try to capture the issue again with my Osci using i2c5.
How slow did you go? Default is 100000 but I needed under 50000 for the BNO055. Some people recommended even lower and to use 10000 instead. Maybe there is still an issue but its speed related?

I've had the misfortune to need to debug something which had a SerLCD in UART mode. It has some non-intuitive behaviour like forcing factory defaults if the RX line is low at startup. This is still better than the old SerLCD which would force factory defaults if it received anything in the first 1s after startup.
I went down to 10kHz. At that speed the failures were rare, but my digital clock python script still failed after some hours. If I have to reduce the speed to 10kHz, I can also use bit-banging.

Please note that I do not have any issues driving the SerLCD using a Raspberry PI Pico using the standard 100kHz baudrate.

trejan
Posts: 3706
Joined: Tue Jul 02, 2019 2:28 pm

Re: I2C read_block_data Error121

Tue Oct 12, 2021 7:36 pm

FlynnTheAvatar wrote:
Tue Oct 12, 2021 7:25 pm
I went down to 10kHz. At that speed the failures were rare, but my digital clock python script still failed after some hours. If I have to reduce the speed to 10kHz, I can also use bit-banging.

Please note that I do not have any issues driving the SerLCD using a Raspberry PI Pico using the standard 100kHz baudrate.
Hmm. Not sure what is going on here. You're seeing the clock stretching blip on the scope and slowing the clock does help but doesn't completely fix it. Clock stretching works for me and somebody else mentioned it was working on the forum but they were also using a Bosch chip IIRC so not really conclusive evidence there. I don't have that BNO055 anymore or a SerLCD so I can't test it again.

FlynnTheAvatar
Posts: 11
Joined: Wed Apr 07, 2021 6:23 pm

Re: I2C read_block_data Error121

Thu Oct 14, 2021 9:25 am

trejan wrote:
Tue Oct 12, 2021 7:36 pm
FlynnTheAvatar wrote:
Tue Oct 12, 2021 7:25 pm
I went down to 10kHz. At that speed the failures were rare, but my digital clock python script still failed after some hours. If I have to reduce the speed to 10kHz, I can also use bit-banging.

Please note that I do not have any issues driving the SerLCD using a Raspberry PI Pico using the standard 100kHz baudrate.
Hmm. Not sure what is going on here. You're seeing the clock stretching blip on the scope and slowing the clock does help but doesn't completely fix it. Clock stretching works for me and somebody else mentioned it was working on the forum but they were also using a Bosch chip IIRC so not really conclusive evidence there. I don't have that BNO055 anymore or a SerLCD so I can't test it again.
I could capture the SCL blip on the scope with i2c5 and 10kHz:
https://1drv.ms/u/s!ApOoV0ole8uGq_xUa-A ... A?e=7ZcpIJ. It is like the blip when using i2c1.

For me it looks like the clock stretching bug. But I am not an expert. If somebody out there does know what this issue is, please tell me. I really like to know what is going wrong and how to work around it (other than using bit-banging I2C).

For comparison, this is a shot using a Pi Pico using hardware I2C with a baudrate of 100kHz. I do see short clock pulses, but all components (Pi Pico, SerLCD and scope) can handle it: https://1drv.ms/u/s!ApOoV0ole8uGq_xTEeR ... A?e=8ncZqh.

Return to “Interfacing (DSI, CSI, I2C, etc.)”