甲醛检测器
本章主要介绍基于 IoT Pi 和 MS-RTOS 制作一个可通过应用程序控制的智能甲醛检测器。
前提条件
- 下载 MS-RTOS 对应的 IDE 开发环境,包括 IoT Studio 工具和 MS-RTOS AutoTester 工具。具体请参考 官网教程。
- 准备一块 IoT Pi 开发板。
- 准备一个配合烧写的 Jlink ARM 仿真器。
- 准备一个甲醛检测传感器,管脚连接如下:3V3 - 3V3 、GND - GND 、RXD - PA2、 TXD - PA3。
操作步骤
步骤 1:工程配置
- 在 MS-RTOS 云开发平台上完成 msrtos_base_sdk 配置和下载。
- 在 IoT Studio 上完成 msrtos_base_sdk 工程导入和编译。
- 在 IoT Studio 上完成 bspstm32f4xx 工程的下载和导入,如下图所示:
步骤 2: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 与密码
};
步骤 3:bspstm32f4xx 编译
选中 bspstm32f4xx 工程,点击编译按钮,编译完成后会在 Debug 目录生成 bspiotpi.bin 文件。
步骤 4:libsddc 配置及编译
下载 libsddc ,将整个目录替换 msrtos_base_sdk 工程中的 libsddc 目录。
选中 msrtos_base_sdk 工程,点击编译按钮,编译 msrtos_base_sdk 工程的组件,编译完成后,会在 libsddc/Debug/sddc_examples/src/example/demo 目录生成 sddc_demo.bin 文件。
步骤 5:烧录代码
使用 MS-RTOS AutoTester 烧写镜像,参考 IoT Pi 快速入门 完成 bspiotpi.bin 和 demo_sddc_sdk.bin 镜像烧写,注意不同的镜像需要烧写到不同的地址。
按下 IoT Pi 开发板的 RESET 按键,MS-RTOS 操作系统启动后,将自动运行 0x08040000 地址处的 SDDC demo 程序:
结果验证
打开嗅探器应用并进行测试,看到甲醛浓度只有 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 (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();
}
}
}
}