使用I2c总线读取陀螺仪值

时间:2017-09-24 11:55:21

标签: python beagleboneblack i2c gyroscope

产品: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

2 个答案:

答案 0 :(得分:1)

根据datasheet,LSM9DS0包含2个子模块:一个包含加速度计和指南针,另一个包含陀螺仪。每个子模块位于不同的地址,由SA0_XMSA0_G引脚的状态决定。

Tables 15 and 16 from the datasheet

Adafruit module上,这些引脚被拉高,因此根据数据表中的表15和16:

  • 加速度计和指南针位于地址0x1d00011101
  • 陀螺仪位于地址0x6b01101011

基于此,您似乎正在访问正确的地址。它还意味着在脚本开头附近,您应该定义一些常量,例如

ACCEL_ADDRESS = 0x1d
GYRO_ADDRESS = 0x6b

并使用它们而不是在代码周围复制幻数。

现在注册地址。由于存在两个不同的设备,因此每个设备暴露不同的寄存器的可能性很大。实际上,表17显示了这种情况,尽管有些间接。重要的部分是标题为" Slave Address"的列,它指的是表15(加速度计指南针)或表16(陀螺仪)。 (寄存器的符号名称可能有助于您在某些情况下区分,因为它们通常具有后缀M(前者)或G(后者),但并非总是如此。

Table 17

这就是你的问题所在。对于陀螺仪,测量值位于地址0x28..0x2d

的寄存器中

Gyroscope registers

然而你正在阅读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(0x0F)。

Device identification register

由于此寄存器返回常量,因此它是验证您与正确设备通话以及通信是否正常工作的好方法。

还有一个:不要复制粘贴代码,而是使用函数。

例如,重构的第一步可能会产生类似的结果:

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)

答案 1 :(得分:0)

有许多i2c出版物,您可以在其中找到它的工作原理。此外,大多数陀螺仪和mems设备基本上也在其数据表中对其进行了解释。但基本上它是两条线,具有逻辑高和逻辑低状态。消息通常以8位段发送。为了发送段,时钟线变低,然后数据转换到要发送的电平。数据线必须稳定,然后时钟变高。时钟变为高电平时的数据电平为位0(数据低电平)或1(数据高电平)。首先发送器件8位地址(实际上是7位地址,最后一位是信号读或写)。通常写你发送先读然后中断然后写。读取时,在发送器件地址后,接下来的8位或16位是寄存器地址。然后设备将发送信息。写作是类似的。一些mems器件具有fifo寄存器和中断,这可能有点不同。有关详细信息,请参见各自的数据表。