简体   繁体   English

使用I2c总线读取陀螺仪值

[英]Read a gyroscope value with the I2c bus

Product : https://www.adafruit.com/product/2020 产品: https : //www.adafruit.com/product/2020

datasheet: https://cdn-shop.adafruit.com/datasheets/LSM9DS0.pdf 数据表: https : //cdn-shop.adafruit.com/datasheets/LSM9DS0.pdf

I'm student and it's the first time for me to use I2c bus. 我是学生,这是我第一次使用I2c总线。 I am trying to read the basic gyroscope value. 我正在尝试阅读陀螺仪的基本值。 I wasted a part of my life to understand how the I2c work. 我浪费了一部分时间来了解I2c的工作原理。 But after reading the datasheet and made my own script. 但是在阅读数据表并制作了自己的脚本之后。 My values are stuck there. 我的价值观固守在那里。 Nothing move and I don't know why. 一无所获,我也不知道为什么。

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

Here is my script. 这是我的剧本。 Someone can help me to solve it? 有人可以帮助我解决吗? I'm working with a beagle bone black. 我正在使用比格犬骨黑。

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

According to the datasheet , the LSM9DS0 contains 2 submodules: one containing accelerometer and compass, the other containing the gyroscope. 根据数据表 ,LSM9DS0包含2个子模块:一个包含加速度计和指南针,另一个包含陀螺仪。 Each of the submodules is located at a different address, determined by the state of SA0_XM and SA0_G pins. 每个子模块位于不同的地址,该地址由SA0_XMSA0_G引脚的状态确定。

数据表中的表15和表16

On the Adafruit module those pins are pulled high, so according to tables 15 and 16 in the datasheet: Adafruit模块上,这些引脚被拉高,因此根据数据表中的表15和表16:

  • accelerometer and compass are at address 0x1d ( 00011101 ) 加速度计和指南针位于地址0x1d00011101
  • gyroscope is at address 0x6b ( 01101011 ) 陀螺仪位于地址0x6b01101011

Based on this, it appears you're accessing the correct address. 基于此,您似乎正在访问正确的地址。 It also means that near the beginning of your script, you should define a few constants, such as 这也意味着在脚本开始附近,您应该定义一些常量,例如

ACCEL_ADDRESS = 0x1d
GYRO_ADDRESS = 0x6b

and use those instead of copying the magic number all around your code. 并使用这些代码,而不是在代码周围复制幻数。


Now the register addresses. 现在,寄存器地址。 Since there are two different devices, there's a good chance that each exposes a different set of registers. 由于存在两种不同的设备,因此每个设备都有很大的机会公开不同的寄存器集。 Indeed, table 17 shows this to be the case, albeit somewhat indirectly. 实际上,表17确实是这种情况,尽管有些间接。 The important part is the column titled "Slave Address", which refers either to table 15 (accelerometer an compass) or table 16 (gyro). 重要的部分是标题为“从站地址”的列,它引用表15(加速度计和指南针)或表16(陀螺仪)。 (The symbolic names of the registers might help you tell the difference in some cases, since they often have suffix M (former) or G (latter), but not always). (寄存器的符号名在某些情况下可能会帮助您分辨出它们的区别,因为它们通常带有后缀M (前者)或G (后缀),但并非总是如此)。

表17

And herein lies your problem. 这就是您的问题。 For a gyroscope, the measurements are in registers at addresses 0x28..0x2d 对于陀螺仪,测量值位于地址0x28..0x2d的寄存器中

陀螺仪寄存器

yet you are reading from 0x08..0x0d , which are reserved in the gyroscope module (getting some fixed nonsense as a result of reading that would not be unexpected). 但是您正在从陀螺仪模块中保留的0x08..0x0d进行读取(由于读取的结果会产生一些固定的废话,这并不是意外的)。

You seem to have gotten the control registers CTRL_REG1_G and CTRL_REG4_G correctly. 您似乎已经正确获得了控制寄存器CTRL_REG1_GCTRL_REG4_G

Of course, just as with the addresses, you should have constants defined for all the registers you want to use: 当然,就像地址一样,您应该为要使用的所有寄存器定义常量:

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

and so on... 等等...


As an aside, the first thing I would try, before actually reading the measured values, would be reading the device identification register, in this case WHO_AM_I_G (0x0F). WHO_AM_I_G ,在实际读取测量值之前,我要做的第一件事就是读取设备标识寄存器,在这种情况下为WHO_AM_I_G (0x0F)。

设备标识寄存器

Since this register returns a constant, it's a good way to validate you're talking with the right device, and that the communication works correctly. 由于此寄存器返回一个常数,因此是验证您正在与正确的设备进行通讯以及通信正常的一种好方法。


One more: don't copy-paste code around, use functions instead. 还有一点:不要在周围复制粘贴代码,而要使用函数。

For example the first step of refactoring could yield something like: 例如,重构的第一步可能会产生如下结果:

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)

There are many i2c publications where you can find out how it works. 您可以在许多i2c出版物中找到其工作方式。 Also most gyro and mems devices basically explain it in their data sheets also. 大多数陀螺仪和记忆设备也基本上在其数据表中对此进行了说明。 But basically it is two wires which have logic high and logic low states. 但基本上是具有逻辑高和逻辑低状态的两条线。 The messages are usually sent in 8 bit segments. 消息通常以8位段发送。 To send a segment the clock wire goes low then the data is transitioned to the level which is to be sent. 为了发送一个段,时钟线变为低电平,然后将数据转换为要发送的电平。 The data wire must be stable and then clock goes high. 数据线必须稳定,然后时钟变高。 The data level when clock goes high is the bit 0 (data low) or 1 (data high). 时钟变高时的数据电平是位0(数据低)或1(数据高)。 The devices 8 bit address is sent first (really 7 bit address, the last bit is to signal read or write). 器件首先发送8位地址(实际上是7位地址,最后一位是发出读或写信号)。 Usually to write you send read first then interrupt followed by write. 通常写操作是先发送读取,然后中断然后写入。 When reading, after device address is sent, the next 8 or 16 bits are register address. 读取时,发送设备地址后,接下来的8位或16位为寄存器地址。 Then the device will send information. 然后设备将发送信息。 Writing is similar. 写作是相似的。 Some mems device have fifo register and interrupts which can be a little different. 某些内存设备具有fifo寄存器和中断,可能有所不同。 See your respective data sheets for details. 有关详细信息,请参见各自的数据表。

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

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