簡體   English   中英

使用I2c總線讀取陀螺儀值

[英]Read a gyroscope value with the I2c bus

產品: https : //www.adafruit.com/product/2020

數據表: https : //cdn-shop.adafruit.com/datasheets/LSM9DS0.pdf

我是學生,這是我第一次使用I2c總線。 我正在嘗試閱讀陀螺儀的基本值。 我浪費了一部分時間來了解I2c的工作原理。 但是在閱讀數據表並制作了自己的腳本之后。 我的價值觀固守在那里。 一無所獲,我也不知道為什么。

Rotation in X-Axis : -1087
Rotation in Y-Axis : -28797
Rotation in Z-Axis : -15032

這是我的劇本。 有人可以幫助我解決嗎? 我正在使用比格犬骨黑。

import smbus
import time


bus = smbus.SMBus(1)

# 0x6b adress (found with i2cdetect), 0x20 register (found with the data sheet), CTRL_REG1_G(20h)
bus.write_byte_data(0x6b, 0x20, 0x0F)

bus.write_byte_data(0x6b, 0x23, 0x30)

time.sleep(0.5)


data0 = bus.read_byte_data(0x6b, 0x08)
data1 = bus.read_byte_data(0x6b, 0x09)


xGyro = data1 * 256 + data0
if xGyro > 32767 :
    xGyro -= 65536

data0 = bus.read_byte_data(0x6b, 0x0A)
data1 = bus.read_byte_data(0x6b, 0x0B)


yGyro = data1 * 256 + data0
if yGyro > 32767 :
    yGyro -= 65536


data0 = bus.read_byte_data(0x6b, 0x0C)
data1 = bus.read_byte_data(0x6b, 0x0D)

zGyro = data1 * 256 + data0
if zGyro > 32767 :
    zGyro -= 65536


print "Rotation in X-Axis : %d" %xGyro
print "Rotation in Y-Axis : %d" %yGyro
print "Rotation in Z-Axis : %d" %zGyro

根據數據表 ,LSM9DS0包含2個子模塊:一個包含加速度計和指南針,另一個包含陀螺儀。 每個子模塊位於不同的地址,該地址由SA0_XMSA0_G引腳的狀態確定。

數據表中的表15和表16

Adafruit模塊上,這些引腳被拉高,因此根據數據表中的表15和表16:

  • 加速度計和指南針位於地址0x1d00011101
  • 陀螺儀位於地址0x6b01101011

基於此,您似乎正在訪問正確的地址。 這也意味着在腳本開始附近,您應該定義一些常量,例如

ACCEL_ADDRESS = 0x1d
GYRO_ADDRESS = 0x6b

並使用這些代碼,而不是在代碼周圍復制幻數。


現在,寄存器地址。 由於存在兩種不同的設備,因此每個設備都有很大的機會公開不同的寄存器集。 實際上,表17確實是這種情況,盡管有些間接。 重要的部分是標題為“從站地址”的列,它引用表15(加速度計和指南針)或表16(陀螺儀)。 (寄存器的符號名在某些情況下可能會幫助您分辨出它們的區別,因為它們通常帶有后綴M (前者)或G (后綴),但並非總是如此)。

表17

這就是您的問題。 對於陀螺儀,測量值位於地址0x28..0x2d的寄存器中

陀螺儀寄存器

但是您正在從陀螺儀模塊中保留的0x08..0x0d進行讀取(由於讀取的結果會產生一些固定的廢話,這並不是意外的)。

您似乎已經正確獲得了控制寄存器CTRL_REG1_GCTRL_REG4_G

當然,就像地址一樣,您應該為要使用的所有寄存器定義常量:

CTRL_REG1_G = 0x20
CTRL_REG4_G = 0x23
OUT_X_L_G = 0x28
OUT_X_H_G = 0x29

等等...


WHO_AM_I_G ,在實際讀取測量值之前,我要做的第一件事就是讀取設備標識寄存器,在這種情況下為WHO_AM_I_G (0x0F)。

設備標識寄存器

由於此寄存器返回一個常數,因此是驗證您正在與正確的設備進行通訊以及通信正常的一種好方法。


還有一點:不要在周圍復制粘貼代碼,而要使用函數。

例如,重構的第一步可能會產生如下結果:

def read_int16(bus, device, register):
    lsb = bus.read_byte_data(device, register)
    msb = bus.read_byte_data(device, register + 1)

    result = msb * 256 + lsb
    return (result - 65536) if (result > 32767) else result


xGyro = read_int16(bus, GYRO_ADDRESS, OUT_X_L_G)
yGyro = read_int16(bus, GYRO_ADDRESS, OUT_Y_L_G)
zGyro = read_int16(bus, GYRO_ADDRESS, OUT_Z_L_G)

您可以在許多i2c出版物中找到其工作方式。 大多數陀螺儀和記憶設備也基本上在其數據表中對此進行了說明。 但基本上是具有邏輯高和邏輯低狀態的兩條線。 消息通常以8位段發送。 為了發送一個段,時鍾線變為低電平,然后將數據轉換為要發送的電平。 數據線必須穩定,然后時鍾變高。 時鍾變高時的數據電平是位0(數據低)或1(數據高)。 器件首先發送8位地址(實際上是7位地址,最后一位是發出讀或寫信號)。 通常寫操作是先發送讀取,然后中斷然后寫入。 讀取時,發送設備地址后,接下來的8位或16位為寄存器地址。 然后設備將發送信息。 寫作是相似的。 某些內存設備具有fifo寄存器和中斷,可能有所不同。 有關詳細信息,請參見各自的數據表。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM