智慧家居 - 基于 IOT Pi 的智能甲醛检测器
之前的文章体验 MS-RTOS 的时候入手了一个块 IOT Pi ,放着也是浪费,这次我们就利用 IOT PI 开发一个智能甲醛检测器。φ(>ω<*)
关于 IOT Pi 和 MS_RTOS 的介绍可以看看 (初识 IOT Pi 与 MS-RTOS),这两个一个是翼辉推出的物联网开发板(官网介绍),一个是新一代小型物联网操作系统(官网介绍),之前只是跟着官方文档大概体验了一下,一直有想法去研究真正实践一下,最近家里新买了一些家具正好做一个智能甲醛检测器来检测下甲醛是否超标。
软件准备
使用 MS-RTOS 需要下载对应的 IDE 开发环境,下载资源以及安装使用可以参考官网教程:IoT Pi 快速入门
其中需要安装的有 IoT Studio 、MS-RTOS AutoTester 这两个软件,分别是集成开发 IDE 和 烧写及日志查看工具。官方文档写得非常具体可,具体使用上遇到什么问题可以看看我之前写的:初识 IOT Pi 与 MS-RTOS 里面有我初次使用的时候遇到坑和解决办法。
硬件准备
一块 IOT Pi 开发板、配合烧写的 Jlink ARM 仿真器(某宝一搜全都是)、一个甲醛检测传感器 (在写这篇文章的时候发现之前买的传感器下架了,链接是他们家另一款甲醛传感器,看了一下,uart 协议虽然有些些差距,但是和之前适配其他气体类传感器结构一致,只需要改动一处宏定义就可以兼容了,具体修改参照后文中的代码解析)
管脚连接如下:3V3 - 3V3 、GND - GND 、RXD - PA2、 TXD - PA3
工程配置
根据官方文档 IoT Pi Pro 快速入门 完成以下步骤:
在 MS-RTOS 云开发平台上完成 msrtos_base_sdk
配置和下载
在 IoT Stduio 上完成 msrtos_base_sdk
工程导入和编译
在 IoT Stduio 上完成 bspstm32f4xx
工程的下载和导入,如下图所示:
Wi-Fi AP 列表配置
bspstm32f4xx/src/board/IOT_PI/iot_pi_init.c
为 IoT Pi 开发板的初始化源文件,在此源文件中的 ap_list[]
变量用于指定手动连接模式下尝试连接到的 Wi-Fi AP 列表:
/**
* WiFi AP list.
*/
static const ms_esp_at_net_ap_t ap_list[] = {
{ "EOS-00000F", "123456789" }, // Spirit 1 的 Wi-Fi AP SSID 与密码
};
bspstm32f4xx 编译
选中 bspstm32f4xx
工程,点击 “编译” 按钮,将编译 bspstm32f4xx
工程,编译完成后,会在 Debug
目录生成 bspiotpi.bin
文件:
libsddc 配置及编译
在灵感桌面的秘密宝库下载 libsddc :https://gitee.com/inspiration-desktop/libsddc.git
将整个目录替换 msrtos_base_sdk 工程中的 libsddc 目录;
选中 msrtos_base_sdk
工程,点击 “编译” 按钮,将编译 msrtos_base_sdk
工程的组件,编译完成后,会在 libsddc/Debug/sddc_examples/src/example/demo
目录生成 sddc_demo.bin
文件:
烧录验证
使用 MS-RTOS AutoTester 烧写镜像,请参考 《IoT Pi 快速入门》 完成 bspiotpi.bin
和 demo_sddc_sdk.bin
镜像烧写,注意不同的镜像需要烧写到不同的地址,如下表所示:
镜像 | 烧写地址 |
---|---|
bspiotpi.bin | 0x08000000 |
demo_sddc_sdk.bin | 0x08040000 |
按下 IoT Pi 开发板的 RESET 按键,MS-RTOS 操作系统启动后,将自动运行 0x08040000
地址处的 SDDC demo 程序:
可以参考 《IoT Pi 快速入门》 或之前的文章 智能温度传感器!基于 arduino 的智能测温模块 在 Spirit 1 中进行设备添加,这里就不赘述了,打开之前写的 DDC 协议嗅探器进行下测试,看到甲醛浓度只有 0.01 这下可以放心了;
还可以设定警告浓度,达到警告浓度后设备会主动上报当前甲醛浓度:
代码解析
由于现在购买到的甲醛传感器模块的协议和我文章中用到的不一致,需要修改 libsddc/src/sddc_sdk_lib/SDDC_SDK_UART_DEV.h
文件中的一个宏值,将 AIR_INFO_TYPE_1
改为 AIR_INFO_TYPE_2
即可:
#define AIR_INFO_TYPE_1 // 改为 AIR_INFO_TYPE_2
#ifdef AIR_INFO_TYPE_1
#define BUF_SIZE 40
#endif
#ifdef AIR_INFO_TYPE_2
#define BUF_SIZE 24
#endif
#ifdef AIR_INFO_TYPE_3
#define BUF_SIZE 9
#endif
#define FRAME_HEADER_AA 0xaa
#define FRAME_HEADER_2C 0x2c
#define FRAME_HEADER_E4 0xe4
#define UART_AIR_NAME "ch2o"
#define WARN_REPORT_DATA 0.06 //甲醛超标浓度
int uart_dev_init(void);
sddc_bool_t uart_dev_state_get(char *objvalue, int value_len);
sddc_bool_t uart_dev_state_set(const ms_uint64_t value);
在 libsddc/src/sddc_sdk_lib/SDDC_SDK_UART_DEV.h
文件中定义了三种类型的数据格式(其实并没有用到。。。)只有上面的宏定义和函数声明有用到。
在 libsddc/src/sddc_sdk_lib/SDDC_SDK_UART_DEV.c
文件中,有着 uart_dev_init
的实现。包括打开串口并配置,并启用一个线程来定期获取甲醛浓度:
int uart_dev_init(void)
{
fd = ms_io_open("/dev/uart2", O_RDWR, 0666);
ms_uart_param_t param;
param.baud = 9600;
param.data_bits = MS_UART_DATA_BITS_8B;
param.stop_bits = MS_UART_STOP_BITS_1B;
param.parity = MS_UART_PARITY_NONE;
param.flow_ctl = MS_UART_FLOW_CTL_NONE;
param.mode = MS_UART_MODE_TX_RX;
param.clk_pol = MS_UART_CPOL_LOW;
param.clk_pha = MS_UART_CPHA_1EDGE;
param.clk_last_bit = MS_UART_LAST_BIT_DISABLE;
int ret = ms_io_ioctl(fd, MS_UART_CMD_SET_PARAM, ¶m);
if (ret < 0) {
ms_printf("[error]: set uart param failed!\n");
ms_io_close(fd);
return -1;
}
warn_data = WARN_REPORT_DATA;
ret = ms_thread_create("t_uart",
iot_pi_uart_dev_get_thread,
MS_NULL,
2048U,
30U,
70U,
MS_THREAD_OPT_USER | MS_THREAD_OPT_REENT_EN,
MS_NULL);
sddc_return_value_if_fail(ret == MS_ERR_NONE, -1);
return 0;
}
iot_pi_uart_dev_get_thread
线程中定期 3s 获取一次甲醛浓度,校验数据无误后如果超过设置的警告浓度就上报到 Spirit 1上面:
void iot_pi_uart_dev_get_thread()
{
ms_uint8_t buf[BUF_SIZE];
while(1) {
usleep(1000 * 3000);
ms_io_read(fd, &buf, sizeof(buf));
if(buf[0] == FRAME_HEADER_AA){
// if(buf[0] == FRAME_HEADER_2C && buf[1] == FRAME_HEADER_E4){
if (CheckSum(&buf, (BUF_SIZE-1)) != buf[BUF_SIZE-1]) {
printf("data checksum fail ...\n");
break;
} else {
printf("data checksum success ...\n");
uart_value_set(&buf);
}
if (data >= WARN_REPORT_DATA) {
uart_report_state();
}
}
}
}
总结
MS-RTOS 和 IOT Pi 使用起来更偏向于普通的嵌入式操作系统开发,配置上封装没有 arduino 这么完善,还是要自己去配置串口和 GPIO 口什么的,但是 IDE 比 arduino 聪明多了,MS-RTOS 开发手感也比 arduino 移植上去的那个半残的 FreeRTOS 好很多,完善很多。大部分 POSIX 接口都支持,但是用 MS-RTOS 接口代码运行效率更高。不过目前组件太少,只能做一些基础开发,希望官方能加入更多的组件。