第二十二章 六轴传感器——原始数据读取实验

本章将介绍板载六轴传感器的使用,结合前面章节介绍的machine.I2C类就能很方便地使用板载的六轴传感器。通过本章的学习,读者将学习到板载六轴传感器的基本使用。 本章分为如下几个小节: 22.1 SH3001驱动介绍及使用方法 22.2 硬件设计 22.3 程序设计 22.4 运行验证

22.1 SH3001驱动介绍及使用方法 SH3001是正点原子DNK210板载的六轴传感器芯片,是一款六轴IMU(Internal measurement unit,惯性从测量单元)。SH3001内部集成有三轴加速度计和三轴陀螺仪(角速度计),相较于多组件方案,免除了组合加速度计和陀螺仪时可能遇到的轴间差问题,并减小了体积和功耗。 SH3001内部集成有三轴加速度计和三轴陀螺仪,输出都是16位的数字量,可通过I2C接口与之进行数据交互。加速度计的测量范围最大可配置为±16g(g为重力加速度),静态测量精度高。陀螺仪的角速度测量范围最大可配置为±2000(dps),具有良好的动态相应特性。 SH3001的特点如下:

  1. 加速度计量程(g):±2、±4、±8、±16
  2. 加速度计灵敏度(LSB/g):16384、8192、4096、2048
  3. 陀螺仪量程(dps):±125、±250、±500、±1000、±2000
  4. 陀螺仪灵敏度(LSB、dps):262、131、65.5、32.8、16.4
  5. 封装:LGA14,2.53.00.9mm3 SH3001传感器的检测轴,如下图所示:

图22.1.1 SH3001检测轴方向 更多有关SH3001的芯片特性以及内部寄存器描述,请参考SH3001的数据手册——《SH3001.pdf》,读者可在A盘硬件资料芯片资料下找到这份文档。 为了方便读者使用正点原子DNK210开发板板载的这个SH3001六轴传感器芯片,正点原子团队为SH3001在正点原子DNK210开发板上的使用环境编写了sh3001.py这一SH3001驱动文件,sh3001.py可以在CanMV环境下使用。 sh3001.py驱动提供了SH3001的构造函数,用于创建一个SH3001对象,SH3001构造函数如下所示: class SH3001(i2c=None, attitude=False) 通过SH3001构造函数可以通过指定参数创建并初始化一个SH3001对象。 i2c指的是I2C对象,这个I2C对象需要先使用I2C的构造函数进行创建,有关I2C对象的介绍请看第二十章《machine.I2C类实验》。 attitude指的是是否在构造SH3001对象时初始化驱动自带的姿态解算功能,当attitude为True时,则在构造SH3001对象时初始化驱动自带的姿态解算功能,当attitude为False时,则在构造SH3001对象时不初始化驱动自带的姿态解算功能。 SH3001构造函数的使用示例如下所示:

from board import board_info
from fpioa_manager import fm
from machine import I2C
from sh3001 import SH3001

fm.register(board_info.IMU_SCL, fm.fpioa.I2C0_SCLK)
fm.register(board_info.IMU_SDA, fm.fpioa.I2C0_SDA)

i2c = I2C(I2C.I2C0, scl=board_info.IMU_SCL, sda=board_info.IMU_SDA)

sh3001 = SH3001(i2c)

从上面的示例中可以看到,从sh3001.py文件中导入了SH3001这个类,那么如何在应用脚本文件中导入另一个驱动文件中的类呢?在CanMV下非常简单,仅需使用CanMV IDE软件将需要被导入的驱动文件保存到CanMV任意文件系统的根目录下即可,具体的操作如下图所示:

【正点原子K210连载】 第二十二章 六轴传感器——原始数据读取实验摘自【正点原子】DNK210使用指南-CanMV版指南_陀螺仪

图22.1.2 保存文件到CanMV文件系统 SH3001类为SH3001对象提供了acc_config()方法,用于配置SH3001对象的加速度计,acc_config()方法如下所示: SH3001.acc_config(odr, range, freq, filter) acc_config()方法用于配置SH3001对象的加速度计。 odr指的是SH3001对象加速度计的数据输出速率,可配置的参数以常量的形式保存在SH3001类中,可配置的值如下表所示: 常量 加速度计数据输出速率

SH3001.ACC_ODR_8000HZ	8000Hz
SH3001.ACC_ODR_4000HZ	4000Hz
SH3001.ACC_ODR_2000HZ	2000Hz
SH3001.ACC_ODR_1000HZ	1000Hz
SH3001.ACC_ODR_500HZ	500Hz
SH3001.ACC_ODR_250HZ	250Hz
SH3001.ACC_ODR_125HZ	125Hz
SH3001.ACC_ODR_63HZ	63Hz
SH3001.ACC_ODR_31HZ	31Hz
SH3001.ACC_ODR_16HZ	16Hz

