简体   繁体   English

在Raspberry Pi上使用Python smbus - 与语法混淆

[英]Using Python smbus on a Raspberry Pi - confused with syntax

I am trying to use python-smbus on a Raspberry Pi to communicate with an MMA7660 accelerometer chip using I2C. 我试图在Raspberry Pi上使用python-smbus与使用I2C的MMA7660加速计芯片进行通信。

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. 在下面的代码中,我正在读取芯片的寄存器0x00,0x01,0x02和0x03,并且我得到了完全相同的值。 Looking at the values, and tilting the chip, I can see that they all correspond to register 0x00, the X value register. 查看这些值并倾斜芯片,我可以看到它们都对应于寄存器0x00,即X值寄存器。

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? 我是否在使用smbus语法做错了什么? 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. 我已经验证了芯片的工作原理 - 我可以使用Arduino与它进行良好的通信,并按照与上面相同的顺序设置寄存器。

Update #1 (28 Jun 2013) : 更新#1(2013年6月28日)

As per Sylvain's comment, I am attaching oscilloscope output for SDA/SCL lines for the following code: 根据Sylvain的评论,我为以下代码附加了SDA / SCL线路的示波器输出:

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

在此输入图像描述

Update #2: 更新#2:

I guess there is a known problem with I2C on Raspberry Pi - there is no "Repeated Start". 我猜在Raspberry Pi上有一个已知的I2C问题 - 没有“重复启动”。

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

According to the Linux SMBus spec: 根据Linux SMBus规范:

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). 但是当我尝试它时,示波器在重复启动(S)之前清楚地显示STOP(P)。

So I guess I am out of luck for using I2C hardware on the Pi to talk to the MMA7760. 所以我想我在Pi上使用I2C硬件与MMA7760对话是不合时宜的。

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] 

I'm absolutly not sure this is the problem, but according to the specs p22: 绝对不确定这是不是问题,但根据规范p22:

MMA7660FC is read using it's internally stored register address as address pointer, the same way the stored register address is used as address pointer for a write. 使用内部存储的寄存器地址作为地址指针读取MMA7660FC,与存储的寄存器地址用作写入的地址指针的方式相同。 The pointer generally auto-increments after each data byte is read using the same rules as for a write (Table 5). 在使用与写入相同的规则读取每个数据字节后,指针通常会自动递增(表5)。 Thus, a read is initiated by first configuring the device's register address by performing a write (Figure 11) followed by a repeated start. 因此, 首先通过执行写操作 (图11)然后重复启动来配置器件的寄存器地址来启动读操作 The master can now read 'n' consecutive bytes from it, with the first data byte being read from the register addressed by the initialized register address. 主设备现在可以从中读取'n'个连续字节,第一个数据字节从初始化寄存器地址寻址的寄存器中读取。

As far as I understand, to "read" from a register, you have to start by writing the register address, and then blindly read a byte. 据我所知,要从寄存器“读取”,你必须先写入寄存器地址,然后盲目读取一个字节。 I don't know if SMBus.read_byte_data take care of that for you, but you could try it manually : 我不知道SMBus.read_byte_data是否为您处理,但您可以手动尝试:

  bus.write_byte(addr,0x00)
  x = bus.read_byte(addr)

  bus.write_byte(addr,0x01)
  y = bus.read_byte_data(addr)

  bus.write_byte(addr,0x02)
  z = bus.read_byte(addr)

  bus.write_byte(addr,0x03)
  tr = bus.read_byte(addr)

Maybe that would even work: 也许这甚至会起作用:

  bus.write_byte(addr,0x00)

  x = bus.read_byte(addr)
  y = bus.read_byte_data(addr)
  z = bus.read_byte(addr)
  tr = bus.read_byte(addr)

After viewing your example, as well as class written for the MMA7455, I was able to write the following: 在查看了您的示例以及为MMA7455编写的类之后,我能够编写以下内容:

import smbus
import time
import os
import math

# Define a class for the accelerometer readings
class MMA7660():
    bus = smbus.SMBus(1)
    def __init__(self):
        self.bus.write_byte_data(0x4c, 0x07, 0x00) # Setup the Mode
        self.bus.write_byte_data(0x4c, 0x06, 0x10) # Calibrate
        self.bus.write_byte_data(0x4c, 0x08, 0x00) # Calibrate
        self.bus.write_byte_data(0x4c, 0x07, 0x01) # Calibrate
    def getValueX(self):
        return self.bus.read_byte_data(0x4c, 0x00)
    def getValueY(self):
        return self.bus.read_byte_data(0x4c, 0x01)
    def getValueZ(self):
        return self.bus.read_byte_data(0x4c, 0x02)

mma = MMA7660()

for a in range(1000):
    x = mma.getValueX()
    y = mma.getValueY()
    z = mma.getValueZ()
    print("X=", x)
   print("Y=", y)
   print("Z=", z)
    time.sleep(0.2)
    os.system("clear")

That should do the trick. 这应该够了吧。

The Raspberry PI I2C Kernel Driver did not support repeated starts for a specific time. Raspberry PI I2C内核驱动程序不支持在特定时间重复启动。 However, the I2C Kernel Driver has been updated and now supports the repeated start, though this functionality must be activated explicitly. 但是,I2C内核驱动程序已更新,现在支持重复启动,但必须明确激活此功能。

To set combined transfers 'on' 设置组合转移'开启'

sudo sh -c '/bin/echo Y > /sys/module/i2c_bcm2708/parameters/combined'

To set combined transfers 'off' 设置组合转移'关闭'

sudo sh -c '/bin/echo N > /sys/module/i2c_bcm2708/parameters/combined'

Information found here: http://raspberrypi.znix.com/hipidocs/topic_i2c_rs_and_cs.htm 在此处可找到的信息: http//raspberrypi.znix.com/hipidocs/topic_i2c_rs_and_cs.htm

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM