4

Raspberry Pi で python-smbus を使用して、I2C を使用して MMA7660 加速度計チップと通信しようとしています。

以下のコードでは、チップのレジスタ 0x00、0x01、0x02、および 0x03 を読み取っており、すべてに対してまったく同じ値を取得しています。値を見て、チップを傾けると、それらはすべて X 値レジスタであるレジスタ 0x00 に対応していることがわかります。

出力:

...
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
...

コード:

  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

smbus 構文で何か間違っていますか? ドキュメントhereを見ました。

チップが動作することを確認しました。Arduino を使用し、上記と同じ順序でレジスタを設定して、正常に通信できます。

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

Sylvain のコメントに従って、次のコードの SDA/SCL ラインのオシロスコープ出力を添付しています。

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

ここに画像の説明を入力

更新 #2:

ラズベリーパイのI2Cには既知の問題があると思います-「繰り返し開始」はありません。

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

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

しかし、試してみると、オシロスコープはリピートスタート (S) の前にストップ (P) を明確に示しています。

したがって、Pi で I2C ハードウェアを使用して MMA7760 と通信するのは運が悪いと思います。

4

4 に答える 4

1

これが問題なのかどうかは絶対にわかりませんが、仕様p22によると:

MMA7660FC は、内部に格納されたレジスタ アドレスをアドレス ポインタとして使用して読み取られます。格納されたレジスタ アドレスが書き込みのアドレス ポインタとして使用されるのと同じ方法です。ポインターは通常、各データ バイトが読み取られた後、書き込みと同じルールを使用して自動インクリメントします (表 5)。したがって、読み出しは、最初に書き込みを実行してデバイスのレジスタ アドレスを構成し(図 11)、その後に開始を繰り返すことによって開始されます。マスターは、初期化されたレジスタ アドレスによってアドレス指定されたレジスタから読み取られる最初のデータ バイトを使用して、マスターから「n」個の連続したバイトを読み取ることができます。

私が理解している限り、レジスタから「読み取る」には、レジスタアドレスを書き込むことから始めて、盲目的にバイトを読み取る必要があります。あなたのためにそれを処理するかどうかはわかりませんが、手動で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)

たぶんそれもうまくいくでしょう:

  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)
于 2013-06-26T10:36:49.903 に答える
0

あなたの例と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")

これでうまくいくはずです。

于 2015-11-14T22:22:17.750 に答える
0

Raspberry PI I2C カーネル ドライバーは、特定の時間の繰り返し開始をサポートしていませんでした。ただし、I2C カーネル ドライバーが更新され、繰り返し開始がサポートされるようになりましたが、この機能は明示的に有効にする必要があります。

複合転送を「オン」に設定するには

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

複合転送を「オフ」に設定するには

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

ここにある情報: http://raspberrypi.znix.com/hipidocs/topic_i2c_rs_and_cs.htm

于 2016-09-03T20:30:45.310 に答える