表22.1.1 acc_config()中odr参数配置值描述 range指的是SH3001对象加速度计的量程,可配置的参数以常量的形式保存在SH3001类中,可配置的值如下表所示: 常量 加速度计量程 SH3001.ACC_RANGE_16G ±16g SH3001.ACC_RANGE_8G ±8g SH3001.ACC_RANGE_4G ±4g SH3001.ACC_RANGE_2G ±2g 表22.1.2 acc_config()中range参数配置值描述 freq指的是SH3001对象加速度计低通滤波器的截至频率,可配置的参数以常量的形式保存在SH3001类中,可配置的参数如下表所示: 常量 低通滤波器截止频率 SH3001.ACC_FREQ_ODRX040 ODR * 0.40 SH3001.ACC_FREQ_ODRX025 ODR * 0.25 SH3001.ACC_FREQ_ODRX011 ODR * 0.11 SH3001.ACC_FREQ_ODRX004 ODR * 0.04 SH3001.ACC_FREQ_ODRX002 ODR * 0.02 表22.1.3 acc_config()中freq参数配置值描述 filter指的是是否使能SH3001对象加速度计的低通滤波器,可配置的参数以常量的形式保存在SH3001类中,可配置的参数如下表所示: 常量 低通滤波器使能状态 SH3001.ACC_FILTER_DISABLE 禁止 SH3001.ACC_FILTER_ENABLE 使能 表22.1.4 acc_config()中filter参数配置值描述 acc_config()方法的使用示例如下所示:

from board import board_info
from fpioa_manager import fm
from machine import I2C
from sh3001 import SH3001

fm.register(board_info.IMU_SCL, fm.fpioa.I2C0_SCLK)
fm.register(board_info.IMU_SDA, fm.fpioa.I2C0_SDA)

i2c = I2C(I2C.I2C0, scl=board_info.IMU_SCL, sda=board_info.IMU_SDA)

sh3001 = SH3001(i2c)
sh3001.acc_config(SH3001.ACC_ODR_500HZ, SH3001.ACC_RANGE_16G, SH3001.ACC_FREQ_ODRX025, SH3001.ACC_FILTER_ENABLE)

SH3001类为SH3001对象提供了get_acc()方法,用于获取SH3001对象的三轴加速度值,get_acc()方法如下所示: SH3001.get_acc() get_acc()方法用于获取SH3001对象的三轴加速度值,获取到的值为板载SH3001芯片输出的数字量,需要结合acc_config()方法配置的加速度计量程才能加算出实际的加速度值。 get_acc()方法的使用示例如下所示:

from board import board_info
from fpioa_manager import fm
from machine import I2C
from sh3001 import SH3001

fm.register(board_info.IMU_SCL, fm.fpioa.I2C0_SCLK)
fm.register(board_info.IMU_SDA, fm.fpioa.I2C0_SDA)

i2c = I2C(I2C.I2C0, scl=board_info.IMU_SCL, sda=board_info.IMU_SDA)

sh3001 = SH3001(i2c)
sh3001.acc_config(SH3001.ACC_ODR_500HZ, SH3001.ACC_RANGE_16G, SH3001.ACC_FREQ_ODRX025, SH3001.ACC_FILTER_ENABLE)
ax, ay, az = sh3001.get_acc()

SH3001类为SH3001对象提供了gyro_config()方法,用于配置SH3001对象的陀螺仪,gyro_config()方法如下所示: SH3001.gyro_config(odr, rangex, rangey, rangez, freq, filter) gyro_config()方法用于配置SH3001对象的陀螺仪。 odr指的是SH3001对象陀螺仪的数据输出速率,可配置的参数以常量的形式保存在SH3001类中,可配置的值如下表所示: 常量 陀螺仪数据输出速率 SH3001.GYRO_ODR_32000HZ 32000Hz SH3001.GYRO_ODR_16000HZ 16000Hz SH3001.GYRO_ODR_8000HZ 8000Hz SH3001.GYRO_ODR_4000HZ 4000Hz SH3001.GYRO_ODR_2000HZ 2000Hz SH3001.GYRO_ODR_1000HZ 1000Hz SH3001.GYRO_ODR_500HZ 500Hz SH3001.GYRO_ODR_250HZ 250Hz SH3001.GYRO_ODR_125HZ 125Hz SH3001.GYRO_ODR_63HZ 63Hz SH3001.GYRO_ODR_31HZ 31Hz 表22.1.5 gyro_config()中odr参数配置值描述 rangex、rangey、rangez指的是SH3001对象陀螺仪X、Y、Z轴的量程,可配置的参数以常量的形式保存在SH3001类中,可配置的值如下表所示: 常量 陀螺仪量程 SH3001.GYRO_RANGE_125DPS 125dps SH3001.GYRO_RANGE_250DPS 250dps SH3001.GYRO_RANGE_500DPS 500dps SH3001.GYRO_RANGE_1000DPS 1000dps SH3001.GYRO_RANGE_2000DPS 2000dps 表22.1.6 gyro_config()中rangex、rangey、rangez参数配置值描述 freq指的是SH3001对象陀螺仪低通滤波器的截至频率,可配置的参数以常量的形式保存在SH3001类中,可配置的参数如下表所示: 常量 低通滤波器截止频率 SH3001.GYRO_FREQ_00 请见SH3001芯片数据手册中的Table 14(Gyroscope digital LPF cut-off frequency configuration) SH3001.GYRO_FREQ_01 SH3001.GYRO_FREQ_02 SH3001.GYRO_FREQ_03 表22.1.7 gyro_config()中freq参数配置值描述 filter指的是是否使能SH3001对象陀螺仪的低通滤波器,可配置的参数以常量的形式保存在SH3001类中,可配置的参数如下表所示: 常量 低通滤波器使能状态 SH3001.GYRO_FILTER_DISABLE 禁止 SH3001.GYRO_FILTER_ENABLE 使能 表22.1.8 gyro_config()中filter参数配置值描述 gyro_config()方法的使用示例如下所示: from board import board_info from fpioa_manager import fm from machine import I2C from sh3001 import SH3001

