基础资料
基于Air103开发板:Air103 - LuatOS 文档
上手:开发上手 - LuatOS 文档
探讨重点
对官方I2C demo中功能的复现,进行相关内容的学习及探讨。
实现功能
功能2:三轴加速度陀螺仪-MPU6050模块;
硬件准备
Air103开发板1块,面包板1块,mpu6050三轴加速度陀螺仪,导线若干。
软件版本
AIR103:LuatOS@AIR103 base 22.10 bsp V0013
软件使用
接口文档可参考:MPU6050
功能2:mpu6050三轴加速度陀螺仪
-- mpu6050 7位地址 寄存器的默认值为 0x68,即0110 1000
--[[ WHO_AM_I 的内容是 MPU-60X0 的 7 位 I2C 地 址的头 6 位。最后一位地址由 AD0 引脚确定。AD0 引脚的值跟寄存器无关。位 0 和 7 保留。(硬编码为 0)。 WHO_AM_I
包含 MPU-60X0 的 6 位 I2C 地址。 上电复位的值从位 6 到位 1 为:110100。The Power-On-Reset value of Bit6:Bit1 is 位 0+110 100+位 7=0110 1000=0x68]]
i2cSlaveAddr = 0x68
-- Air103 硬件i2c ID
i2cId = 0
--[[
I2C0
I2C0_SDA(SDA,ADC1,GPIO04) (PA4,7#),黄色 D1(SDA)
I2C0_SCL(SCK,ADC0,GPIO01) (PA1,8#),绿色 D0(SCL)
]]
sys.taskInit(function()
if i2c.setup(0, i2c.FAST, 0x68) == 1 then
log.info("i2c", "存在 i2c0") -- I/user.i2c 存在 i2c0
else
i2c.close(0) -- 除非i2c的id错误,通常不会失败
return
end
i2c.send(0, 0x68,117)--发送器件地址 确认#define MPU6050_RA_WHO_AM_I 0x75。
--格式:0, 0x68, string.char(0x75) Register(Hex) 75,Register (Decimal):117,均可识别
sys.wait(50)
local revData = i2c.recv(0, 0x68, 1)--读器件地址
log.info("recv",revData:toHex())--打印 I/user.recv 68 2
i2c.close(0)
end)
初始化硬件i2c
代码如下
-- mpu6050 7位地址 寄存器的默认值为 0x68,即0110 1000
--[[ WHO_AM_I 的内容是 MPU-60X0 的 7 位 I2C 地 址的头 6 位。最后一位地址由 AD0 引脚确定。AD0 引脚的值跟寄存器无关。位 0 和 7 保留。(硬编码为 0)。 WHO_AM_I
包含 MPU-60X0 的 6 位 I2C 地址。 上电复位的值从位 6 到位 1 为:110100。The Power-On-Reset value of Bit6:Bit1 is 位 0+110 100+位 7=0110 1000=0x68]]
i2cSlaveAddr = 0x68
-- Air103 硬件i2c ID
i2cId = 0
--[[
I2C0
I2C0_SDA(SDA,ADC1,GPIO04) (PA4,7#),黄色 D1(SDA)
I2C0_SCL(SCK,ADC0,GPIO01) (PA1,8#),绿色 D0(SCL)
]]
sys.taskInit(function()
if i2c.setup(0, i2c.FAST, 0x68) == 1 then
log.info("i2c", "存在 i2c0") -- I/user.i2c 存在 i2c0
else
i2c.close(0) -- 除非i2c的id错误,通常不会失败
return
end
i2c.send(0, 0x68,117)--发送器件地址 确认#define MPU6050_RA_WHO_AM_I 0x75。
--格式:0, 0x68, string.char(0x75) Register(Hex) 75,Register (Decimal):117,均可识别
sys.wait(50)
local revData = i2c.recv(0, 0x68, 1)--读器件地址
log.info("recv",revData:toHex())--打印 I/user.recv 68 2
i2c.close(0)
end)
示例
--支持mpu6500,mpu6050,mpu9250,icm2068g,icm20608d,自动判断器件id,只需要配置i2c id就可以
--注意:因使用了sys.wait()所有api需要在协程中使用
-- 用法实例
local mpu6xxx = require "mpu6xxx"
i2cid = 0
i2c_speed = i2c.FAST
sys.taskInit(function()
i2c.setup(i2cid,i2c_speed)
mpu6xxx.init(i2cid)--初始化,传入i2c_id
while 1 do
sys.wait(100)
local temp = mpu6xxx.get_temp()--获取温度
log.info("6050temp", temp)
local accel = mpu6xxx.get_accel()--获取加速度
log.info("6050accel", "accel.x",accel.x,"accel.y",accel.y,"accel.z",accel.z)
local gyro = mpu6xxx.get_gyro()--获取陀螺仪
log.info("6050gyro", "gyro.x",gyro.x,"gyro.y",gyro.y,"gyro.z",gyro.z)
end
end)
LOG
[2022-11-27 09:18:12.727] I/user.Device i2c id is: MPU6050
[2022-11-27 09:18:12.929] I/user.mpu6xxx init_ok
[2022-11-27 09:18:13.038] I/user.6050temp 26.84412
[2022-11-27 09:18:13.038] I/user.6050accel accel.x -498.0469 accel.y 130.2490 accel.z 738.4033
[2022-11-27 09:18:13.038] I/user.6050gyro gyro.x -2.213740 gyro.y -1.068702 gyro.z -0.6870229
[2022-11-27 09:18:13.148] I/user.6050temp 26.84412
[2022-11-27 09:18:13.148] I/user.6050accel accel.x -520.7520 accel.y 136.1084 accel.z 765.3809
[2022-11-27 09:18:13.148] I/user.6050gyro gyro.x -2.213740 gyro.y -1.145038 gyro.z -0.6870229
[2022-11-27 09:18:13.257] I/user.6050temp 26.84412
[2022-11-27 09:18:13.257] I/user.6050accel accel.x -520.8740 accel.y 136.7188 accel.z 764.6484
[2022-11-27 09:18:13.257] I/user.6050gyro gyro.x -2.213740 gyro.y -1.068702 gyro.z -0.6870229
后期工作
六轴MPU6050输出欧拉角,DMP库应用
DMP是什么?
引自链接:https://www.zhihu.com/question/38173997/answer/81954770
DMP就是指 MPU6050内部集成的处理单元,可以直接运算出四元数和姿态,而不再需要另外进行数学运算。DMP的使用大大简化了代码设计。DMP是数字运动处理器的缩写,顾名思义mpu9150(mpu6050)并不单单是一款传感器,其内部还包含了可以独立完成姿态解算算法的处理单元。如在设计中使用DMP来实现传感器融合算法优势很明显。首先,invensense官方提供的姿态解算算法应该比一般的小白要可靠的多。其次,由DMP实现姿态解算算法将单片机从算法处理的压力中解放出来,单片机所要做的是等待DMP解算完成后产生的外部中断,在外部中断里去读取姿态解算的结果。这样单片机有大量的时间来处理其他任务,提高了系统的实时性。
经过 DMP你就可以得到四元数,四元数就是4个数,可以表征姿态,经过几个数学公式之后就可以的出姿态,姿态包括pitch,roll,yaw。
综上,dmp之后直接出结果,可以直接用,当然你如果有特殊需要自己还要加滤波也没有问题。
具体怎么用我直接上附件吧,在论坛以前收藏的一个帖子,基本包含所有的技术细节,无论是自己软解,还是直接用DMP都有说明。