PR29-1 current sensor wrong output with python

Hi,

I have a PR29-1 single channel current monitor. This is connected to an Onion omega 2+ with ethernet and I2C shield.

I am having trouble getting sensible output from the PR29-1 (all outputs are max values of 255). I have tried using the onion I2C python module, as well as using pythons’s smbus2 module. It could be that I dont have the right register address, but I dont see it in the documentation.

Below the code and results for both approaches:
Onion I2C python module
I modified this script: https://github.com/bhaskar-anil429/Onion-Omega-Current-Monitoring/blob/master/Current_monit.py

from OmegaExpansion import onionI2C
import time
import sys
print 'Starting: onionI2C module testing...'
i2c     = onionI2C.OnionI2C(0)
# set the verbosity
i2c.setVerbosity(1)
command2 = [0x6A, 0x02, 0x00, 0x00, 0x00, 0x00, 0xFE]
#while True:
#print ""
#ret = raw_input('  Ready to read?')
data = i2c.writeBytes(0x2A,0x92,command2)
#print '   Read returned: ', data
print ' write bytes: ', command2
# Convert the data to 14-bits
time.sleep(0.5)
data = i2c.readBytes(0x2A, 0x55, 3)
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


while True:
        command1 = [0x6A, 0x01, 0x01, 0x06, 0x00, 0x00, 0x04]

        data2 = i2c.writeBytes(0x2A,0x92,command1)
        print ' write bytes: ', command1
        time.sleep(0.5)
        data1 = i2c.readBytes(0x2A, 0x55, noOfChannel * 3)
        # Convert the data
        #while True:
        for i in range(0, noOfChannel) :
                msb1 = data1[i * 3]
                #print ' msb1: ', msb1
                msb = data1[1 + i * 3]
                #print ' msb: ', msb
                lsb = data1[2 + i * 3]
                #print ' lsb: ', lsb
                #print ' i: ', i
                # 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
                time.sleep(5)
                print "\n"
print "New Updated Current Values are: "

I get this output

Starting: onionI2C module testing...
 write bytes:  [106, 2, 0, 0, 0, 0, 254]
onion-i2c:: Reading 3 bytes from device 0x2a: addr = 0x55       read 3 bytes, value: 0xffffff
Type of Sensor : 255
Maximum Current : 255 A
No. of Channels : 255
 write bytes:  [106, 1, 1, 6, 0, 0, 4]
Traceback (most recent call last):
  File "./testC2.py", line 33, in <module>
    data1 = i2c.readBytes(0x2A, 0x55, noOfChannel * 3)
OverflowError: Attempting to read more bytes than I2C max buffer: 32.

Using the smbus2 approach
I use this script

#!/usr/bin/python

from smbus2 import SMBus
import time
import sys

print "Content-Type: text/plain\r\n\r\n"

# Get I2C bus
bus = SMBus(0)

# 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)

time.sleep(0.5)

# 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, 0x01, 0x00, 0x00, 0xff]       #channel 1 only

calibrationRead = [0x6A,  0x03,  0x01,  0x0C, 0x00,  0x00, 0x0C]

bus.write_i2c_block_data(0x2A, 0x92, command1)

time.sleep(0.5)

# 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, (noOfChannel*3)+1)
data1 = bus.read_i2c_block_data(0x2A, 0x55, 37)

readings = ""

print data1
sys.exit()

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

    # Convert the data to ampere
    current = (msb1 * 65536 + msb * 256 + lsb) / 1000.0
    readings += str("%.3f" %current)
    readings += "|"

readings = readings[:-1]
print readings
    # Output data to screen
    #print "Channel no : %d " %(i + 1)
#print "Current Value : %.3f A" %current

I get this output

Content-Type: text/plain


Type of Sensor : 255
Maximum Current : 255 A
No. of Channels : 255
Traceback (most recent call last):
  File "./testC.py", line 52, in <module>
    data1 = bus.read_i2c_block_data(0x2A, 0x55, 37)
  File "/usr/lib/python2.7/site-packages/smbus2/smbus2.py", line 385, in read_i2c_block_data
    raise ValueError("Desired block length over %d bytes" % I2C_SMBUS_BLOCK_MAX)
ValueError: Desired block length over 32 bytes

hi, this code was written for onion omega 1.
Omega 2 i2c needs to be modified to make it work.

once you do that , you can use this script to read the current

Thanks