fm.register(board_info.IMU_SCL, fm.fpioa.I2C0_SCLK) fm.register(board_info.IMU_SDA, fm.fpioa.I2C0_SDA)

i2c = I2C(I2C.I2C0, scl=board_info.IMU_SCL, sda=board_info.IMU_SDA)

sh3001 = SH3001(i2c) sh3001.gyro_config(SH3001.GYOR_ODR_500HZ, SH3001.GYRO_RANGE_2000DPS, SH3001.GYRO_RANGE_2000DPS, SH3001.GYRO_RANGE_2000DPS, SH3001.GYRO_FREQ_00, SH3001.GYRO_FILTER_ENABLE) SH3001类为SH3001对象提供了get_gyro()方法,用于获取SH3001对象的三轴陀螺仪值,get_gyro()方法如下所示: SH3001.get_gyto() get_gyto()方法用于获取SH3001对象的三轴陀螺仪值,获取到的值为板载SH3001芯片输出的数字量,需要结合gyro_config()方法配置的陀螺仪量程才能加算出实际的陀螺仪值。 get_gyro()方法的使用示例如下所示:

from board import board_info
from fpioa_manager import fm
from machine import I2C
from sh3001 import SH3001

fm.register(board_info.IMU_SCL, fm.fpioa.I2C0_SCLK)
fm.register(board_info.IMU_SDA, fm.fpioa.I2C0_SDA)

i2c = I2C(I2C.I2C0, scl=board_info.IMU_SCL, sda=board_info.IMU_SDA)

sh3001 = SH3001(i2c)
sh3001.gyro_config(SH3001.GYOR_ODR_500HZ, SH3001.GYRO_RANGE_2000DPS, SH3001.GYRO_RANGE_2000DPS, SH3001.GYRO_RANGE_2000DPS, SH3001.GYRO_FREQ_00, SH3001.GYRO_FILTER_ENABLE)
gx, gy, gz = sh3001.get_gyro()

SH3001类为SH3001对象提供了temp_config()方法,用于配置SH3001对象的温度计,temp_config()方法如下所示: SH3001.temp_config(odr, enable) temp_config()方法用于配置SH3001对象的温度计。 odr指的是SH3001对象温度计的数据输出速率,可配置的参数以常量的形式保存在SH3001类中,可配置的值如下表所示: 常量 温度计数据输出速率 SH3001.TEMP_ODR_500HZ 500Hz SH3001.TEMP_ODR_250HZ 250Hz SH3001.TEMP_ODR_125HZ 125Hz SH3001.TEMP_ODR_63HZ 63Hz 表22.1.9 temp_config()中odr参数配置值描述 enable指的是是否使能SH3001对象的温度计,可配置的参数以常量的形式保存在SH3001类中,可配置的参数如下表所示: 常量 温度计使能状态 SH3001.TEMP_DISABLE 禁止 SH3001.TEMP_ENABLE 使能 表22.1.10 temp_config()中enable参数配置值描述 temp_config()方法的使用示例如下所示:

from board import board_info
from fpioa_manager import fm
from machine import I2C
from sh3001 import SH3001

fm.register(board_info.IMU_SCL, fm.fpioa.I2C0_SCLK)
fm.register(board_info.IMU_SDA, fm.fpioa.I2C0_SDA)

i2c = I2C(I2C.I2C0, scl=board_info.IMU_SCL, sda=board_info.IMU_SDA)

