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
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
0xFF, but this behavior opens some questions to me:
- How can I solve this with a block read via SMBus?
- Has anyone done this successfully?
- What am I doing wrong, here?
smbus.read_word_data(addr, cmd, data) is called with these arguments:
0x45for 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.