
简介本资源是一套基于RT-Thread实时操作系统的嵌入式温湿度监测与报警系统完整工程面向物联网开发初学者、嵌入式工程师及高校实践教学人员解决工业环境、仓储物流、医药冷链等场景中对温湿度实时感知、阈值预警与本地/远程响应的核心需求。压缩包共44个文件涵盖6个C源文件含传感器驱动、LVGL图形界面、OneNet云对接模块、6个头文件board.h、rtconfig.h等硬件与系统配置、2个Keil工程文件.uvprojx/.uvoptx、1个LVGL界面截图png及SCons构建脚本、CubeMX配置、Kconfig菜单配置等关键开发要素整体大小1.95MB结构清晰符合RT-Thread官方项目规范。已有1011人学习下载读者可直接编译烧录至星火一号开发板获得从DHT22数据采集、LCD/LVGL动态显示、蜂鸣器LED本地报警到Wi-Fi联网告警的全链路可运行代码并复用其多任务调度设计、中断处理逻辑与云平台通信模板。1. 项目整体设计与思路拆解1.1 为什么做温湿度监测与报警系统事情要从我手头的一个实际需求说起。工作室里有一批对环境要求比较敏感的电子元器件夏天潮湿、冬天干燥稍微不注意就会影响良品率。一开始我用的是那种十几块钱的温湿度计但问题很明显没法实时远程看数据也没法在温湿度超限时自动报警。后来我翻了翻手上的开发板发现RT-Thread官方的星火一号开发板正好适合做这个事——板载资源够用、支持RT-Thread操作系统、扩展接口齐全于是就有了这个温湿度监测与报警系统的项目。从技术角度看这个项目的核心需求有三个一是实时采集环境温湿度数据二是将数据解析、显示并按照预设阈值进行报警判断三是保留后续扩展的能力比如数据上报、云端联动。因为涉及传感器读取、多任务调度、外设控制用裸机开发虽然也能实现但代码耦合度高、扩展性差。所以我在方案选型时直接锁定了RT-Thread实时操作系统配合星火一号开发板来跑多线程任务。1.2 整体架构与核心方案选型先说一下硬件层面的核心配置主控星火一号开发板STM32F407ZGT6主频168MHzCortex-M4内核传感器DHT11温湿度传感器也可以用AHT20我后面会做对比显示板载OLED显示屏0.96寸I2C接口SSD1306驱动报警无源蜂鸣器 LED指示灯交互板载按键用于设置报警阈值调试板载ST-Link 串口软件层面的核心架构是这样的操作系统RT-Thread Nano版本也可以通过RT-Thread Studio直接创建完整版工程传感器驱动基于RT-Thread的传感器设备驱动框架通过软件包方式加载DHT11驱动应用层温湿度采集线程、数据显示线程、报警判断线程调试接口FinSH控制台这个真的强烈推荐直接在终端里敲命令就能查看系统状态为什么选RT-Thread而不是FreeRTOS我的理由主要有几点第一RT-Thread的组件生态比较完整传感器驱动有现成的软件包可以复用第二FinSH控制台调试起来太方便了不用反复烧录固件就能动态查看传感器数据第三星火一号开发板本身就是RT-Thread官方设计的评估板芯片适配和BSP支持都已经做得很成熟拿来就能直接用基本不用自己适配驱动。1.3 报警机制的设计思路报警逻辑看起来简单实际上要考虑的细节不少。我最初的方案是温度超过阈值就触发报警但实际跑起来后发现了一个问题如果传感器读数在阈值附近抖动蜂鸣器会频繁通断非常影响体验。所以我加了三层机制平滑滤波连续采集5次数据去掉最大值和最小值后取平均抑制偶发跳变。滞回控制当温度超过上限值触发报警后必须回落到上限值减2℃才解除报警避免在阈值附近反复触发。蜂鸣器间歇鸣响报警时蜂鸣器不是一直响而是每500ms切换一次状态既醒目又不至于太刺耳。这套机制看起来简单但是在实际使用中体验差距很明显。后面章节我会把具体实现代码和参数计算过程详细拆开讲。2. 硬件准备与核心器件解读2.1 传感器选型DHT11、AHT20、SHT30怎么选先聊聊传感器选型。现在市面上常见的数字温湿度传感器主要有三款DHT11、AHT20、SHT30。型号温度精度湿度精度采样周期通信接口价格约适合场景DHT11±2℃±5%RH1s单总线3~5元入门学习、精度要求不高的场景AHT20±0.3℃±2%RH0.5sI2C5~8元精度要求较高的环境监测SHT30±0.3℃±2%RH0.5sI2C8~15元工业级应用长期稳定性更好我最终用的是DHT11理由是项目定位是快速搭建一套可用的环境监测报警系统精度需求没那么苛刻。DHT11的价格便宜、驱动代码简单、网上资料多踩坑时排查也方便。如果你做的是精度敏感的场景比如药品存储、实验室环境我建议直接上AHT20I2C接口比单总线稳定得多。这里要提醒一句DHT11是单总线通信协议对时序要求非常严格主控IO口模式切换必须精确到微秒级。RT-Thread的软件包已经写好了驱动但如果自己写裸机驱动建议用定时器捕获的方式来读取单纯靠延时函数有概率在优化等级不同的情况下出现时序错乱。2.2 星火一号开发板的硬件亮点星火一号是RT-Thread官方推出的开发板主控芯片是STM32F407ZGT6。这块芯片的资源对做温湿度监测系统来说绰绰有余——168MHz的主频、192KB SRAM、1MB Flash跑RT-Thread加几路传感器采集加OLED显示CPU占用率基本在5%以下。板载资源方面我用到的有板载ST-Link调试下载器一根USB线搞定烧录和调试不用外接J-Link板载OLED屏幕接口通过I2C总线直接驱动SSD1306板载无源蜂鸣器和LED灯报警输出不用额外接外设板载的按键用来切换报警阈值修改模式开发板上引出的排针间距是2.54mm标准间距用杜邦线连接非常方便。DHT11我接在GPIOB的PB12引脚上OLED走I2C1PB6和PB7蜂鸣器用PA1LED用PC13板载按键用了PB0和PB1。2.3 硬件接线与供电注意事项硬件接线图我直接说关键点因为这种项目接线本来就是查手册用万用表的事但我还是要把几个容易出错的地方单独拎出来讲。第一DHT11的供电电压是3.3V~5.5V但它的数据引脚输出高电平是跟着供电电压走的。如果开发板上的传感器电源是5V供电那么数据引脚输出的高电平也是5V这会超过STM32的容忍电压严格说STM32的普通IO最大容忍电压是VDD0.3V很多引脚通过FT标记支持5V容忍。最稳妥的做法是DHT11用3.3V供电数据引脚直接接主控IO。如果因为走线原因必须用5V供电数据线上串一个1kΩ的电阻做电平限制或者用分压电路降到3.3V。第二OLED用的I2C接口要接上拉电阻。虽然星火一号板载了上拉但如果你自己飞线扩展I2C上拉电阻是必须的一般用4.7kΩ到10kΩ都可以。我之前有块OLED模块本身带了上拉结果还额外加了上拉导致I2C总线上拉过强反而出现通信不稳定的问题——这个细节值得注意。第三蜂鸣器如果用的是无源蜂鸣器需要PWM信号驱动声音才正常如果直接用GPIO高低电平驱动只能听到咔哒咔哒声而不是连续的滴滴声。我在项目里偷了个懒用GPIO翻转的方式驱动实测下来报警声音虽然没有PWM那么好听但通过500ms间隔的滴滴声也足够引起注意了。如果你对报警音调有要求可以改用定时器PWM输出2kHz方波驱动。3. 基于RT-Thread的软件实现全流程3.1 工程创建与环境配置我用的是RT-Thread StudioIDE版本4.1创建工程流程很简单但有几个关键配置点值得记录。第一步打开RT-Thread Studio新建RT-Thread项目选择基于开发板模板芯片型号选STM32F407ZGTX开发板选择星火一号。第二步等待工程创建完成后在rtconfig.h中确认以下宏已经开启#define RT_THREAD_PRIORITY_MAX 32 #define RT_USING_HEAP 1 #define RT_USING_COMPONENTS_INIT 1 #define RT_USING_SERIAL 1 #define RT_USING_FINSH 1 #define RT_USING_I2C 1 #define RT_USING_SENSOR 1 #define RT_USING_PIN 1第三步打开menuconfig在硬件设备驱动中确认I2C驱动、PIN驱动、串口驱动已开启。传感器软件包方面我在RT-Thread Settings - Sensor - DHT11中勾选了DHT11软件包并配置了读取的引脚号。这一步有个小坑RT-Thread Studio的menuconfig配置界面里引脚号填的是board级别的引脚编号不是F407的原始引脚编号。我第一次就填错了号导致传感器读取失败后面在board.h里查了引脚映射表才搞定。3.2 传感器驱动与数据采集实现在RT-Thread中使用传感器设备的标准流程是查找设备 - 打开设备 - 读取数据。先来看DHT11软件包接入后的核心代码#include rtthread.h #include rtdevice.h #include sensor.h #include sensor_dht11.h #define DHT11_DEVICE_NAME dht11 static rt_device_t dht11_dev RT_NULL; static struct rt_sensor_data sensor_data; static int dht11_init(void) { rt_err_t ret RT_EOK; dht11_dev rt_device_find(DHT11_DEVICE_NAME); if (dht11_dev RT_NULL) { LOG_E(Can not find device: %s, DHT11_DEVICE_NAME); return -RT_ERROR; } ret rt_device_open(dht11_dev, RT_DEVICE_FLAG_RDONLY); if (ret ! RT_EOK) { LOG_E(Open device failed: %d, ret); return ret; } return RT_EOK; } static int dht11_read_data(float *temp, float *humi) { rt_ssize_t size rt_device_read(dht11_dev, 0, sensor_data, 1); if (size ! 1) { LOG_E(Read sensor data failed, size%d, size); return -RT_ERROR; } *temp sensor_data.data.temp; *humi sensor_data.data.humidity; return RT_EOK; }这里有几个细节需要注意rt_device_find返回的是设备句柄如果找不到设备先检查驱动注册是否成功可以用list_device命令在FinSH中查看。rt_device_read返回的实际读取长度DHT11软件包一次读取返回一条数据所以检查返回值是否为1。DHT11的数据手册也值得认真看一遍。它的一次数据帧有40bit16bit湿度数据、16bit温度数据、8bit校验码。驱动层已经帮你做了校验和数据解析但了解这个格式有助于理解后面可能出现的异常数据问题。比如如果读到的温度值是-4.0湿度是0.0多数情况下不是传感器坏了而是数据线上有上拉/下拉干扰导致数据帧中湿度高位字节清零了。3.3 温湿度采集线程与滤波算法我设计了一个温湿度采集线程优先级设置为15周期性每1秒执行一次采集并做滤波处理。选用这个周期是因为DHT11手册要求两次读取间隔至少1秒同时1秒的刷新率对于环境监测来说足够快。滤波方面我采用了取中值平均滤波#define FILTER_COUNT 5 static void data_filter(float *temp_buffer, float *humi_buffer, int count, float *temp_out, float *humi_out) { // 对温度做冒泡排序实际上可以只取最值 for (int i 0; i count - 1; i) { for (int j 0; j count - 1 - i; j) { if (temp_buffer[j] temp_buffer[j 1]) { float tmp temp_buffer[j]; temp_buffer[j] temp_buffer[j 1]; temp_buffer[j 1] tmp; float tmp_h humi_buffer[j]; humi_buffer[j] humi_buffer[j 1]; humi_buffer[j 1] tmp_h; } } } // 去掉最大值和最小值剩余3个取平均 float temp_sum 0.0f, humi_sum 0.0f; for (int i 1; i count - 1; i) { temp_sum temp_buffer[i]; humi_sum humi_buffer[i]; } *temp_out temp_sum / (count - 2); *humi_out humi_sum / (count - 2); }为什么用5个点去掉最值取均值而不是简单求均值因为DHT11偶尔会因为时序干扰读到一个跳变值比如实际温度25.4℃突然读到26.8℃这种偶发毛刺对均值的影响可能比较大而去极值取中值平均能在保留数据平滑性的同时把毛刺滤掉。线程代码结构如下static void temp_humi_thread_entry(void *parameter) { float temp_buffer[FILTER_COUNT]; float humi_buffer[FILTER_COUNT]; float temp 0.0f, humi 0.0f; int idx 0; while (1) { float temp_raw, humi_raw; if (dht11_read_data(temp_raw, humi_raw) RT_EOK) { temp_buffer[idx] temp_raw; humi_buffer[idx] humi_raw; idx; if (idx FILTER_COUNT) { idx 0; data_filter(temp_buffer, humi_buffer, FILTER_COUNT, temp, humi); // 数据更新回调 on_env_data_updated(temp, humi); } } rt_thread_mdelay(1000); } }3.4 OLED显示与报警控制实现OLED显示我用了RT-Thread的ssd1306软件包直接查找设备lcd并调用rt_device_control设置显示内容。核心显示逻辑并不复杂关键是要注意显示刷新不能阻塞传感器采集线程。我单独建了一个显示线程通过消息队列从采集线程接收最新的温湿度数据然后更新屏幕。屏幕布局我是这样设计的------------------ | TEMP: 25.4 C | | HUMI: 60.2 % | | [状态正常/报警] | ------------------报警阈值默认设置为温度上限30℃湿度下限30%RH。这个阈值在实际使用中是可以动态调整的通过开发板上的两个按键实现一个按键切换修改温度/湿度另一个按键加/减数值。报警判断放在采集线程里更直接我加一个带滞回的判断函数typedef struct { float temp_limit_high; float humi_limit_low; uint8_t alarm_state; // 0正常1报警 } alarm_ctx_t; static alarm_ctx_t g_alarm; static void check_alarm(float temp, float humi) { uint8_t new_state 0; if (g_alarm.alarm_state 0) { // 正常状态 if (temp g_alarm.temp_limit_high || humi g_alarm.humi_limit_low) { new_state 1; // 进入报警 } } else { // 报警状态滞回 if (temp (g_alarm.temp_limit_high - 2.0f) humi (g_alarm.humi_limit_low 5.0f)) { new_state 0; // 恢复正常 } } if (new_state ! g_alarm.alarm_state) { g_alarm.alarm_state new_state; if (new_state) { rt_pin_write(PIN_BUZZER, PIN_HIGH); rt_pin_write(PIN_LED, PIN_LOW); } else { rt_pin_write(PIN_BUZZER, PIN_LOW); rt_pin_write(PIN_LED, PIN_HIGH); } } // 报警状态下蜂鸣器间歇鸣响 if (g_alarm.alarm_state) { if (rt_tick_get() % 1000 500) rt_pin_write(PIN_BUZZER, PIN_HIGH); else rt_pin_write(PIN_BUZZER, PIN_LOW); } }这里我用了rt_tick_get() % 1000来判断500ms翻转这是一个比较粗糙但实现简单的方式。更精确的做法是给蜂鸣器单独开一个控制线程或使用软件定时器。如果你用的是实时性要求更高的场景建议用软件定时器来翻转。3.5 FinSH调试与串口数据上报这一步我强烈推荐每一位做嵌入式开发的同行都好好利用。RT-Thread的FinSH本质上就是一个命令行工具我在调试过程中反复用它来看传感器原始数据、修改阈值参数不用改代码重新烧录效率提升非常明显。串口数据上报的代码我直接沿用了RT-Thread的日志系统#define LOG_TAG env #include ulog.h LOG_D(Temperature: %.1f°C, Humidity: %.1f%%, temp, humi); if (g_alarm.alarm_state) { LOG_W(ALARM: Temp%.1f, Humi%.1f, temp, humi); }经过实测串口输出可以使用RT-Thread Studio自带的串口终端或任意串口工具连接。波特率是1152008N1日志输出帧结构大概是每2秒1行方便后续接上位机或者用Python脚本做数据存储分析。4. 核心功能模块的深入解析4.1 DHT11驱动原理与时序解读有朋友可能会问直接用软件包不就行了吗为什么还要去了解驱动原理因为实际项目中传感器的读取错误率和你对硬件协议的理解深度直接相关。出了问题如果没有原理层面的认知排查效率会非常低。DHT11的通信协议是单总线协议以主机发送起始信号开始主机拉低总线至少18ms唤醒传感器然后释放总线等待传感器响应。传感器回应一个80us的低电平响应信号然后拉高80us准备发送数据。每个数据位时序50us低电平 26~28us高电平表示逻辑050us低电平 70us高电平表示逻辑1。40位数据发送完毕后传感器释放总线进入空闲状态。所有位时序的定时精度要求在微秒级别所以这也是上面提到的为什么驱动代码必须用定时器捕获或者关中断的方式做不能依赖任务调度。在RT-Thread的DHT11软件包中它用的是rt_hw_us_delay来做微秒延时同时操作PIN口时临时关闭了线程调度。这个驱动能工作但有一个隐患在极端情况下如果系统正在处理高优先级中断且持续时间过长单总线时序会被破坏。不过对于DHT11这种慢速传感器来说这个概率极低实测稳定运行了一周偶尔还会出现校验失败的情况软件包用重试机制解决了这个问题。如果你用AHT20它的I2C时序相对宽容很多因为I2C有SCL时钟线做同步不会出现单总线那样严格的时序要求。这就是为什么很多工业产品普遍用I2C接口传感器而不是单总线传感器。4.2 报警阈值的参数计算与设计逻辑报警系统的核心是阈值但阈值不是随便拍脑袋定的。我设置的默认阈值依据是JIS Z 8703日本工业标准和一般电子产品仓储环境要求温度不超过30℃湿度不低于30%RH。这两个值对于普通民用场景比较有代表性。阈值设计逻辑要考虑三个方面环境需求你保护的物品/设备对环境温湿度有什么要求。比如精密电子车间是22℃±2℃、45%~65%RH一般仓库是15℃~30℃、35%~75%RH。要根据实际需求先定。传感器精度的影响DHT11的温度精度±2℃湿度精度±5%RH。这意味着当显示值接近阈值时实际值可能已经超限了。所以阈值设定时要预留传感器的误差裕量。比如你的环境要求是温度不超过28℃那报警阈值应该设置在26℃左右留出2℃的误差空间。滞回宽度的选择我在前面提到报警后温度回落2℃才解除。这个2℃是怎么来的主要考虑两个因素一是传感器本身的自然波动DHT11在稳定环境中的读数波动大约是±0.5℃二是空调/制冷设备的控温回差一般空调的温度控制回差是±1℃。如果设置的滞回值小于传感器波动范围报警系统就会在临界点附近来回触发所以取2℃既能避免抖动又不会太迟钝。湿度这边的滞回我用的是5%RH也是类似的逻辑。DHT11的湿度测量波动比温度大一些取5%左右比较合适。4.3 多线程任务调度评估整个系统运行中有几个线程在并发工作线程名称优先级周期最大栈空间估算功能temp_humi_thread151s1024B采集温湿度并滤波display_thread20200ms1024B刷新OLED显示alarm_thread10500ms512B报警判断与输出控制idle_thread31-512B系统空闲tshell_thread5-4096BFinSH控制台线程优先级的分配逻辑是报警线程优先级最高数值越小优先级越高因为报警是安全相关的实时任务采集线程其次显示线程优先级最低因为UI刷新晚几百毫秒感知不强烈FinSH线程是RT-Thread自带的优先级默认是5这个值不用改。为什么报警线程的周期不也用1秒而是用500ms因为报警输出需要快速响应蜂鸣器响和新数据到达之间的延迟如果太长用户站在设备旁边会明显感觉反应慢半拍。500ms的周期配合报警函数的滞回判断既能做到快速响应又不会因为传感器更新慢导致报警线程空转。内存占用方面所有线程的栈加上系统核心数据结构总内存占用大约16KB星火一号的192KB SRAM剩余空间还非常充裕。如果你后续要加以太网、WIFI、文件系统这个余量是完全够用的。4.4 OLED显示驱动的优化OLED显示这一块看起来很简单但实际有几个优化心得可以分享。第一I2C的通信速率默认是100kHz标准模式SSD1306这些OLED模块支持400kHz快速模式在RT-Thread的I2C驱动配置里可以直接改。实测从100kHz提到400kHz后整屏刷新的等待时间从大约30ms降到了约10ms对于1秒刷新一次的应用来说体验提升非常明显但也注意I2C设备的实际走线质量如果杜邦线较长超过15cm建议不要超频到400kHz否则可能出现通信错误。第二不要整屏刷新。OLED模块本身不支持分区域刷新但可以在内存中维护一个背板缓冲区只把变化的部分写入显存。我在项目里只把温度和湿度数值更新固定内容TEMP:和HUMI:标签只在初始化时写入一次。这样每次刷新只需要发送约40字节的数据显著减少了I2C通信量。第三字库选择。SSD1306模块支持内置的ASCII字符字库8x6直接调用软件包自带的中文显示也是可以的。但中文显示一般在主控中有取模软件生成的数组本项目只显示英文和数字用起来最方便。5. 常见问题与排查技巧实录5.1 传感器读取失败或者数值为0这是我调试过程中遇到最多的一个问题。主要表现是FinSH中查看DHT11设备存在但读出来的数据一直是0.0或-4.0。排查思路按优先级来检查传感器电源DHT11的VCC引脚是否稳定在3.3V~5V之间用万用表量一下最直接。我之前有一次把杜邦线插错了把VCC接到了GND上数据全是0第一时间没查出来。检查数据线连接DHT11的DATA引脚和主控GPIO之间是否有虚接、短路、接触不良。杜邦线用久了会有氧化层接触电阻大了会导致时序边缘变差。检查引脚配置确认驱动配置里填的引脚号和实际接线一致。RT-Thread的PIN编号不是芯片引脚号需要查开发板的引脚映射表。检查上拉电阻DHT11的数据线上必须有4.7kΩ~10kΩ的上拉电阻到VCC没有上拉的话数据读取会失败。很多DHT11模块已经板载了上拉电阻但如果你直接买了裸传感器记得自己接。如果这些检查都做完了还是不行可以在FinSH里用list_device命令确认设备的注册状态然后用逻辑分析仪抓一下总线波形看看有没有响应信号。没有响应信号多为接线问题有波形但数据全是1或0多为上拉或者干扰问题。5.2 OLED屏幕显示乱码或者不显示OLED的问题主要集中在I2C地址不匹配、显示初始化失败和数据发送异常。SSD1306的I2C地址一般是0x3C或者0x3D取决于模块上SA0引脚的电平。我用的模块默认是0x3C但有的模块是0x3D。RT-Thread的ssd1306软件包可以通过menuconfig修改I2C地址默认是0x3C。如果你买到的模块是0x3D不修改配置就会初始化失败屏幕黑屏。另外有一个非常隐蔽的问题I2C时序受上拉电阻和线缆电容影响的容忍度不一样。如果杜邦线超过20cm线电容大了之后高频通信容易出错表现为屏幕闪烁或者显示错乱。处理方法是缩短杜邦线或者把I2C速度降到100kHz。5.3 蜂鸣器不响或者声音异常蜂鸣器不响先分清是有源还是无源。有源蜂鸣器内部有振荡源给高电平就响无源蜂鸣器需要外部给PWM信号才能发声。我用的是无源蜂鸣器如果直接写rt_pin_write(PIN_HIGH)只能听到一声咔哒不会有持续声音。所以在报警输出中我用的是每500ms翻转一次电平等效于产生了1Hz的方波信号听感上就是滴、滴、滴的节奏。如果你希望发出更清脆的声音应该使用定时器的PWM输出配置为2kHz左右的方波然后通过PWM占空比控制音量。5.4 串口日志输出乱码串口乱码是最简单的问题但也是最常见的。出现乱码的排查顺序串口工具的波特率是否和代码里配置一致。RT-Thread默认调试串口是115200如果串口助手设置成了9600打印出来就会乱码。系统时钟配置是否正确。如果外部晶振频率没配对比如实际是8MHz但代码里配的是25MHz串口波特率就会有偏差。共地问题。USB转串口模块和开发板必须共地否则信号电压参考点不一致会出现间歇性乱码。6. 系统扩展方向与实际使用心得整个系统跑起来之后实用价值已经超过了最初的预期。我在工作室里连续运行了两周没有出现一次死机或者严重的传感器错误。30℃温度报警触发过两次一次是下午阳光直射到传感器附近一次是空调停机后的温度反弹报警响应都很及时蜂鸣器的声音在隔壁房间都能听到。后续我计划做几个方向的扩展数据上云星火一号板载了以太网接口可以很容易地接上RT-Thread的SAL套接字抽象层通过MQTT协议把温湿度数据推送到云端。数据积累之后还能做一些趋势分析比如判断环境变化的规律。多传感器接入在I2C总线上挂AHT20再加SHT30做数据比对和冗余校验提高系统在传感器故障时的健壮性。远程报警联动报警触发时除了蜂鸣器和LED还可以通过微信/短信通知。方案是接入ESP8266或者直接用开发板以太网加上一个简单的HTTP客户端调用第三方消息推送接口。最后分享一个我在实际测试中发现的细节传感器的放置位置比传感器本身的精度更重要。一开始我把DHT11放在开发板旁边由于芯片发热读到的温度比环境实际温度高了将近3℃。后来我把传感器用杜邦线延长到离开发板约30cm的地方数据才基本接近真实环境温度。做环境监测项目时一定要让传感器远离热源保持在通风的环境中不然报出来的数据都是假数据后续的所有逻辑都会跟着出问题。以上就是这个基于RTT星火一号开发板的温湿度监测与报警系统的完整实现过程。项目本身难度不高但麻雀虽小五脏俱全从传感器驱动到多线程调度再到报警策略设计每个环节都有值得深入琢磨的地方。如果你也在做类似的嵌入式小项目希望这篇文章能给你一些参考和启发。本文还有配套的精品资源点击获取