sh3001 = SH3001(i2c)
temp_config(SH3001.TEMP_ODR_63HZ, SH3001.TEMP_ENABLE)

SH3001类为SH3001对象提供了get_temp()方法,用于获取SH3001对象的温度计,get_gyro()方法如下所示: SH3001.get_temp() get_temp()方法用于获取SH3001对象的温度计值,该温度计主要测量SH3001芯片内部的内部,因此并不能很直观得反映出环境温度的情况。 get_temp()方法的使用示例如下所示:

from board import board_info
from fpioa_manager import fm
from machine import I2C
from sh3001 import SH3001

fm.register(board_info.IMU_SCL, fm.fpioa.I2C0_SCLK)
fm.register(board_info.IMU_SDA, fm.fpioa.I2C0_SDA)

i2c = I2C(I2C.I2C0, scl=board_info.IMU_SCL, sda=board_info.IMU_SDA)

sh3001 = SH3001(i2c)
temp_config(SH3001.TEMP_ODR_63HZ, SH3001.TEMP_ENABLE)
temp = sh3001.get_temp()

SH3001类为SH3001对象提供了get_attitude()方法,用于获取SH3001对象姿态解算后的欧拉角,get_attitude()方法如下所示: SH3001.get_attitude() get_attitude()方法用于获取SH3001对象姿态解算后的欧拉角(俯仰角、横滚角和航向角),需要注意的是,通过三轴加速度和三轴陀螺仪数据进行姿态解算需要一定的数学算法支撑,本驱动的姿态解算算法仅供读者参考。 get_attitude()方法的使用示例如下所示:

from board import board_info
from fpioa_manager import fm
from machine import I2C
from sh3001 import SH3001

fm.register(board_info.IMU_SCL, fm.fpioa.I2C0_SCLK)
fm.register(board_info.IMU_SDA, fm.fpioa.I2C0_SDA)

i2c = I2C(I2C.I2C0, scl=board_info.IMU_SCL, sda=board_info.IMU_SDA)

sh3001 = SH3001(i2c, attitude=True)
pitch, roll, yaw = sh3001.get_attitude()

22.2 硬件设计 22.2.1 例程功能

  1. 创建一个I2C对象和一个SH3001对象
  2. 每间隔一段时间读取并打印输出SH3001温度计、加速度计和陀螺仪的测量原始数据 22.2.2 硬件资源
  3. SH3001 IIC_SCL - IO22 IIC_SDA - IO23 22.2.3 原理图 本章实验内容,需要使用到板载的SH3001芯片,正点原子DNK210开发板上的SH3001芯片连接原理图,如下图所示:

图22.2.3.1 SH3001连接原理图

22.3 程序设计 22.3.1 SH3001驱动 有关SH3001驱动的介绍,请见第22.1小节《SH3001驱动介绍及使用方法》。 22.3.2 程序流程图

【正点原子K210连载】 第二十二章 六轴传感器——原始数据读取实验摘自【正点原子】DNK210使用指南-CanMV版指南_加速度计_02

图22.3.2.1 六轴传感器——原始数据读取实验流程图 22.3.3 main.py代码 main.py中的脚本代码如下所示:

from board import board_info
from fpioa_manager import fm
from machine import I2C
import time
from sh3001 import SH3001

fm.register(board_info.IMU_SCL, fm.fpioa.I2C0_SCLK)
fm.register(board_info.IMU_SDA, fm.fpioa.I2C0_SDA)

i2c = I2C(I2C.I2C0, scl=board_info.IMU_SCL, sda=board_info.IMU_SDA)

sh3001 = SH3001(i2c)

while True:
    temp = sh3001.get_temp()
    ax, ay, az = sh3001.get_acc()
    gx, gy, gz = sh3001.get_gyro()
    print("T: %.2f Ax: %d Ay: %d Az: %d Gx: %d Gy: %d Gz: %d" % (temp, ax, ay, az, gx, gy, gz))
    time.sleep_ms(500)

可以看到首先构造了一个I2C对象,I2C对象的SCL和SDA信号使用的正是六轴传感器连接的对应IO。

接着构造了一个SH3001对象,并且传入了前面的I2C对象。 接着便在一个循环中读取并打印输出从SH3001对象获取到的温度值、加速度值和陀螺仪值。 22.4 运行验证 将DNK210开发板连接CanMV IDE,并将SH3001的驱动脚本文件保存到CanMV的文件系统后点击CanMV IDE上的“开始(运行脚本)”按钮后,可以看到“串行终端”窗口中输出了一系列信息,如下图所示:

【正点原子K210连载】 第二十二章 六轴传感器——原始数据读取实验摘自【正点原子】DNK210使用指南-CanMV版指南_参数配置_03

图22.4.1 “串行终端”窗口打印输出 可以看到,“串行终端”不断输出从SH3001获取到的温度值、加速度值和陀螺仪值。