树莓派-JY901陀螺仪的使用
参考: https://blog.csdn.net/APP852045932/article/details/87995972
注意: IIC地址根据硬件可能不同. 如我的是0X50
JY901
类的代码:
import smbus
import time
class JY901:
def __init__(self, iic_ins, iic_addr=0x50) -> None:
self.iic_addr = iic_addr
self.iic_ins = iic_ins
self.angle_zero_x = 0
self.angle_zero_y = 0
self.angle_zero_z = 0
def read(self) -> dict:
return {"ANGLE": self._read_angle(), "ACC": self._read_acc(), "GYRO": self._read_gyro()}
def reset_angle(self) -> None:
self.angle_zero_x, self.angle_zero_y, self.angle_zero_z = self._read_angle()
def _read_acc(self) -> tuple:
return self._read_value(0x34, 16*9.8), self._read_value(0x35, 16*9.8), self._read_value(0x36, 16*9.8)
def _read_gyro(self) -> tuple:
return self._read_value(0x37, 2000), self._read_value(0x38, 2000), self._read_value(0x39, 2000)
def _read_angle(self) -> tuple:
return self._read_value(0x3d, 180) - self.angle_zero_x, self._read_value(0x3e, 180) - self.angle_zero_y, self._read_value(0x3f, 180) - self.angle_zero_z
def _read_value(self, cmd: int, constant: float) -> float:
value = self.iic_ins.read_i2c_block_data(self.iic_addr, cmd, 2)
value = (value[1] << 8 | value[0]) / 32768 * constant
if value >= constant:
value -= 2 * constant
return value
if __name__ == "__main__":
jy901 = JY901(smbus.SMBus(1))
jy901.reset_angle()
while True:
print(jy901.read()["ANGLE"])
time.sleep(0.1)
对于_read_value
方法的解释:
value = self.iic_ins.read_i2c_block_data(self.iic_addr, cmd, 2)
: 向iic_addr
(此处即0X50)写入控制字cmd
(看数据手册),然后读取2个字节.
这个方法返回数组, 一个元素为一个字节, 格式为十进制无符号整数.
value = (value[1] << 8 | value[0]) / 32768 * constant
将读到的两个字节:
- 读出的两个数表示一个16bit数的前8bit和后8bit. 通过移位运算+或运算把它合成为一个整数.
/ 32768
: 32768 = 2 15 32768 = 2^{15} 32768=215. 对于有符号16bit整数, 范围为 [ − 32768 , 32767 ] [-32768, 32767] [−32768,32767]. 将其范围缩放为 [ − 1 , 1 ] [-1, 1] [−1,1]. 注: 溢出为负可在之后处理.* constant
: 更具数据手册, 找出最大值表示的物理量用标准单位代表的值.
if value >= constant:
value -= 2 * constant
: 溢出为负的处理