Using Python smbus on a Raspberry Pi - confused with syntax

M-V picture M-V · Jun 26, 2013 · Viewed 62.2k times · Source

I am trying to use python-smbus on a Raspberry Pi to communicate with an MMA7660 accelerometer chip using I2C.

In the code below, I am reading registers 0x00, 0x01, 0x02 and 0x03 of the chip, and I am getting the exact same values for all. Looking at the values, and tilting the chip, I can see that they all correspond to register 0x00, the X value register.

Output:

...
1 1 1 2
3 3 3 3
1 1 1 1
59 60 60 60
51 51 51 51
58 58 58 58
3 3 3 3
62 62 62 62
58 58 58 58
62 62 62 62
...

Code:

  import smbus
  import time

  bus = smbus.SMBus(1)
  # I2C address for MMA7660                                                     
  addr = 0x4C
  try:
    bus.write_byte_data(addr, 0x07, 0x00)
    bus.write_byte_data(addr, 0x06, 0x10)
    bus.write_byte_data(addr, 0x08, 0x00)
    bus.write_byte_data(addr, 0x07, 0x01)
  except IOError, err:
    print err

  while True:
    try:
      x = bus.read_byte_data(addr,0x00)
      y = bus.read_byte_data(addr,0x01)
      z = bus.read_byte_data(addr,0x02)
      tr = bus.read_byte_data(addr,0x03)
      print x, y, z, tr
      time.sleep(0.25)
    except:
      print 'exiting...'
      break

Am I doing something wrong with the smbus syntax? I did look at the documentation here.

I have verified that the chip works - I can communicate fine with it using an Arduino and setting the registers in the same order as above.

Update #1 (28 Jun 2013):

As per Sylvain's comment, I am attaching oscilloscope output for SDA/SCL lines for the following code:

bus.write_byte(addr, 0x01)
print bus.read_byte(addr)

enter image description here

Update #2:

I guess there is a known problem with I2C on Raspberry Pi - there is no "Repeated Start".

https://raspberrypi.stackexchange.com/questions/7138/mma8452-i2c-module

According to the Linux SMBus spec:

SMBus Read Byte:  i2c_smbus_read_byte_data()
============================================

This reads a single byte from a device, from a designated register.
The register is specified through the Comm byte.

S Addr Wr [A] Comm [A] S Addr Rd [A] [Data] NA P

But when I tried it, the osciiloscope clearly shows a STOP (P) before the Repeated Start (S).

So I guess I am out of luck for using I2C hardware on the Pi to talk to the MMA7760.

Answer

ThomGob picture ThomGob · Sep 22, 2013

if you read all the needed registers at once, it works fine:

import smbus
bus = smbus.SMBus(1) 

Register = bus.read_i2c_block_data(0x4c, 0x99,4)
acc_x = Register[0]*1.0
acc_y = Register[1]*1.0
acc_z = Register[2]*1.0
acc_tilt     = Register[3]