树莓派IIC读取陀螺仪JY901数据

基本描述:9轴姿态角度传感器广泛用于物联网开发,其中JY901陀螺仪由于自带卡尔曼动态滤波算法便作为了我硬件开发的选择。JY901陀螺仪基本可以在各个平台上进行数据的读取(如arduino、stm32、树莓派、上位机等),但由于JY901的官方只提供了树莓派串口通信的读取方式,而未提供树莓派IIC通信的读取方式。为了实现树莓派上多个JY901陀螺仪的同时运作,本方案决定采用使用IIC通信方式,用Python3进行数据的读取。

第一步:硬件连接

树莓派IIC读取陀螺仪JY901数据_第1张图片

将JY901陀螺仪对应的VCC、SDA、SCL、GND与树莓派进行连接

第二步:

使用i2cdetect命令侦测是否成功接入I2C的设备:

sudo i2cdetect -y 1
    0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:          -- -- -- -- -- -- -- -- -- -- -- -- -- 
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
50: -- 51 -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
70: -- -- -- -- -- -- -- --                         

查看该地址下的设备寄存器信息

i2cdump -y 1 0x51
No size specified (using byte-data access)
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f    0123456789abcdef
00: 00 00 1e 06 02 00 00 00 f8 1b fe 00 00 00 00 00    ..???...???.....
10: 00 00 00 00 00 00 00 00 00 00 51 00 b0 b1 a6 04    ..........Q.????
20: 03 03 00 00 00 1e 01 ff 2c 00 00 00 e8 01 c0 00    ??...??.,...???.
30: 00 00 15 d4 70 a1 3b 00 00 00 e6 6d d1 f2 81 a3    ..??p?;...?m????
40: 89 16 45 22 48 00 00 00 00 00 00 00 00 00 00 00    ??E"H...........
50: 00 93 80 18 aa 00 00 00 00 00 00 00 00 00 00 00    .????...........
60: 00 00 00 00 00 00 00 00 00 00 03 00 00 00 00 00    ..........?.....
70: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00    ................
80: 00 00 1e 06 02 00 00 00 f8 1b fe 00 00 00 00 00    ..???...???.....
90: 00 00 00 00 00 00 00 00 00 00 51 00 b0 b1 a6 04    ..........Q.????
a0: 03 03 00 00 00 1e 01 ff 2c 00 00 00 e8 01 c0 00    ??...??.,...???.
b0: 00 00 15 4b 70 a3 39 00 00 00 e5 6d d3 f2 81 a3    ..?Kp?9...?m????
c0: 89 37 1d 5a 1c 00 00 00 00 00 00 00 00 00 00 00    ?7?Z?...........
d0: 00 93 80 18 aa 00 00 00 00 00 00 00 00 00 00 00    .????...........
e0: 00 00 00 00 00 00 00 00 00 00 03 00 00 00 00 00    ..........?.....
f0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00    ................

查看JY901使用说明书V4.0:

树莓派IIC读取陀螺仪JY901数据_第2张图片

我们可知加速度、角速度、角度所在的寄存器地址,接下来可以通过Python3进行编码读取了

第三步:

import smbus
import time


