RRH62000支持的传感器驱动很多,上一次仅仅是添加完了温度传感器,这次将剩余的rrh62000传感器接口添加上去。下面是传感器支持的功能列表。
相对应的,rtthread目前支持的传感器列表如下:
#define RT_SENSOR_CLASS_ACCE (1) /* Accelerometer */ #define RT_SENSOR_CLASS_GYRO (2) /* Gyroscope */ #define RT_SENSOR_CLASS_MAG (3) /* Magnetometer */ #define RT_SENSOR_CLASS_TEMP (4) /* Temperature */ #define RT_SENSOR_CLASS_HUMI (5) /* Relative Humidity */ #define RT_SENSOR_CLASS_BARO (6) /* Barometer */ #define RT_SENSOR_CLASS_LIGHT (7) /* Ambient light */ #define RT_SENSOR_CLASS_PROXIMITY (8) /* Proximity */ #define RT_SENSOR_CLASS_HR (9) /* Heart Rate */ #define RT_SENSOR_CLASS_TVOC (10) /* TVOC Level */ #define RT_SENSOR_CLASS_NOISE (11) /* Noise Loudness */ #define RT_SENSOR_CLASS_STEP (12) /* Step sensor */ #define RT_SENSOR_CLASS_FORCE (13) /* Force sensor */ #define RT_SENSOR_CLASS_DUST (14) /* Dust sensor */ #define RT_SENSOR_CLASS_ECO2 (15) /* eCO2 sensor */ #define RT_SENSOR_CLASS_GNSS (16) /* GPS/GNSS sensor */ #define RT_SENSOR_CLASS_TOF (17) /* TOF sensor */ #define RT_SENSOR_CLASS_SPO2 (18) /* SpO2 sensor */ #define RT_SENSOR_CLASS_IAQ (19) /* IAQ sensor. */ #define RT_SENSOR_CLASS_ETOH (20) /* EtOH sensor. */ #define RT_SENSOR_CLASS_BP (21) /* Blood Pressure */
从这里面看,如果不动RTT的传感器支持列表(不往里面新增),在不考虑功能重复的情况下,RRH62000至少可以添加6种传感器。除去之前添加的温度传感器,还能添加的有,灰尘传感器(规格书中提到的PMxxx,NCxxx总共9种),湿度传感器,总挥发性有机化合物传感器,二氧化碳传感器,空气质量传感器。
由于开源项目部分暂时不适合动中间框架层的代码,因此灰尘传感器部分就只上报一个参数上去,若有需求,内部项目在框架层添加传感器种类并在驱动层将剩余功能添加上。
代码修改
前面已经贴过所有的部分了,这里仅仅贴修改的部分。
drv_rrh62000.c
代码修改其实就一个套路,增加一种传感器的注册,并在读数据接口中根据传感器种类上报对应数据。由于传感器框架存在我一直认为不合理的地方,就是如果传感器是以模组形式存在,那目前的传感器框架分别读传感器内容时,就会出现每次读都要跑去运行一遍总线的情况。这极大地增加了系统地开销。
static rt_ssize_t _get_data(rt_sensor_t sensor, struct rt_sensor_data *data) { struct sensor_device *dev = sensor->parent.user_data; rt_bool_t isDataReady = RT_FALSE; switch(sensor->info.type) { case RT_SENSOR_CLASS_TEMP: case RT_SENSOR_CLASS_HUMI: case RT_SENSOR_CLASS_TVOC: case RT_SENSOR_CLASS_ECO2: case RT_SENSOR_CLASS_IAQ: case RT_SENSOR_CLASS_DUST: if((rrh62000_read_data_status(dev->dev, &isDataReady) == RT_EOK) && (isDataReady)) { rrh62000_read_measured_value(dev->dev, &dev->data); } break; default: return 0; } switch(sensor->info.type) { case RT_SENSOR_CLASS_TEMP: data->data.temp = (dev->data.temperature.integer_part << 16) + dev->data.temperature.decimal_part; break; case RT_SENSOR_CLASS_HUMI: data->data.temp = (dev->data.humidity.integer_part << 16) + dev->data.humidity.decimal_part; break; case RT_SENSOR_CLASS_TVOC: data->data.temp = (dev->data.tvoc.integer_part << 16) + dev->data.tvoc.decimal_part; break; case RT_SENSOR_CLASS_ECO2: data->data.temp = (dev->data.eco2.integer_part << 16) + dev->data.eco2.decimal_part; break; case RT_SENSOR_CLASS_IAQ: data->data.temp = (dev->data.iaq.integer_part << 16) + dev->data.iaq.decimal_part; break; case RT_SENSOR_CLASS_DUST: data->data.temp = (dev->data.nc_2p5.integer_part << 16) + dev->data.nc_2p5.decimal_part; break; default: goto RET; break; } data->timestamp = rt_sensor_get_ts(); return 1; RET: return 0; } #ifdef BSP_USING_RRH62000_TEMP rt_err_t rrh62000_register_temperature(const char *name, struct rt_sensor_config *cfg, struct sensor_device *dev) { rt_sensor_t sensor = RT_NULL; rt_int8_t result; /* sensor register */ sensor = rt_calloc(1, sizeof(struct rt_sensor_device)); if (sensor == RT_NULL) goto __exit; sensor->info.type = RT_SENSOR_CLASS_TEMP; // Set real type sensor->info.vendor = RT_SENSOR_VENDOR_UNKNOWN; // Set real vendor sensor->info.model = name; // set real model name sensor->info.unit = RT_SENSOR_UNIT_DCELSIUS; // set to real unit flag sensor->info.intf_type = RT_SENSOR_INTF_I2C; // Set interface type sensor->info.range_max = 0xFFFF; // Set to range max sensor->info.range_min = 0x0000; // Set to range min sensor->info.period_min = 50; // Set frequency rt_memcpy(&sensor->config, cfg, sizeof(struct rt_sensor_config)); sensor->ops = &sensor_ops; result = rt_hw_sensor_register(sensor, name, RT_DEVICE_FLAG_RDONLY, dev); if (result != RT_EOK) { goto __exit; } return RT_EOK; __exit: if (sensor) rt_free(sensor); return -RT_ERROR; } #endif #ifdef BSP_USING_RRH62000_HUMI rt_err_t rrh62000_register_humidity(const char *name, struct rt_sensor_config *cfg, struct sensor_device *dev) { rt_sensor_t sensor = RT_NULL; rt_int8_t result; /* sensor register */ sensor = rt_calloc(1, sizeof(struct rt_sensor_device)); if (sensor == RT_NULL) goto __exit; sensor->info.type = RT_SENSOR_CLASS_HUMI; // Set real type sensor->info.vendor = RT_SENSOR_VENDOR_UNKNOWN; // Set real vendor sensor->info.model = name; // set real model name sensor->info.unit = RT_SENSOR_UNIT_PERMILLAGE; // set to real unit flag sensor->info.intf_type = RT_SENSOR_INTF_I2C; // Set interface type sensor->info.range_max = 0xFFFF; // Set to range max sensor->info.range_min = 0x0000; // Set to range min sensor->info.period_min = 50; // Set frequency rt_memcpy(&sensor->config, cfg, sizeof(struct rt_sensor_config)); sensor->ops = &sensor_ops; result = rt_hw_sensor_register(sensor, name, RT_DEVICE_FLAG_RDONLY, dev); if (result != RT_EOK) { goto __exit; } return RT_EOK; __exit: if (sensor) rt_free(sensor); return -RT_ERROR; } #endif #ifdef BSP_USING_RRH62000_TVOC rt_err_t rrh62000_register_TVOC(const char *name, struct rt_sensor_config *cfg, struct sensor_device *dev) { rt_sensor_t sensor = RT_NULL; rt_int8_t result; /* sensor register */ sensor = rt_calloc(1, sizeof(struct rt_sensor_device)); if (sensor == RT_NULL) goto __exit; sensor->info.type = RT_SENSOR_CLASS_TVOC; // Set real type sensor->info.vendor = RT_SENSOR_VENDOR_UNKNOWN; // Set real vendor sensor->info.model = name; // set real model name sensor->info.unit = RT_SENSOR_UNIT_MGM3; // set to real unit flag sensor->info.intf_type = RT_SENSOR_INTF_I2C; // Set interface type sensor->info.range_max = 0xFFFF; // Set to range max sensor->info.range_min = 0x0000; // Set to range min sensor->info.period_min = 50; // Set frequency rt_memcpy(&sensor->config, cfg, sizeof(struct rt_sensor_config)); sensor->ops = &sensor_ops; result = rt_hw_sensor_register(sensor, name, RT_DEVICE_FLAG_RDONLY, dev); if (result != RT_EOK) { goto __exit; } return RT_EOK; __exit: if (sensor) rt_free(sensor); return -RT_ERROR; } #endif #ifdef BSP_USING_RRH62000_DUST rt_err_t rrh62000_register_Dust(const char *name, struct rt_sensor_config *cfg, struct sensor_device *dev) { rt_sensor_t sensor = RT_NULL; rt_int8_t result; /* sensor register */ sensor = rt_calloc(1, sizeof(struct rt_sensor_device)); if (sensor == RT_NULL) goto __exit; sensor->info.type = RT_SENSOR_CLASS_DUST; // Set real type sensor->info.vendor = RT_SENSOR_VENDOR_UNKNOWN; // Set real vendor sensor->info.model = name; // set real model name sensor->info.unit = RT_SENSOR_UNIT_MGM3; // set to real unit flag sensor->info.intf_type = RT_SENSOR_INTF_I2C; // Set interface type sensor->info.range_max = 0xFFFF; // Set to range max sensor->info.range_min = 0x0000; // Set to range min sensor->info.period_min = 50; // Set frequency rt_memcpy(&sensor->config, cfg, sizeof(struct rt_sensor_config)); sensor->ops = &sensor_ops; result = rt_hw_sensor_register(sensor, name, RT_DEVICE_FLAG_RDONLY, dev); if (result != RT_EOK) { goto __exit; } return RT_EOK; __exit: if (sensor) rt_free(sensor); return -RT_ERROR; } #endif #ifdef BSP_USING_RRH62000_ECO2 rt_err_t rrh62000_register_ECO2(const char *name, struct rt_sensor_config *cfg, struct sensor_device *dev) { rt_sensor_t sensor = RT_NULL; rt_int8_t result; /* sensor register */ sensor = rt_calloc(1, sizeof(struct rt_sensor_device)); if (sensor == RT_NULL) goto __exit; sensor->info.type = RT_SENSOR_CLASS_ECO2; // Set real type sensor->info.vendor = RT_SENSOR_VENDOR_UNKNOWN; // Set real vendor sensor->info.model = name; // set real model name sensor->info.unit = RT_SENSOR_UNIT_PPM; // set to real unit flag sensor->info.intf_type = RT_SENSOR_INTF_I2C; // Set interface type sensor->info.range_max = 0xFFFF; // Set to range max sensor->info.range_min = 0x0000; // Set to range min sensor->info.period_min = 50; // Set frequency rt_memcpy(&sensor->config, cfg, sizeof(struct rt_sensor_config)); sensor->ops = &sensor_ops; result = rt_hw_sensor_register(sensor, name, RT_DEVICE_FLAG_RDONLY, dev); if (result != RT_EOK) { goto __exit; } return RT_EOK; __exit: if (sensor) rt_free(sensor); return -RT_ERROR; } #endif #ifdef BSP_USING_RRH62000_IAQ rt_err_t rrh62000_register_IAQ(const char *name, struct rt_sensor_config *cfg, struct sensor_device *dev) { rt_sensor_t sensor = RT_NULL; rt_int8_t result; /* sensor register */ sensor = rt_calloc(1, sizeof(struct rt_sensor_device)); if (sensor == RT_NULL) goto __exit; sensor->info.type = RT_SENSOR_CLASS_IAQ; // Set real type sensor->info.vendor = RT_SENSOR_VENDOR_UNKNOWN; // Set real vendor sensor->info.model = name; // set real model name sensor->info.unit = RT_SENSOR_UNIT_NONE; // set to real unit flag sensor->info.intf_type = RT_SENSOR_INTF_I2C; // Set interface type sensor->info.range_max = 0xFFFF; // Set to range max sensor->info.range_min = 0x0000; // Set to range min sensor->info.period_min = 50; // Set frequency rt_memcpy(&sensor->config, cfg, sizeof(struct rt_sensor_config)); sensor->ops = &sensor_ops; result = rt_hw_sensor_register(sensor, name, RT_DEVICE_FLAG_RDONLY, dev); if (result != RT_EOK) { goto __exit; } return RT_EOK; __exit: if (sensor) rt_free(sensor); return -RT_ERROR; } #endif static int rrh62000_device_register(void) { rt_int8_t result; struct sensor_device *dev; const char *name = "rrh62000"; struct rt_sensor_config cfg = { .mode = RT_SENSOR_MODE_POLLING, .power = RT_SENSOR_POWER_DOWN, }; dev = rrh62000_param_init(); if(dev == RT_NULL) { goto __exit; } #ifdef BSP_USING_RRH62000_TEMP result = rrh62000_register_temperature(name, &cfg, dev); if (result != RT_EOK) { goto __exit; } #endif #ifdef BSP_USING_RRH62000_HUMI result = rrh62000_register_humidity(name, &cfg, dev); if (result != RT_EOK) { goto __exit; } #endif #ifdef BSP_USING_RRH62000_TVOC result = rrh62000_register_TVOC(name, &cfg, dev); if (result != RT_EOK) { goto __exit; } #endif #ifdef BSP_USING_RRH62000_DUST result = rrh62000_register_Dust(name, &cfg, dev); if (result != RT_EOK) { goto __exit; } #endif #ifdef BSP_USING_RRH62000_ECO2 result = rrh62000_register_ECO2(name, &cfg, dev); if (result != RT_EOK) { goto __exit; } #endif #ifdef BSP_USING_RRH62000_IAQ result = rrh62000_register_IAQ(name, &cfg, dev); if (result != RT_EOK) { goto __exit; } #endif return RT_EOK; __exit: if(dev) rt_free(dev); return -RT_ERROR; } INIT_DEVICE_EXPORT(rrh62000_device_register); #ifdef BSP_USING_RRH62000_TEMP #define RRH_TEMP_DEVICE_NAME "temp_rrh" static void rrh6200_temp_read(void) { rt_device_t dev = rt_device_find(RRH_TEMP_DEVICE_NAME); rt_err_t result; rt_uint32_t len; struct rt_sensor_data data; if(!dev) { rt_kprintf("No device name %s\n\r", RRH_TEMP_DEVICE_NAME); return; } result = rt_device_open(dev,RT_DEVICE_FLAG_RDONLY); if(result != RT_EOK) { rt_kprintf("Open %s Fail\n\r", RRH_TEMP_DEVICE_NAME); return; } len = rt_device_read(dev, 0 ,&data,1); if(len) { rt_kprintf("Temp %d.%d \n\r", data.data.temp >> 16, data.data.temp & 0x0000FFFF); } result = rt_device_close(dev); if(result != RT_EOK) { rt_kprintf("Close %s Fail\n\r", RRH_TEMP_DEVICE_NAME); return; } } MSH_CMD_EXPORT(rrh6200_temp_read, rrh62000 sample); #endif #ifdef BSP_USING_RRH62000_HUMI #define RRH_HUMI_DEVICE_NAME "humi_rrh" static void rrh6200_humi_read(void) { rt_device_t dev = rt_device_find(RRH_HUMI_DEVICE_NAME); rt_err_t result; rt_uint32_t len; struct rt_sensor_data data; if(!dev) { rt_kprintf("No device name %s\n\r", RRH_HUMI_DEVICE_NAME); return; } result = rt_device_open(dev,RT_DEVICE_FLAG_RDONLY); if(result != RT_EOK) { rt_kprintf("Open %s Fail\n\r", RRH_HUMI_DEVICE_NAME); return; } len = rt_device_read(dev, 0 ,&data,1); if(len) { rt_kprintf("Humidity %d.%d \n\r", data.data.humi >> 16, data.data.humi & 0x0000FFFF); } result = rt_device_close(dev); if(result != RT_EOK) { rt_kprintf("Close %s Fail\n\r", RRH_HUMI_DEVICE_NAME); return; } } MSH_CMD_EXPORT(rrh6200_humi_read, rrh62000 sample); #endif #ifdef BSP_USING_RRH62000_TVOC #define RRH_TVOC_DEVICE_NAME "tvoc_rrh" static void rrh6200_tvoc_read(void) { rt_device_t dev = rt_device_find(RRH_TVOC_DEVICE_NAME); rt_err_t result; rt_uint32_t len; struct rt_sensor_data data; if(!dev) { rt_kprintf("No device name %s\n\r", RRH_TVOC_DEVICE_NAME); return; } result = rt_device_open(dev,RT_DEVICE_FLAG_RDONLY); if(result != RT_EOK) { rt_kprintf("Open %s Fail\n\r", RRH_TVOC_DEVICE_NAME); return; } len = rt_device_read(dev, 0 ,&data,1); if(len) { rt_kprintf("TVOC %d.%d \n\r", data.data.tvoc >> 16, data.data.tvoc & 0x0000FFFF); } result = rt_device_close(dev); if(result != RT_EOK) { rt_kprintf("Close %s Fail\n\r", RRH_TVOC_DEVICE_NAME); return; } } MSH_CMD_EXPORT(rrh6200_tvoc_read, rrh62000 sample); #endif #ifdef BSP_USING_RRH62000_DUST #define RRH_DUST_DEVICE_NAME "dust_rrh" static void rrh6200_dust_read(void) { rt_device_t dev = rt_device_find(RRH_DUST_DEVICE_NAME); rt_err_t result; rt_uint32_t len; struct rt_sensor_data data; if(!dev) { rt_kprintf("No device name %s\n\r", RRH_DUST_DEVICE_NAME); return; } result = rt_device_open(dev,RT_DEVICE_FLAG_RDONLY); if(result != RT_EOK) { rt_kprintf("Open %s Fail\n\r", RRH_DUST_DEVICE_NAME); return; } len = rt_device_read(dev, 0 ,&data,1); if(len) { rt_kprintf("dust %d.%d \n\r", data.data.dust >> 16, data.data.dust & 0x0000FFFF); } result = rt_device_close(dev); if(result != RT_EOK) { rt_kprintf("Close %s Fail\n\r", RRH_DUST_DEVICE_NAME); return; } } MSH_CMD_EXPORT(rrh6200_dust_read, rrh62000 sample); #endif #ifdef BSP_USING_RRH62000_ECO2 #define RRH_ECO2_DEVICE_NAME "eco2_rrh" static void rrh6200_eco2_read(void) { rt_device_t dev = rt_device_find(RRH_ECO2_DEVICE_NAME); rt_err_t result; rt_uint32_t len; struct rt_sensor_data data; if(!dev) { rt_kprintf("No device name %s\n\r", RRH_ECO2_DEVICE_NAME); return; } result = rt_device_open(dev,RT_DEVICE_FLAG_RDONLY); if(result != RT_EOK) { rt_kprintf("Open %s Fail\n\r", RRH_ECO2_DEVICE_NAME); return; } len = rt_device_read(dev, 0 ,&data,1); if(len) { rt_kprintf("ECO2 %d.%d \n\r", data.data.eco2 >> 16, data.data.eco2 & 0x0000FFFF); } result = rt_device_close(dev); if(result != RT_EOK) { rt_kprintf("Close %s Fail\n\r", RRH_ECO2_DEVICE_NAME); return; } } MSH_CMD_EXPORT(rrh6200_eco2_read, rrh62000 sample); #endif #ifdef BSP_USING_RRH62000_IAQ #define RRH_IAQ_DEVICE_NAME "iaq_rrh6" static void rrh6200_iaq_read(void) { rt_device_t dev = rt_device_find(RRH_IAQ_DEVICE_NAME); rt_err_t result; rt_uint32_t len; struct rt_sensor_data data; if(!dev) { rt_kprintf("No device name %s\n\r", RRH_IAQ_DEVICE_NAME); return; } result = rt_device_open(dev,RT_DEVICE_FLAG_RDONLY); if(result != RT_EOK) { rt_kprintf("Open %s Fail\n\r", RRH_IAQ_DEVICE_NAME); return; } len = rt_device_read(dev, 0 ,&data,1); if(len) { rt_kprintf("IAQ %d.%d \n\r", data.data.iaq >> 16, data.data.iaq & 0x0000FFFF); } result = rt_device_close(dev); if(result != RT_EOK) { rt_kprintf("Close %s Fail\n\r", RRH_IAQ_DEVICE_NAME); return; } } MSH_CMD_EXPORT(rrh6200_iaq_read, rrh62000 sample); #endif
KConfig
menu "Board extended module Drivers" menuconfig BSP_USING_RRH62000 bool "Enable RRH62000" default n if BSP_USING_RRH62000 config BSP_USING_RRH62000_TEMP bool "Enable RRH62000 Temperature" default n config BSP_USING_RRH62000_HUMI bool "Enable RRH62000 Humidity" default n config BSP_USING_RRH62000_TVOC bool "Enable RRH62000 TVOC" default n config BSP_USING_RRH62000_ECO2 bool "Enable RRH62000 ECO2" default n config BSP_USING_RRH62000_DUST bool "Enable RRH62000 Dust" default n config BSP_USING_RRH62000_IAQ bool "Enable RRH62000 IAQ" default n endif endmenu
以上部分修改完后,需运行menuconfig选配好对应的传感器功能并运行scons --target=mdk5生成新工程。我的测试环境是将所有传感器功能都启用。
运行结果
\ | / - RT - Thread Operating System / | \ 5.2.0 build Nov 30 2024 20:07:57 2006 - 2024 Copyright by RT-Thread team [I/I2C] I2C bus [i2c1] registered rrh62000 firmware version 1.0 rrh62000 algoritm version 3.2.0 [I/sensor] rt_sensor[temp_rrh62000] init success [I/sensor] rt_sensor[humi_rrh62000] init success [I/sensor] rt_sensor[tvoc_rrh62000] init success [I/sensor] rt_sensor[dust_rrh62000] init success [I/sensor] rt_sensor[eco2_rrh62000] init success [I/sensor] rt_sensor[iaq_rrh62000] init success Hello RT-Thread! msh >rrh6200_iaq_read IAQ 0.0 msh >rrh6200_iaq_read IAQ 1.0 msh >rrh6200_eco2_read ECO2 400.0 msh >rrh6200_dust_read dust 0.1 msh >rrh6200_tvoc_read TVOC 0.2 msh >rrh6200_temp_read Temp 21.85 msh >rrh6200_humi_read Humidity 41.75 msh >