产品: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
答案 0 :(得分:1)
根据datasheet,LSM9DS0包含2个子模块:一个包含加速度计和指南针,另一个包含陀螺仪。每个子模块位于不同的地址,由SA0_XM
和SA0_G
引脚的状态决定。
在Adafruit module上,这些引脚被拉高,因此根据数据表中的表15和16:
0x1d
(00011101
)0x6b
(01101011
)基于此,您似乎正在访问正确的地址。它还意味着在脚本开头附近,您应该定义一些常量,例如
ACCEL_ADDRESS = 0x1d
GYRO_ADDRESS = 0x6b
并使用它们而不是在代码周围复制幻数。
现在注册地址。由于存在两个不同的设备,因此每个设备暴露不同的寄存器的可能性很大。实际上,表17显示了这种情况,尽管有些间接。重要的部分是标题为" Slave Address"的列,它指的是表15(加速度计指南针)或表16(陀螺仪)。 (寄存器的符号名称可能有助于您在某些情况下区分,因为它们通常具有后缀M
(前者)或G
(后者),但并非总是如此。
这就是你的问题所在。对于陀螺仪,测量值位于地址0x28..0x2d
的寄存器中然而你正在阅读0x08..0x0d
,这是在陀螺仪模块中保留的(由于阅读不会出现意外而得到一些固定的废话)。
您似乎已正确获得控制寄存器CTRL_REG1_G
和CTRL_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)。
由于此寄存器返回常量,因此它是验证您与正确设备通话以及通信是否正常工作的好方法。
还有一个:不要复制粘贴代码,而是使用函数。
例如,重构的第一步可能会产生类似的结果:
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寄存器和中断,这可能有点不同。有关详细信息,请参见各自的数据表。