I'm trying to Connect my Raspberry Pi 3B+ with a Raspbian 10 to an INA219 current sensor (that also returns voltage and a premultiplied power) via SMBus in Python 3.7. After destroying one Raspberry 2B I ended up with a Raspbian 10, installed on a Raspberry 2B and now running the same image on a Raspberry 3B+. This worked perfectly, but I will try a clean OS installation, if the problem is suspected to come from the OS installation.

Please note, I'm aware of Adafruit libraries, but I can't use them in my case, as they don't read registers all at once and they are not compatible to a framework I'm using, but SMBus is.

I can read each register and perform setup/calibration according to some easy-to-find examples and with the help of the data sheet, but I can't get smbus.read_i2c_block_data(addr, cmd, data) to work.

After searching for similar problems I basically came across the issue of a repeated start-condition as opposed to a stop-condition. I know that SMBus is just a subset of I²C and that this may apply, here, but the datasheet states that SMBus is supported. It even uses a repeated start-condition in the high-speed I²C handshake. Also echo -n 1 > /sys/module/i2c_bcm2708/parameters/combined didn't help (and it was gone after a reboot, so I would have to add another startup dependency, anyway).

When I read each register with smbus.read_word_data(addr, cmd, data) (after initializing config and calibration with 2 calls to smbus.write_word_data(addr, cmd, data) at the right point in time) I get this, for example:

[0, 66, 40, 216, 0, 7, 0, 24]

This is completely fine and it translates to 0.6 mV shunt voltage, 5.2 V bus voltage, 38 mW power and 6.6 mA current, which is correct. But when I try to read the registers 0x01 to 0x04 at once (words split into big endian bytes, and yes, starting at 0x01 is correct), I get:

[0, 0, 0, 66, 0, 255, 0, 255]

The first line always changes according to measured values and the first 2 bytes of both sequences are roughly equal (here, it is equal, but it sometimes differed a bit). So the first register seems to be read. The rest of the second sequence only contains 0xFF bytes, no matter how many registers I want to read.

Normally, if I make mistakes, I mostly get I/O errors or read values are rather 0x00 than 0xFF, but this behavior opens some questions to me:

  1. How can I solve this with a block read via SMBus?
  2. Has anyone done this successfully?
  3. What am I doing wrong, here?

Edit: smbus.read_word_data(addr, cmd, data) is called with these arguments:

  • addr=0x40 (also 0x41, 0x44, 0x45 for one of my 4 sensors respectively)
  • cmd=0x01: starts with the second register
  • data=0x04: reads 4 consecutive 16 bit registers
  • returns a list of 4 short integers (16 bit each)

I also tried to set data=0x08, as I wasn't sure, if I didn't miss something and the function would actually read bytewise instead of per register. I noticed that I made a mistake with the interpretation, so I updated the suspicios result above, too.

With the BME280 sensor, I use read_word_data just as I do it here. That works fine.

  • Just a quick reply. I spent over 20+ hours to learn to use Rpi3B+ stretch IDLE python 3.7.3 SMBus block read and failed (will give you the link of details later). Then I googled to find that the SMBus block read is not completely supported. What is worst is the following: (1) You cannot do "bus/cycle" stretching, (2) You cannot lower I2C speed, say to 10kHz, as a get around faking cycle stretching. Now the good news, Rpi4B buster can lower I2C speed to fake cycle stretching, and solve/get around related SMBus block read problems. – tlfong01 Nov 13 at 2:02
  • The following forum posts are related to my testing I2C block read commands: raspberrypi.org/forums/…. – tlfong01 Nov 13 at 4:57
  • 2
    You are making us guess at the call which is failing. That wastes our time and your time. read_i2c_block_data(addr, cmd, data) takes three parameters. I have no idea what you have set them too. Please edit your question to include the command issued and the response. – joan Nov 13 at 11:16
  • Clock stretching is a huge kludge regardless, at least IMO. – crasic Nov 15 at 2:15

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.