i2c python

Hi,

I’m writing a python script to communicate via i2c with the ph oem sensor from Atlas Scientific.

https://www.atlas-scientific.com/product_pages/oem/oem_ph.html
https://www.atlas-scientific.com/_files/_datasheets/_oem/pH_oem_datasheet.pdf

I already tried with the i2c module of mraa and smbus without luck.

Now I am trying to translate this arduino example from Atlas to python but I read garbage

Any suggestions?, attached the full example arduino code

Atlas arduino code
`

byte i2c_device_address=0x65;
byte starting_register=0x00
byte device_type;
byte version_number;
Wire.beginTransmission(i2c_device_address);
Wire.write(staring_register);
Wire.endTransmission();
Wire.requestFrom(i2c_device_address,(byte)2);
device_type = Wire.read();
version_number = Wire.read();
Wire.endTransmission();

`

My python script

`
import smbus

General i2c device class so that other devices can be added easily

class i2c_device:
def init(self, addr, port):
self.addr = addr
self.bus = smbus.SMBus(port)

def write(self, byte):
self.bus.write_byte(self.addr, byte)

def read(self):
return self.bus.read_byte(self.addr)

def read_nbytes_data(self, data, n): # For sequential reads > 1 byte
return self.bus.read_i2c_block_data(self.addr, data, n)

ph = i2c_device(0x65, 2)
ph.write(0x00)

device_type = ph.read()
version_number = ph.read()
print(device_type)
print(version_number)

`

OEM_pH_Sample_code.ino (33.6 KB)

OK.
Let’s start with some background information.
What model of Beaglebone?
What version of OS, kernel?
Which version of Python?
How is the pH sensor hooked to the Beaglebone?
What Voltage are you using to power the pH sensor?

Now some basics to see if the I2C bus is running

sudo apt-get install i2c-tools

now run
i2cdetect -y -r 1
what do you get?

now run
i2cdetect -y -r 2
what do you get?

When you say that you get “garbage” what do you mean?
What do you actually get? errors? tracebacks? obviously wrong data, but no reported errors?

— Graham

Hi Graham, thanks

here more info

HW: Beaglebone seeedstudio green wireless
OS: Debian GNU/Linux 8.8 (jessie)
Kernel: Linux beaglebone 4.4.30-ti-r64
Python: Python 2.7.9

I made a custom cape, the sensor it’s power with 3.3v and conected to I2C_2 through an isolator

SDA → P9.20
SCL → P9.19

The HW it’s OK, I check with an arduino and example code and I can write registers with my python script on the beaglebone.

The ph sensor is in 0x65 address and other Atlas sensor in 0x64

`

debian@beaglebone:~$ i2cdetect -y -r 2
0 1 2 3 4 5 6 7 8 9 a b c d e f
00: – -- – -- – -- – -- – -- – -- –
10: – -- – -- – -- – -- – -- – -- – -- – --
20: – -- – -- – -- – -- – -- – -- – -- – --
30: – -- – -- – -- – -- – -- – -- – -- – --
40: – -- – -- – -- – -- – -- – -- – -- – --
50: – -- – -- UU UU UU UU – -- – -- – -- – --
60: – -- – -- 64 65 – -- – -- – -- – -- – --
70: – -- – -- – -- – --

`

Now I can write register with this script (can on/off onboard LED) but when I try to read all 25 register I get this

1, 1, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0

The first 2 bytes are the ID and FW, but I expect the rest to have values such as the pH (registers 0x16, 0x17, 0x18, 0x19) but I am getting only 0 (garbage)

Python script

`

import smbus
import time

class i2c_device:
def init(self, addr, port):
self.addr = addr
self.bus = smbus.SMBus(port)

def write(self, byte):
self.bus.write_byte(self.addr, byte)

def write_i2c_block_data(self, byte, array):
self.bus.write_i2c_block_data(self.addr, byte, array)

def read(self):
return self.bus.read_byte(self.addr)

def read_nbytes_data(self, data, n): # For sequential reads > 1 byte
return self.bus.read_i2c_block_data(self.addr, data, n)

ph = i2c_device(0x65, 2)
ph.write(0x00)
i=0
while (i <= 25):
print(ph.read())
time.sleep(0.5)
i+=1

`

This are the value in hexadecimal of the 25 registers in the sensor, check with datasheet and it’s ok

1,4,1,65,0,1,0,1,0,0,0,0,0,0,0,0,9,C4,0,0,9,C4,0,0,16

I used arduino to read this, I discovered that what I read with python is garbage

Sebastián:

Is your Arduino 3.3V or 5.0 V I/O?

What clock speed are you running the I2C bus in the Beaglebone?
With the time distortion in the level translator, I would not go above 100 kHz until proven good at higher speeds.

I note that your schematic shows VDDP connected to 5V.

This should be connected to the same reference Voltage as the I2C bus is using, which is 3.3V in the case of the Beaglebone.

I have not digested the ADM3260 data sheet sufficiently to understand if it is OK to run both buses at 3.3V, and the power supply input at 5V.
Is this what you are actually doing when on the Beaglebone?

— Graham

finally this work for me :slight_smile:

thanks for your time Graham

working python script

`

import smbus
import time

General i2c device class so that other devices can be added easily

class i2c_device:
def init(self, addr, port):
self.addr = addr
self.bus = smbus.SMBus(port)

def write_i2c_block_data(self, byte, array):
self.bus.write_i2c_block_data(self.addr, byte, array)

def read_nbytes_data(self, data, n): # For sequential reads > 1 byte
return self.bus.read_i2c_block_data(self.addr, data, n)

ph = i2c_device(0x65, 2)
print(ph.read_nbytes_data(0x00, 25)) //read all registers
ph.write_i2c_block_data(0x05,[0x00]) // off LED

`

Sounds like you can move ahead, and learn a little python.
— Graham