class Gyro(object):

    def __init__(self, addr):
        self.addr = addr
        self.i2c = smbus.SMBus(1)

    def get_acc(self):
        try:
            self.raw_acc_x = self.i2c.read_i2c_block_data(self.addr, 0x34, 2)
            self.raw_acc_y = self.i2c.read_i2c_block_data(self.addr, 0x35, 2)
            self.raw_acc_z = self.i2c.read_i2c_block_data(self.addr, 0x36, 2)
        except IOError:
            print("ReadError: gyro_acc")
            return (0, 0, 0)
        else:
            self.k_acc = 16 * 9.8

            self.acc_x = (self.raw_acc_x[1] << 8 | self.raw_acc_x[0]) / 32768 * self.k_acc
            self.acc_y = (self.raw_acc_y[1] << 8 | self.raw_acc_y[0]) / 32768 * self.k_acc
            self.acc_z = (self.raw_acc_z[1] << 8 | self.raw_acc_z[0]) / 32768 * self.k_acc

            if self.acc_x >= self.k_acc:
                self.acc_x -= 2 * self.k_acc 
        
            if self.acc_y >= self.k_acc:
               self.acc_y -= 2 * self.k_acc
                
            if self.acc_z >= self.k_acc:
                self.acc_z -= 2 * self.k_acc

            return (self.acc_x, self.acc_y, self.acc_z)

    def get_gyro(self):
        try:
            self.raw_gyro_x = self.i2c.read_i2c_block_data(self.addr, 0x37, 2)
            self.raw_gyro_y = self.i2c.read_i2c_block_data(self.addr, 0x38, 2)
            self.raw_gyro_z = self.i2c.read_i2c_block_data(self.addr, 0x39, 2)
        except IOError:
            print("ReadError: gyro_gyro")
            return (0, 0, 0)
        else:
            self.k_gyro = 2000

            self.gyro_x = (self.raw_gyro_x[1] << 8 | self.raw_gyro_x[0]) / 32768 * self.k_gyro
            self.gyro_y = (self.raw_gyro_y[1] << 8 | self.raw_gyro_y[0]) / 32768 * self.k_gyro
            self.gyro_z = (self.raw_gyro_z[1] << 8 | self.raw_gyro_z[0]) / 32768 * self.k_gyro

            if self.gyro_x >= self.k_gyro:
                self.gyro_x -= 2 * self.k_gyro
        
            if self.gyro_y >= self.k_gyro:
               self.gyro_y -= 2 * self.k_gyro
                
            if self.gyro_z >= self.k_gyro:
                self.gyro_z -= 2 * self.k_gyro

            return (self.gyro_x, self.gyro_y, self.gyro_z)
         

    def get_angle(self):
        try:
            self.raw_angle_x = self.i2c.read_i2c_block_data(self.addr, 0x3d, 2)
            self.raw_angle_y = self.i2c.read_i2c_block_data(self.addr, 0x3e, 2)
            self.raw_angle_z = self.i2c.read_i2c_block_data(self.addr, 0x3f, 2)
        except IOError:
            print("ReadError: gyro_angle")
            return (0, 0, 0)
        else:
            self.k_angle = 180

            self.angle_x = (self.raw_angle_x[1] << 8 | self.raw_angle_x[0]) / 32768 * self.k_angle
            self.angle_y = (self.raw_angle_y[1] << 8 | self.raw_angle_y[0]) / 32768 * self.k_angle
            self.angle_z = (self.raw_angle_z[1] << 8 | self.raw_angle_z[0]) / 32768 * self.k_angle

            if self.angle_x >= self.k_angle:
                self.angle_x -= 2 * self.k_angle
        
            if self.angle_y >= self.k_angle:
                self.angle_y -= 2 * self.k_angle
                
            if self.angle_z >= self.k_angle:
                self.angle_z -= 2 * self.k_angle

            return (self.angle_x, self.angle_y, self.angle_z)

def main():
    head_gyro = Gyro(0x51)
    while(True):
        print(" Acc:  " + repr(head_gyro.get_acc()) + "\n", "Gyro: " + repr(head_gyro.get_gyro()) + "\n", "Angle:" + repr(head_gyro.get_angle()) + "\n")
        time.sleep(0.2)

main()

然后运行:

树莓派IIC读取陀螺仪JY901数据_第3张图片

对于异常情况的处理:

树莓派IIC读取陀螺仪JY901数据_第4张图片

总结:树莓派通过IIC的通信方式对JY901陀螺仪进行数据读取可以解决一个树莓派读取多个JY901陀螺仪(或设备)的问题,由于JY901卖家未提供相关的代码加之网上很多资料都采用的串口读取方式,所以并有对此问题有很好的解决。由于初学Python代码可能冗余度还是蛮高的很多地方都还可以改进啦,大家懂这个读取方式就好啦,只是想分享而已,希望对刚接触的童鞋有些帮助!

你可能感兴趣的:(树莓派IIC读取陀螺仪JY901数据)