手把手搭建自己的智能家居 - 基于 IOT Pi 的智能甲醛检测器
智慧家居 - 基于 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 接口代码运行效率更高。不过目前组件太少,只能做一些基础开发,希望官方能加入更多的组件。
手把手搭建自己的智能家居 - 基于 IOT Pi 的智能甲醛检测器的更多相关文章
- Mentor面向智能家居的IoT方案
版权声明:本文为博主原创文章,未经博主同意不得转载. https://blog.csdn.net/wireless_com/article/details/82111734 眼下有各种智能家居的自己主 ...
- 从零开始的DIY智能家居 - 基于 ESP32 的智能浇水器
前言 上次 土壤湿度传感器 完成之后,就立下一个 flag 要搭建一个智慧浇水的智能场景,现在终于有时间填坑了!(o゚▽゚)o 智慧浇水场景的核心设备有三个: 检测土壤状态的:土壤湿度传感器 通过这个 ...
- 从零开始的DIY智能家居 - 基于 ESP32 的土壤湿度传感器
前言 自从上次做了那个 甲醛传感器 和 水浊度传感器 之后开始尝到智能家居的甜头了,这两东西有没有用我不知道,但是没事的时候掏出手机瞄两眼,看着就让人很安心( ̄︶ ̄). 于是懒惰的我开始琢磨把给植物浇 ...
- 从零开始的DIY智能家居 - 基于 ESP32 的智能水浊度传感器
前言 家里有个鱼缸养了几条鱼来玩玩,但是换水的问题着实头疼,经常一个不注意就忘记换水,鱼儿就没了.o(╥﹏╥)o 在获得 Spirit 1 边缘计算机 后就相当于有了一个人智能设备服务器,可以自己开发 ...
- 从零开始 DIY 智能家居 - 基于 ESP32 的智能紫外线传感器模块
目录 前言 硬件选择 二.使用步骤 获取代码 设备控制命令: 设备和协议初始化流程: 配置设备信息 回调函数注册 数据获取与上报流程 总结 前言 做了这么多传感器都是自己玩,这次家里人看不下去了,非得 ...
- 从零开始 DIY 智能家居 - 基于 ESP32 的智能语音合成播报模块
目录 前言 硬件选择 代码解析 获取代码 设备控制命令: 设备和协议初始化流程: 配置设备信息 回调函数注册 语音播报与设置流程 总结 前言 这里这么多设备,突然发现我做的好像都是传感器之类的居多好像 ...
- 从零开始的DIY智能家居 - 基于 ESP32 的智能光照传感器
前言 上周出差有点急,结果家里灯没关,开了整整一周的时间(T▽T),整个人都裂开了,准备做一个能够远程控制灯的东西,让我以后出差能远程把家里灯关了. 第一步就是做这期的主题 - 智能光照传感器,因为我 ...
- 【智能家居篇】wifi在智能家居中的应用
转载请注明出处:http://blog.csdn.net/Righthek 谢谢! 在设计智能家居系统方案时,一个很关键的point就是组网方式.组网方式关系到整个智能家居系统的稳定性.可扩展性.实时 ...
- 基于能量收集的智能家居-2013国家级大学生创业实践项目申报_商业计划书_V0.2
SmartHome项目商业计划 基于能量收集的 免电池无线智能家居系统 IA-SmartHome团队 2012.12 l 基于无线的智能家居解决方案,节省施工成本: l 基于能 ...
随机推荐
- 【PHP数据结构】其它排序:简单选择、桶排序
这是我们算法正式文章系列的最后一篇文章了,关于排序的知识我们学习了很多,包括常见的冒泡和快排,也学习过了不太常见的简单插入和希尔排序.既然今天这是最后一篇文章,也是排序相关的最后一篇,那我们就来轻松一 ...
- 基于Docker构建企业Jenkins CI平台
- 远程连接centos7中mysql8.0
远程连接centos7中mysql8.0 1.使用Navicat for MySQL或者其它数据连接软件 2.先检查centos中防火墙是否关闭,如果关闭不需要设置,如果没有关闭防火墙,请打开3306 ...
- 2021牛客暑期多校训练营9C-Cells【LGV引理,范德蒙德行列式】
正题 题目链接:https://ac.nowcoder.com/acm/contest/11260/C 题目大意 一个平面上,\(n\)个起点\((0,a_i)\)分别对应终点\((i,0)\),每次 ...
- WPF进阶技巧和实战06-控件模板
逻辑树和可视化树 System.Windows.LogicalTreeHelper System.Windows.Media.VisualTreeHelper 逻辑树类(LogicalTreeHelp ...
- BufferedInputStream与BufferedOutputStream的缓存底层实现
首先观察BufferedInputStream 的继承体系,可以看出他是继承自一个FilterInputStream,而这个又是继承自InputStream 我们在之前的装饰器模式就讲过,这个Buff ...
- Redis多种数据类型以及使用场景
SDS简单动态字符串 struct sdshdr { // 记录buf数组中已使用字节的数量 // 等于SDS所保存字符串的长度 int len; // 记录buf数组中未使用字节的数量 int fr ...
- 为什么'\x1B'.length===1?\x与\u知识延伸
背景 先讲一下背景,再说原因 大多数库都会在日志中使用chalk库为console的内容进行上色 被chalk处理后,其原本的内容会被'\x1B...'所包裹 console.log(chalk.bl ...
- HTML(思维导图)
- Cartography Tools(制图工具)
制图工具 1.制图优化 # Process: 分散标记 arcpy.DisperseMarkers_cartography("", "", "EXPA ...