Chaos-nano在手持式VOC检测设备上的应用
Chaos-nano 在手持式 `VOC` 检测设备上的应用
- `Chaos-nano` 在手持式 `VOC` 检测设备上的应用
- 产品开发背景
- `VOC` 的危害
- 产品开发的必要性
- 产品介绍
- 产品结构
- 核心优势:极致便携性设计
- 核心芯片:`STM8L151F3` 详细介绍
- 系统整体框架
- 产品系统实现分析
- 工作流程
- 软件实现
- 任务分类与优先级设定
- 核心任务代码逻辑解析
- `Chaos-nano` 在开发中带来的优势
- 新旧软件代码对比
- 传统开发模式带来的问题:
- 使用 `Chaos-nano` 操作系统后的代码优势
- `Chaos-nano` 带来的核心价值总结
- 1. 提升产品易用性
- 2. 降低开发与维护成本,加速产品迭代
- 3. 释放硬件潜力,保障核心产品特性
- 产品视频
产品开发背景
VOC的危害
VOC(挥发性有机化合物)是常温下易挥发的有机化学物质,广泛存在于室内装修材料(甲醛、苯)、家具板材、汽车内饰、日用化学品(清洁剂、香水)等场景中,对人体健康具有显著危害。尤其对老人与孕妇这两类特殊群体,VOC危害更为突出:
孕妇:孕期免疫力较低,长期接触
VOC可能影响胎儿正常发育,增加胎儿畸形、早产、流产的风险,其中甲醛、苯等物质已被证实具有明确的生殖毒性;老人:身体机能衰退,呼吸系统、心血管系统及肝脏肾脏功能较弱,
VOC刺激易引发呼吸道感染、头晕胸闷、血压波动等症状,长期暴露可能加重慢性疾病(如哮喘、冠心病)。
此外,VOC还会导致室内空气质量下降,引发眼睛干涩、皮肤瘙痒等不适,影响特殊群体的日常生活质量。
产品开发的必要性
随着居民对健康重视程度的提升,老人与孕妇的居住环境安全成为家庭核心关注点,但传统VOC检测存在明显痛点:
- 专业检测机构服务价格高昂(单次检测费用数百至数千元),且检测周期长,无法满足日常高频监测需求;
- 大型实验室仪器体积庞大、操作复杂,老人与孕妇难以独立使用,更无法随身携带;
- 普通家用检测工具体积大多数续航较短,无法支撑长时间外出检测;
针对老人与孕妇群体的使用需求,需要一款可以随身携带、可以长时间工作的VOC检测设备;同时需要具备操作极简、数据直观、安全无辐射等核心特性。基于该思路开发面向老人与孕妇的手持式VOC检测设备,具有极强的现实必要性与社会价值。
产品介绍
该产品以“极致便携+长续航”为核心设计目标:
- 为了能够满足便携,在外观设计上采用了这种直径 4 cm 的圆形的外观设计;
- 为了能够长时间工作,在器件选择上选用了低功耗的 8 位单片机
STM8L151F3,并且在系统软件设计上采用了Chaos-nano操作系统——该系统是轻量级的异步协作式操作系统,可以在任务不执行的时候阻塞任务,且可以在合适的时候进入到低功耗状态——进一步降低了产品的功耗。
产品结构
手持式VOC检测设备基于Chaos-nano操作系统与STM8L151F3芯片构建,针对老人与孕妇的使用习惯,采用“极简设计+核心功能聚焦”的模块化结构,核心组成包括:
- 硬件层:
- 控制核心:
STM8L151F3微控制器(小巧封装,降低设备体积); - 传感模块:高精度低功耗
VOC传感器,温湿度传感器 SHT21; - 显示模块:0.95 英寸
OLED显示屏; - 操作模块:一键式操作按键(仅保留开机/唤醒、显示切换 2 个核心按键,简化操作);
- 电源模块:限于产品体积,该产品采用了
150 mAh,并采用usb-micro接口(支持 5V 充电,适配家庭常用充电器);
- 控制核心:
- 系统层:搭载
Chaos-nano操作系统,提供轻量化任务调度、中断处理、低功耗管理等核心功能,适配STM8L151F3的硬件资源限制,确保设备运行稳定、续航持久。 - 应用层:聚焦老人与孕妇的核心需求,包含快速检测、数据精准显示、安全报警、一键校准等功能模块,简化冗余操作,同时通过深度功耗优化,确保
150 mAh电池支撑持续工作 8 小时以上。
核心优势:极致便携性设计
依托150 mAh紧凑锂电池与STM8L151F3芯片的小巧封装,以及轻量级的Chaos-nano操作系统,设备实现“口袋级便携”:
- 尺寸:长 40 mm × 宽 40 mm × 厚 10 mm,并配有钥匙孔,便于老人与孕妇可轻松放入口袋、手提包或随身悬挂,几乎无携带负担;
- 材质:外壳采用 ABS 塑料表面防滑处理,手感舒适,便于握持;边角圆润无棱角,避免磕碰伤害;与铝合金铝块结合,使整体不显单调;
- 续航适配:
usb-micro接口支持充电宝、手机充电器、电脑 USB 口等多种充电方式,外出时可随时补充电量,配合 8 小时以上持续工作能力,满足全天外出检测需求(如就医、购物、探访亲友等场景)。
核心芯片:STM8L151F3详细介绍
STM8L151F3是意法半导体推出的超低功耗 8 位微控制器,基于STM8内核架构,专为电池供电的便携式智能设备设计,其特性与“150 mAh 电池+8 小时续航”的产品定位及老人、孕妇的使用需求高度适配,是设备的理想控制核心:
内核与主频:采用
STM8增强型内核,最高工作频率 16 MHz,支持 16 位乘法指令与硬件除法,指令执行效率高,可快速响应传感器数据采集、按键操作等实时任务,确保设备“开机即测、数据秒出”,无需老人与孕妇长时间等待。存储资源:内置 8 KB Flash 与 1 KB RAM,与
Chaos-nano操作系统的轻量化设计完美匹配——内核仅占用 500 余字节 RAM,剩余内存可充分支撑传感器数据处理、报警逻辑等核心功能,无需额外扩展存储芯片,既降低设备体积与成本,又减少故障风险。运行模式(持续检测状态):16 MHz 主频下芯片自身功耗仅 240 μA/MHz(约 3.8 mA);
STM8L151F3集成多种实用外设,无需额外扩展芯片,既简化设备结构、缩小体积,又降低功耗:芯片封装小巧(UFQFPN20 封装,尺寸 4 mm × 4 mm),可大幅缩小设备体积,为 150
mAh电池的紧凑布局提供硬件基础。
系统整体框架
系统采用“硬件驱动-操作系统-应用层”三层架构:
- 底层驱动层:由
STM8L15x_StdPeriph_Driver驱动库与自定义设备驱动组成,实现STM8L151F3芯片外设(ADC、I2C、GPIO等)及VOC传感器、显示模块、按键等硬件的底层控制,重点优化低功耗驱动逻辑与数据采集精度,对应代码中的devices目录及stm8l15x_it.c/stm8l15x_it.h中断处理文件。 - 操作系统层:即
Chaos-nano内核(kernel目录),负责任务调度(如“采集-处理-显示”任务优先级管理)、低功耗管理(核心功能),通过精简设计确保在STM8L151F3的 1 KB RAM 中高效运行,同时优化任务切换延迟与功耗控制策略,平衡续航与响应速度。 - 应用层:优化核心逻辑,包括:
- 传感器快速采集(
handle.c/handle.h); - 数据直观显示;
- 操作逻辑简化(仅 2 个按键,开机自动检测,无操作自动休眠);
- 传感器快速采集(
产品系统实现分析
工作流程
- 按下开机键之后,系统进行初始化并启动开机键检测任务。当检测到开机键持续 3 s 按下后,设置电源开机并显示第一屏内容;
- 按下切屏按键后:
- 会触发相应的中断,在中断中启动切屏任务;
- 当从中断返回后,调度器优先调度切屏任务;
- 在切屏任务中会切换显示内容;
- 上电后,系统会按照一定的延迟进行数据采集:
- 每 1 s 启动温湿度任务采集一次温湿度,当采集到数据后刷新显示;
- 每 1 s 启动
VOC任务采集一次VOC数据,当采集到数据后刷新显示; - 每 2 s 启动电池任务采集一次电池的电量和充电状态,然后刷新显示;
- 显示刷新:
- 显示刷新没有设定单独的任务,因此显示刷新属于同步操作——这里没有采用单独的任务进行异步刷新显示;
- 通过全局标志来判断当前处于哪个屏幕显示,当有当前屏幕的内容需要刷新时会对屏幕进行刷新,否则直接返回;
- 电池标志在每个屏幕上都有,所以当有电池数据需要刷新时会及时刷新该部分显示;
软件实现
任务分类与优先级设定
该软件基于IAR for STM8开发环境,搭配Chaos-nano操作系统,采用“任务化”设计,将功能拆解为5个独立的任务:
- 电源按键检测任务;
- 切屏按键检测任务;
- 温湿度(SHT21)检测任务;
VOC检测任务;- 电池状态与电量检测任务;
通过基于优先级调度实现高效协同工作。
| 任务 ID | 任务名称 | 核心功能 | 优先级 | 触发方式 |
|---|---|---|---|---|
| TASK_ID_POWER | 电源按键检测 | 检测电源按键是否在规定的时间内保持按下状态 | 0 | 中断 |
| TASK_ID_KEY | 切屏按键检测 | 切换显示屏幕 | 1 | 中断 |
| TASK_ID_SHT21 | 温湿度检测 | 获取温湿度检测数据 | 2 | 定时器 |
| TASK_ID_TVOC | VOC检测 | 获取VOC检测数据 | 3 | 定时器 |
| TASK_ID_BAT | 电池检测 | 检测电池的充电状态与电池电量 | 4 | 定时器 |
核心任务代码逻辑解析
- 主调度逻辑
主函数通过 “获取下一个高优先级任务→执行任务→状态重置” 的循环,实现任务调度,核心逻辑如下:
voidstart_kernel(void){board_init();task_init();time_init();device_on();while(1){switch(task_getNextPriority()){caseTASK_ID_POWER:powerOnHandle();break;caseTASK_ID_KEY:keyHandle();break;caseTASK_ID_SHT21:Get_TempHum();break;caseTASK_ID_TVOC:Get_Tvoc();break;caseTASK_ID_BAT:Check_Charge_Bat();break;caseTASK_ID_DISP://bat_pic(3,50, pow_bat[1]);break;default:task_restoreAll();if(IDLE_PRI==task_getNextPriority()){sleep_cpu();}break;}}}- 电源键检测
当按下电源按键后,会通过中断触发TASK_ID_POWER任务
- 如果在电源关闭的状态下按下:该任务中会先延迟 3 s 后再次判断该按键是否保持按下状态,如果保持按钮下状态则设置相应的引脚和标志位;
- 如果在电源开启的状态下按下:该任务中会先延迟 5 s 后再次判断该按键是否保持按下状态,如果保持按钮下状态则设置相应的引脚和标志位;
voidpowerOnHandle(void){staticbool flag=false;if(!powerOn){if(!flag){if(GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_3)!=RESET){time_create(TASK_ID_POWER,3000,&flag,true);}else{time_cancel(TASK_ID_POWER);}}else{if(GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_3)!=RESET){powerOn=true;GPIO_ResetBits(GPIOD,GPIO_Pin_0);GPIO_SetBits(GPIOA,GPIO_Pin_2);curDispPageNumber=DISP_UPDATE_SHT21;update_disp(curDispPageNumber);}}}else{if(!flag){if(GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_3)!=RESET){time_create(TASK_ID_POWER,5000,&flag,true);}else{time_cancel(TASK_ID_POWER);}}else{if(GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_3)!=RESET){powerOn=false;GPIO_SetBits(GPIOD,GPIO_Pin_0);GPIO_ResetBits(GPIOA,GPIO_Pin_2);curDispPageNumber=DISP_UPDATE_POWER_OFF;update_disp(curDispPageNumber);}}}task_setBlock(TASK_ID_POWER);flag=false;return;}- 温度检测任务
当温湿度传感器初始化时,会启动一个定时器。当定时器计时结束时会触发TASK_ID_SHT21任务,并在该任务中获取通过IIC从SHT21中获取温湿度数据,更新屏幕显示;且启动下一延迟。
voidGet_TempHum(void){if(flag){flag=false;Get_TempHum_1();update_disp(DISP_UPDATE_SHT21);time_create(TASK_ID_SHT21,DELAY_MS,&flag,true);}task_setBlock(TASK_ID_SHT21);}Chaos-nano在开发中带来的优势
由于使用的是 8 位单片机所以产品最初是使用的是传统的软件开发方式;在Chaos-nano操作系统被开发后,使用Chaos-nano操作系统对该项目进行了重构。
新旧软件代码对比
- 以下代码时传统模式开发中的按键处理部分:
voidKeyHandle(){OLED_CLS();while(1){if(Sleeping==0){if(PowerStatus==ENABLE)//表示开机{Delay(3000);Check_Charge_Bat();Dis_Bat();if(page_nums==0){//显示温度my_page=3;Delay(1000);if(FlagChange==ENABLE)//按下S2翻页{page_nums=1;OLED_CLS();Dis_Uin();FlagChange=DISABLE;}Get_TempHum();Check_Charge_Bat();Dis_Bat();//OLED 显示Dis_Data(page_nums);}elseif(page_nums==1){//显示RHmy_page=0;Delay(1000);if(FlagChange==ENABLE){page_nums=2;OLED_CLS();Check_Charge_Bat();FlagChange=DISABLE;}Get_TempHum();Check_Charge_Bat();//OLED 显示Dis_Data(page_nums);}elseif(page_nums==3){//显示TVOCmy_page=2;Delay(1000);if(FlagChange==ENABLE){page_nums=0;OLED_CLS();FlagChange=DISABLE;}Get_Tvoc();//OLED 显示Dis_Data(page_nums);}elseif(page_nums==2){//显示OC2my_page=1;Delay(1000);if(FlagChange==ENABLE){page_nums=3;OLED_CLS();Check_Charge_Bat();FlagChange=DISABLE;}Check_Charge_Bat();Get_Tvoc();//OLED 显示Dis_Data(page_nums);}}elseif(PowerStatus==DISABLE)//充电状态关机{Delay(3000);if(FlagS==ENABLE){FlagChange=DISABLE;page_nums=0;FlagS=DISABLE;//关闭OLED屏幕OLED_CLS();}}}ScreenDispose();}}- 使用
Chaos-nano操作系统后的代码
voidkeyHandle(void){if(!powerOn)return;curDispPageNumber=(curDispPageNumber==DISP_UPDATE_SHT21)?DISP_UPDATE_TVOC:DISP_UPDATE_SHT21;OLED_CLS();update_disp(DISP_UPDATE_BAT);update_disp(curDispPageNumber);task_setBlock(TASK_ID_KEY);}voidupdate_disp(enumdisp_update_tdisp_update_number){switch(disp_update_number){caseDISP_UPDATE_SHT21:{if(disp_update_number!=curDispPageNumber)return;//显示温湿度......}break;caseDISP_UPDATE_TVOC:{uint16_tTvocmg_L=0;uint16_teCO2PPM=0;if(disp_update_number!=curDispPageNumber)return;//显示甲醛和空气质量......}break;caseDISP_UPDATE_BAT:{if((curDispPageNumber==DISP_UPDATE_SHT21)||(curDispPageNumber==DISP_UPDATE_TVOC)){Dis_Bat(true);}else{Dis_Bat(false);}}break;caseDISP_UPDATE_POWER_OFF:{OLED_CLS();Dis_Bat(true);}break;}}传统开发模式带来的问题:
- 逻辑冗余且耦合度极高
- 代码将按键检测、页面切换、数据采集(温湿度、TVOC)、OLED 显示、电池检测等功能 “堆叠” 在一个无限循环中,各模块职责边界模糊。例如,按键翻页逻辑与
page_nums变量强绑定,数据采集函数(Get_TempHum()、Get_Tvoc())直接嵌入页面判断分支,若需新增 “甲醛浓度单独显示” 页面,需修改整个循环结构与多个判断条件,牵一发而动全身。 - 依赖
Sleeping、PowerStatus、FlagChange等全局变量进行状态控制,变量状态流转不透明,排查问题时需追溯整个代码流程,维护成本极高。
- 阻塞式设计影响用户体验
- 代码中大量使用
Delay(1000)、Delay(3000)等阻塞延时函数,期间 CPU 无法响应其他操作。对于用户而言,按下按键后可能需等待 1-3 秒才能完成页面切换,操作流畅度差;若在延时期间触发其他按键(如误触),设备无任何响应,易造成 “设备故障” 的误解。 - 无限循环
while(1)占用全部 CPU 资源,即使设备处于无操作状态,也无法进入低功耗模式,直接导致电池的续航能力大幅缩水,难以满足长时间工作的产品需求。
- 扩展性差,适配需求变更成本高
- 页面切换逻辑通过
page_nums的多分支if-else实现,若需新增检测参数(如温湿度、TVOC 之外增加 PM2.5 显示),需新增page_nums枚举值、扩展判断分支、修改翻页逻辑,代码量呈线性增长,且容易引入逻辑错误。 - 按键处理与显示、数据采集深度耦合,若需优化操作逻辑(如 “长按按键锁定数据”),需在冗长的循环中插入新的判断条件,破坏原有代码结构。
使用Chaos-nano操作系统后的代码优势
模块化拆分,职责单一清晰
- 将原代码拆分为 “按键处理(
keyHandle())” 与 “显示更新(update_disp())” 两大独立模块,按键仅负责触发页面切换,显示仅负责根据页面类型更新内容,数据采集可独立封装为任务,各模块通过curDispPageNumber枚举变量通信,职责边界明确。 - 采用枚举
enum disp_update_t定义显示类型(DISP_UPDATE_SHT21、DISP_UPDATE_TVOC等),新增页面时仅需扩展枚举值与update_disp()中的switch分支,无需修改按键处理逻辑,扩展性极强。例如,新增 “甲醛显示” 页面,仅需添加DISP_UPDATE_FORMALDEHYDE枚举项与对应的显示分支,代码改动量不足 10 行。
- 将原代码拆分为 “按键处理(
非阻塞式设计,适配特殊群体操作需求
- 彻底摒弃阻塞延时,借助
Chaos-nano的任务调度机制实现异步处理。按键按下后,keyHandle()仅完成 “页面序号切换→触发显示更新→任务阻塞” 的核心逻辑,无需等待;数据采集、OLED 刷新等耗时操作可由独立任务异步执行,用户按下按键后瞬间完成页面切换,无延迟感,操作体验更流畅。 - 通过
task_setBlock(TASK_ID_KEY)函数将按键任务阻塞,避免短时间内重复触发,同时释放CPU资源供其他任务(如低功耗管理、数据校准)使用。配合Chaos-nano的低功耗调度,设备无操作时可快速进入休眠模式,最大化延长电池的续航时间。
- 彻底摒弃阻塞延时,借助
状态管理透明,维护效率大幅提升
- 页面状态通过
curDispPageNumber枚举变量统一管理,取值范围明确(仅对应已定义的显示类型),避免了裸机代码中全局变量状态混乱的问题。例如,update_disp()函数通过判断枚举值直接定位显示逻辑,无需追溯全局变量的修改记录。 - 逻辑分支从 4 个
if-else简化为 1 个switch语句,可读性极强。开发人员无需理解复杂的循环嵌套与延时逻辑,即可快速定位问题或进行功能扩展,大幅缩短产品迭代周期。
- 页面状态通过
低耦合设计,适配产品功能迭代
- 按键处理与数据采集、显示逻辑完全解耦。若需优化用户使用体验(如 “默认显示 TVOC 浓度,减少翻页操作”),仅需修改
curDispPageNumber的初始值;若需调整电池显示逻辑,仅需修改update_disp()中的DISP_UPDATE_BAT分支,不影响其他功能模块。 - 依托
Chaos-nano的任务管理能力,可轻松新增独立任务(如 “低电量报警”“一键校准”),无需担心与原有按键、显示逻辑冲突。例如,新增 “校准任务” 时,仅需创建新任务并添加新功能的代码,原有代码无需改动。
- 按键处理与数据采集、显示逻辑完全解耦。若需优化用户使用体验(如 “默认显示 TVOC 浓度,减少翻页操作”),仅需修改
Chaos-nano带来的核心价值总结
对于本项目而言,Chaos-nano不仅是 “让代码更简洁”,更是通过架构革新实现了三大核心价值:
1. 提升产品易用性
非阻塞式设计消除了按键操作的延迟感,模块化逻辑保障了设备运行的稳定性,让老人与孕妇 “一键操作、即刻响应” 的核心需求得到充分满足,降低了特殊群体的使用门槛。
2. 降低开发与维护成本,加速产品迭代
简洁的代码结构、清晰的模块划分,让开发人员无需花费大量时间梳理逻辑关系,新增功能、修改需求时的代码改动量减少 60% 以上,显著缩短产品开发周期与维护成本。
3. 释放硬件潜力,保障核心产品特性
Chaos-nano的低功耗调度机制,配合非阻塞式代码设计,同时确保设备体积小巧、重量轻盈,完美实现 “极致便携 + 长续航” 的产品定位。
综上,Chaos-nano操作系统通过对传统裸机代码的架构重构,解决了逻辑冗余、耦合度高、扩展性差等痛点,同时为开发团队提供了高效、灵活的开发框架,成为产品核心竞争力的重要支撑。
代码位置:https://gitee.com/kongrong77/Chaos-nano/tree/main/examples/nose_chaos_nano
产品视频
https://gitee.com/kongrong77/Chaos-nano/blob/main/pic/voc.gif