0

I'm having some issues reading flow sensor data (Sensirion LPG10, to be precise) using the RPi Zero's I2C bus.

I think I have set the bus and wiring up correctly as running 'i2cdetect -y 1' returns the correct device address (0x40) as specified in the sensor's datasheet.

The sensor datasheet specifies that I first write a byte (value 0xf1) to trigger a sensor measurement, then read a byte word (so, 2 bytes for the data, a 3rd for a checksum if I desire) immediately after. This information is in section 4.4 and is specified as the first thing to try.

I manage to detect that the sensor is there on the I2C bus, and I manage to write the first byte - at least, no I/O errors are returned with either the smbus or pigpio modules at this stage.

However, when attempting to read the bytes - whether individually in order, or reading all at once - I get errors. With smbus it's a little complex as read_word_data specifies a register, which isn't provided in the datasheet - pigpio lets me use i2c_read_device(0x40, 2) which should theoretically work, but doesn't.

The code snippets I tried:

# pigpio

addr = 0x40    # Sensor address
pi = pigpio.pi()

handle = pi.i2c_open(1, addr)

pi.i2c_write_byte(handle, 0xf1)

# Here I have tried on and off various time.sleep values

(len, bytes) = pi.i2c_read_device(handle, 2)

# Error handling
if len < 0:
    print(pigpio.error_text(len))
pi.i2c_close(handle)
pi.stop()
#smbus
from smbus import SMBus
bus = SMBus(1)
i2cBus.write_byte(0x40, 0xf1)

#Trying to return even a single byte, let alone the 2-byte word, fails
byte = i2cBus.read_byte(0x40) # Fails with I/O error
# I can't find a way to read the 2-byte word with smbus either as it specifies a register/channel which the sensor does not seem to specify

It is worth noting that I have not changed any of the other Raspberry Pi I2C interface settings, other than to ensure it is enabled in raspi-config and rebooting afterwards.

I don't see anything particularly different in their example code (Arduino, though): Example code The only difference I see is the baud rate set to 9600, but their datasheet specified that 100kbps baud rate (I believe the RPi default) is workable so I don't see how this would be the issue, if the datasheet is correct (and it likely is!)

Can anyone figure out where I'm going wrong? Thank you so much in advance, any help is greatly appreciated!

3
  • The pigpio code is wrong. The bus is not opened. Try these commands from the command line. pigs i2co 1 0x40 0 get a handle for the device. Then pigs i2cwd 0 0xf1 then pigs i2crd 0 3.
    – joan
    Commented Aug 7, 2020 at 16:56
  • Sorry, I think I missed the open function from the code I copied, but I think it's included - will confirm when I'm home though. I will definitely try the command line inputs when I'm home though, thank you very much for those! Much appreciated. I'll update once I've tried.
    – TheFaustie
    Commented Aug 7, 2020 at 20:21
  • I did have the bus open included, but wasn't in my question, so I've edited that, thanks for the pointer. I had a look and tried your command line inputs: the first one returned '0' (I assume handle flag); the second one did not return anything but also didn't fail, so assuming that's a good write; the third returns 'ERROR: i2C read failed (-83)'. I'm wondering if there's an electrical issue also but I would be surprised as the address/write both seem to work OK.
    – TheFaustie
    Commented Aug 7, 2020 at 22:51

1 Answer 1

0

Looking at the datasheet it seems the problem is likely to be clock stretching by the slave. This is not supported by the Pi's I2C driver.

My pigpio does support bit banging I2C which should allow a test of this theory.

See bb_i2c_zip,

Implement the following untested snippet as a test.

SDA=2
SCL=3
baud=50000

pi.bb_i2c_open(SDA, SCL, baud)

# address 0x40            4 0x40
# start                   2
# write one byte 0xf1     7 1 0xf1
# restart                 2
# read 3 bytes            6 3
# stop                    3
# end                     0

cmd = [4, 0x40, 2, 7, 1, 0xf1, 2, 6, 3, 3, 0]

(count, data) = pi.bb_i2c_zip(SDA, cmd)

print(count, data)

# at the end of the session

pi.bb_i2c_close(SDA)
3
  • Thank you for this! Sorry for the delay in getting back to you. I tried the bb_i2c_zip function and it worked perfectly; my code is slightly different to yours but I'm definitely getting good readings now, so thank you again. Good to know also that this is due to clock stretching; I'll look more into this as many of the other sensors I have to implement mention this in their datasheet. I think I will work primarily with bb_i2c_zip from now on. Your pigpio library is excellent; the docs were really detailed, describing low-level transactions helped me a lot. Thanks very much!
    – TheFaustie
    Commented Aug 10, 2020 at 15:22
  • That's good to hear. For the sake of portability it's best to only use the bit bang functions when the hardware driver functions don't work.
    – joan
    Commented Aug 10, 2020 at 15:47
  • Good to know, will keep that in mind, thank you!
    – TheFaustie
    Commented Aug 10, 2020 at 16:34

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.