AP3216C
利用 RT-Thread 的AP3216C 软件包读取传感器 ap3216c 测量的接近感应(ps,proximity sensor)与光照强度(als,ambient light sensor)。
创建BSP1.0.0版本的项目后,在软件包中添加AP3216C.
在软件包的说明中发现需要开启sensor和iic
所以在设置中开启sensor和iic.
这里了解到使用的引脚编号(pin munber)是rt thread的引脚编号,不是开发板原理图中的引脚编号,计算公式为
(字母-A)*16+数字
比如我的i2c3 SCL引脚为PC0,带入则是(C-A)*16+0=32
i2c3 SDA引脚为PC1,带入则是(C-A)*16+1=33
软件包是基于sensor构建的,利用sensor框架可以方便的驱动外设,从官方文档中了解到:
函数 | 描述 |
---|---|
rt_device_find() | 根据传感器设备设备名称查找设备获取设备句柄 |
rt_device_open() | 打开传感器设备 |
rt_device_read() | 读取数据 |
rt_device_control() | 控制传感器设备 |
rt_device_set_rx_indicate() | 设置接收回调函数 |
rt_device_close() | 关闭传感器设备 |
一般sensor设备流程就是:
在软件包中提供了一个sensor设备的初始化例程,将其粘贴到主函数并修改成需要用的i2c即可
在设备中烧录后打开终端,输入list_device发现已经生成了2个sensor设备,分别是pr_ap321和li_ap321
这样在主函数中对这两个设备查找就能正确使用啦
#include <rtthread.h>
#include <rtdevice.h>
#include <board.h>
#include "sensor_lsc_ap3216c.h"
#define AP3216C_I2C_BUS "i2c3"
int rt_hw_ap3216c_port(void)
{
struct rt_sensor_config cfg;
cfg.intf.dev_name = AP3216C_I2C_BUS;
cfg.intf.user_data = (void *)AP3216C_I2C_ADDR;
rt_hw_ap3216c_init("ap3216c", &cfg);
return RT_EOK;
}
INIT_ENV_EXPORT(rt_hw_ap3216c_port);
/* defined the LED0 pin: PE7 */
#define LED0_PIN GET_PIN(E, 7)
int main(void)
{
rt_device_t pr,li;
struct rt_sensor_data prdata,lidata;
//data=ap3216c_init(i2c_bus_name);
pr=rt_device_find("pr_ap321");
li=rt_device_find("li_ap321");
rt_device_open(pr, RT_DEVICE_FLAG_RDONLY);
rt_device_open(li, RT_DEVICE_FLAG_RDONLY);
while (1)
{
rt_device_read(pr, 0, &prdata, 1);
rt_device_read(li, 0, &lidata, 1);
rt_kprintf("ps data : %d\n",prdata.data.proximity);
rt_kprintf("light : %d\n",lidata.data.light);
HAL_Delay(2000);
}
return RT_EOK;
}
现象:
ICM20608
利用 RT-Thread 的 ICM20608 软件包读取传感器 icm20608 所测量的三轴加速度(three accelerate)、三轴陀螺仪(three gyroscope)。
在软件包中加入ICM20608,发现软件包说明需要开启iic,因为潘多拉开发板的ICM20608和AP3216C共用同一个I2C3,所以与上文的iic开启方式一样设置I2C即可.
根据软件包的API说明,主要流程如下
初始化传感器
初始化函数 icm20608_init 传入的参数 i2c_bus_name 为该传感器挂载的 i2c 总线名称,进行初始化;初始化若失败,则返回空,若成功,>则返回六轴传感器的设备对象 dev。零值校准
首先在进行零值校准时,x 轴、y 轴应处于水平状态,且传感器处于静态;其次使用零值校准函数 icm20608_calib_level 进行零值校准时,>传入设备对象 dev 与 读取零值次数(此处为 10 次,可以改动),若失败,释放资源,提示失败,释放资源,若成功,返回 RT_EOK,零>值数据存放在设备对象 dev 中。读取三轴加速度与三轴陀螺仪
成功校准后,进行数据读取。如果失败,提示传感器不正常工作;如果成功,打印读取的三轴加速度与三轴陀螺仪的测量值.
记得引入icm20608.h头文件
#include <rtthread.h>
#include <rtdevice.h>
#include <board.h>
#include <icm20608.h>
int main(void)
{
icm20608_device_t dev;
rt_err_t result;
dev=icm20608_init("i2c3");
if(dev!=RT_NULL){
rt_kprintf("icm20608 init success!");
}else {
rt_kprintf("icm20608 init fialure!");
}
result=icm20608_calib_level(dev, 10);
if(result==RT_EOK){
rt_kprintf("calibation success!");
rt_kprintf("accel_offset: X%6d Y%6d Z%6d", dev->accel_offset.x, dev->accel_offset.y, dev->accel_offset.z);
rt_kprintf("gyro_offset : X%6d Y%6d Z%6d", dev->gyro_offset.x, dev->gyro_offset.y, dev->gyro_offset.z);
}else {
rt_kprintf("cablibation failure!");
}
while (1)
{
rt_int16_t accel_x, accel_y, accel_z;
rt_int16_t gyros_x, gyros_y, gyros_z;
/* 读取三轴加速度 */
result = icm20608_get_accel(dev, &accel_x, &accel_y, &accel_z);
if (result == RT_EOK)
{
rt_kprintf("current accelerometer: accel_x%6d, accel_y%6d, accel_z%6d", accel_x, accel_y, accel_z);
}
else
{
rt_kprintf("The sensor does not work");
break;
}
/* 读取三轴陀螺仪 */
result = icm20608_get_gyro(dev, &gyros_x, &gyros_y, &gyros_z);
if (result == RT_EOK)
{
rt_kprintf("current gyroscope : gyros_x%6d, gyros_y%6d, gyros_z%6d", gyros_x, gyros_y, gyros_z);
}
else
{
rt_kprintf("The sensor does not work");
break;
}
rt_thread_mdelay(1000);
}
return RT_EOK;
}
现象: