12-Channel On-Board AC Current Monitor with I2C Interface

Hi there, I couldn’t find any topics that my question could fall under.

I recently purchases a AC current monitor with I2C interface and I am putting it with a raspberry pi. When I ran the sample code I got an error that I cant find on google.

The complete sample code is in this link: https://github.com/ControlEverythingCommunity/PECMAC/blob/master/Python/PECMAC125A.py

I am getting the error in this line:
data1 = bus.read_i2c_block_data(0x2A, 0x55, noOfChannel*3)

This is the error:
Traceback (most recent call last):
File “/home/pi/Documents/CurrentSensor.py”, line 43, in
data1 = bus.read_i2c_block_data(0x2A, 0x55, 36)
OSError: [Errno 22] Invalid argument

Thank you for any help you could give me

Hi Alberto, it looks like the data being passed to read_i2c_block_data is of the incorrect type. It should be a byte and its being passed as an integer. If you’re wanting to pass the byte value of 36 then you should use 0x20.

That should work, but let me know if not.

Thanks, it works for the first 10 channels, then it says this:
Traceback (most recent call last):
File “/home/pi/Documents/CurrentSensor.py”, line 49, in
lsb = data1[2 + i * 3]
IndexError: list index out of range

I’ll have to see your code. My assumption is that its a mismatch of byte and integer values being used, but I won’t know until I see the whole code and context.

it works for first 10 channel because the i2c read buffer size is 32 bytes and when you try to read all 12 channels the total number of bytes gets to 36 bytes.
you can do this
first read 1-10 and then read 11-12.


I tried to read from 1-10 then 11-12 but couldn’t figure out how to do it.
What could I read to understand better this?

Also if helping me modify the code is possible, I will appreciate the time
This is the code that I am using that outputs ten channels then the error:

import smbus
import time

# Get I2C bus
bus = smbus.SMBus(1)

# PECMAC125A address, 0x2A(42)
# Command for reading device identification data
# 0x6A(106), 0x02(2), 0x00(0),0x00(0), 0x00(0) 0x00(0), 0xFE(254)
# Header byte-2, command-2, byte 3, 4, 5 and 6 are reserved, checksum
command2 = [0x6A, 0x02, 0x00, 0x00, 0x00, 0x00, 0xFE]
bus.write_i2c_block_data(0x2A, 0x92, command2)


# PECMAC125A address, 0x2A(42)
# Read data back from 0x55(85), 3 bytes
# Type of Sensor, Maximum Current, No. of Channels
data = bus.read_i2c_block_data(0x2A, 0x55, 3)

# Convert the data
typeOfSensor = data[0]
maxCurrent = data[1]
noOfChannel = data[2]

# Output data to screen
print("Type of Sensor : %d" %typeOfSensor)
print("Maximum Current : %d A" %maxCurrent)
print("No. of Channels : %d" %noOfChannel)

# PECMAC125A address, 0x2A(42)
# Command for reading current
# 0x6A(106), 0x01(1), 0x01(1),0x0C(12), 0x00(0), 0x00(0) 0x0A(10)
# Header byte-2, command-1, start channel-1, stop channel-12, byte 5 and 6 reserved, checksum
command1 = [0x6A, 0x01, 0x01, 0x0C, 0x00, 0x00, 0x0A]
bus.write_i2c_block_data(0x2A, 0x92, command1)


# PECMAC125A address, 0x2A(42)
# Read data back from 0x55(85), No. of Channels * 3 bytes
# current MSB1, current MSB, current LSB
data1 = bus.read_i2c_block_data(0x2A, 0x55, 0x20)

# Convert the data
for i in range(0, noOfChannel):
    msb1 = data1[i * 3]
    lsb = data1[2 + i * 3]
    msb = data1[1 + i * 3]

	# Convert the data to ampere
    current = (msb1 * 65536 + msb * 256 + lsb) / 1000.0
	# Output data to screen
    print("Channel no : %d " %(i + 1))
    print("Current Value : %.3f A" %current)

Sorry for the format, still learning

here you go


1 Like

Ah, Bhaskar’s right, the SMBus library has a max buffer length of 32 bytes and the sample code is returning 36 so it would cut off the data for the last few channels.

1 Like