简介:本资源是一套基于STM32F103C8T6的智能仓储环境监测系统完整工程实现,面向嵌入式初学者、课程设计学生及物联网实践开发者,解决小型仓储场景下温湿度、光照、烟雾等多参数实时感知与闭环调控问题。项目融合Proteus仿真与真实硬件逻辑,支持本地按键交互、OLED可视化及ESP8266远程监控,具备加热、散热、通风、声光报警等完整执行链路。压缩包含335个文件,涵盖56个编译中间文件(.o)、55个源码备份(.zbak)、55个配置文件(.crf)、38个头文件(.h)、36个C源文件(.c)及Keil工程(.uvprojx)、Hex固件、启动汇编与链接脚本等核心开发资产,总大小16.99MB。已有79人学习下载,提供可直接编译运行的完整代码结构、模块化驱动(ADC、I2C、TIM、RCC等)、阈值设定逻辑实现及无线通信接口封装,便于理解嵌入式系统软硬协同设计全流程。 做嵌入式开发这几年,我陆陆续续做过不少基于STM32的小项目,但真正让我觉得“做了一个完整产品”而不是“点亮一颗LED”的,是这个智能仓储环境监测系统。它不是一个DEMO,而是一套能实际放进仓库里跑起来、能持续记录数据、能联动风机和加热器、还能出报表的完整设备。如果你的工作或毕业设计正好需要做类似的环境监测类项目,这篇文章应该能帮你省下至少两三个月的踩坑时间。
这套系统的核心功能一句话就能讲清楚:围绕STM32做主控,采集仓库里的温湿度、烟雾浓度、光照强度,通过LCD实时显示,支持本地按键设定阈值,超限时自动控制风机、加热器、补光灯,同时把数据通过ESP8266上报到上位机或云平台。硬件上有传感器、执行器、显示器、通信模块,软件上有嵌入式驱动、状态机、协议解析、任务调度,算是把嵌入式开发里最常见的知识点都串起来了。不管你是想学STM32实战的初学者,还是准备参加电赛/做毕设的学生,这套方案都值得完整看一遍。
1. 系统整体设计与方案选型
1.1 设计思路:先想清楚要采集什么、控制什么
我一般接到一个项目不会先画电路板,而是先把系统拆成几个功能块:感知层、控制层、执行层、交互层、通信层。感知层就是各种传感器,负责“摸环境”;控制层就是STM32主控,负责“做决策”;执行层是继电器、风扇、加热器这些“干活的东西”;交互层是屏幕、按键,负责“让人知道状态”;通信层负责“把数据传到别的地方”。这种分层思维对后面的代码组织、硬件接线、问题排查都有好处。
具体到这个项目,仓库环境监测最核心的参数有三个:温湿度(影响货物存储条件,比如电子元器件怕潮、纸制品怕火)、烟雾浓度(火灾预警)、光照强度(避免阳光直射某些敏感物资,也用于智能补光)。执行端的逻辑也很直白:温度过高开风扇,湿度过大开除湿器或加热器,烟雾超标声光报警并打开排烟风机,光照不足自动补光。这套逻辑在代码里就是几个if判断,但对应的硬件接线和驱动设计,才是工作量的大头。
1.2 主控选型:为什么选STM32F103C8T6
主控我选了STM32F103C8T6,这颗芯片在嵌入式圈子里几乎人手一颗。有人可能会问,现在STM32F4、H7都出来了,为什么不选更强的?原因很简单:这个项目的负载完全用不到F4级别的算力,而F103的资源恰好覆盖所有需求。它有64KB Flash、20KB RAM,三个USART、两个I2C、两个SPI、一个ADC,12个通道,足够驱动两个传感器(I2C的SHT30和模拟量的MQ135)、一个OLED显示屏(I2C或SPI)、一个ESP8266(USART1)、一个按键模块(GPIO)、两个继电器(GPIO)和一路蜂鸣器(PWM)。
从性价比角度说,C8T6的国产替代版(比如GD32F103、MM32F103)现在几块钱就能拿到,资料却和ST原厂互通,拿来做产品验证或者学生项目都极其合适。而且F103系列的资料多、例程全,遇到任何奇怪问题,基本都能在网上找到别人的解决方案,这对开发效率的提升是实打实的。
1.3 传感器与执行器选型
传感器选型是我在这个项目里比较纠结的部分,因为传感器直接决定了数据的可靠程度。先说说温湿度。DHT11太粗糙(精度±2度,湿度±5%),做仓库监测这种需要连续记录数据的场景不太够看;我最后选了SHT30,I2C接口,精度±0.3度、湿度±2%RH,价格也就几块钱,同系列的SHT31、SHT35可以通过替换焊盘兼容。如果你手头只有DHT11,也不是不能用,但数据曲线会丑很多。
烟雾传感器用的MQ135,这是一个经典的气体传感器,对烟雾、甲醛、苯都有响应,输出模拟电压。它的特点是便宜、灵敏度可调,缺点是需要预热、非线性和温漂。后面我会详细讲怎么标定。光照传感器用的BH1750,也是I2C接口,直接输出勒克斯(Lux),不用自己做复杂的换算。
执行器方面,我用了两个5V继电器模块,一个控制排风扇,一个控制加热器/除湿器,另外加了一个无源蜂鸣器做声光报警。继电器模块用光耦隔离,STLINK或调试器供电建议和继电器电源分开,不然电机一启动,单片机可能直接复位。这里踩过坑,后面会细说。
2. 硬件电路与接线细节
2.1 STM32最小系统与调试接口
很多新手刚开始喜欢买一块现成的开发板,这没错,但如果你要做实际部署,开发板占地方又贵,到最后还是要画一块自己的板子。这个项目我用的是自己打的PCB,核心电路就那几个部分:电源(5V转3.3V)、晶振(8M)、复位电路、SWD调试口、BOOT配置。
调试口我强烈建议引出SWD而不是JLINK的20针接口,只用SWIO、SWCLK、GND三个脚就能下载和调试,省IO还省空间。但这里有一个坑必须提醒:如果SWD引脚被复用成其他功能,或者程序里不小心禁用了JTAG/SWD,下过一次程序后,第二次可能就下载不进去了。网上搜“STM32禁用JTAG”会出现一堆帖子,基本都是这个问题。解决办法是按住复位键的同时点下载,在下载瞬间松开复位,或者用串口ISP方式先擦除Flash再重新烧录。我当初第一次碰到这问题的时候折腾了整整一晚,后来才明白是GPIO初始化时把SWD引脚给改了。
2.2 传感器与执行器接线方式
整个系统的接线我整理了一个表,方便你对照着做:
| 模块 | 接口类型 | STM32引脚 | 供电 | 备注 |
|---|---|---|---|---|
| SHT30温湿度 | I2C | PB6(SCL), PB7(SDA) | 3.3V | 上拉电阻4.7k |
| BH1750光照 | I2C | PB6(SCL), PB7(SDA) | 3.3V | 可软件设置地址 |
| MQ135烟雾 | ADC | PA1 | 5V | 输出经分压接ADC |
| OLED 0.96寸 | I2C | PB6(SCL), PB7(SDA) | 3.3V | 和传感器共用I2C |
| ESP8266 | USART1 | PA9(TX), PA10(RX) | 3.3V | 注意电平匹配 |
| 继电器1(风扇) | GPIO | PA4 | 5V | 光耦隔离 |
| 继电器2(加热) | GPIO | PA5 | 5V | 光耦隔离 |
| 蜂鸣器 | PWM/GPIO | PA6 | 3.3V | 低电平触发 |
| 按键 | GPIO | PA0, PA2 | 3.3V | 上拉输入 |
这里有一个很容易忽略的点:SHT30、BH1750、OLED都挂在同一组I2C总线上,地址必须错开。SHT30默认地址是0x44,BH1750是0x23,OLED是0x3C,这三个地址没有冲突,可以放心挂在一起。如果后面要加其他I2C设备,需要先查一下地址,避免冲突。
电源方面,我的做法是外部输入直流12V,经过一个MP1584降压模块降到5V,然后再用LDO(AMS1117-3.3)降到3.3V给MCU和传感器供电。继电器模块和蜂鸣器直接吃5V。需要特别注意的是,MQ135的加热电阻功率不小,发热明显,工作电流有150mA左右,如果从AMS1117取电,3.3V那一路会被拖垮,所以MQ135的5V供电要单独从降压模块走。
2.3 PCB布局经验
PCB布局上吃过几次亏,这里讲一下最关键的几条。第一,模拟地和数字地要单点连接,MQ135输出的模拟信号线尽量短,不要走直角,避免和继电器驱动线并行走长距离。第二,继电器和蜂鸣器这类感性负载,必须在两端并联续流二极管(1N4007)或RC吸收电路,否则关断瞬间的反向电动势会把单片机的GPIO打坏。第三,ESP8266的供电不能直接从MCU的3.3V引脚拉,因为WiFi发射瞬间电流能到300mA以上,电压跌落会导致模块反复重启。我给ESP8266单独放了一个AMS1117-3.3,并且并联了两个100uF的电解电容,实测稳定很多。
3. 软件架构与核心代码实现
3.1 开发环境:STM32CubeMX + HAL库 + Keil
现在做STM32开发,我强烈建议直接用STM32CubeMX生成初始化代码,再配合HAL库写业务逻辑,不要自己手动去翻寄存器了。当然,我理解还是有人喜欢标准外设库(标准库),觉得网上教程多、代码透明。但客观说,ST官方现在已经不更新标准库了,新出的芯片根本不支持。如果你是做产品而不是学单片机原理,直接上HAL库才是正路。
CubeMX里需要做的配置如下:
- RCC:HSE外部晶振8MHz
- SYS:Debug Serial Wire(SWD)
- I2C1:Standard Mode,100kHz
- ADC1:IN1单通道,连续转换模式,开启DMA循环请求
- USART1:115200-8-N-1,使能空闲中断(IDLE)
- USART2:115200,用于调试打印
- TIM2:1ms定时中断,作为系统时间基准
- FreeRTOS:CMSIS_V1接口,创建数据采集、显示刷新、通信上报三个任务
这个配置下来,CubeMX生成的代码已经帮你处理好了时钟树、GPIO初始化、DMA中断这些底层杂事,后续主要工作就集中在业务逻辑上。
3.2 ADC多通道DMA采集:别让传感器数据采集卡死CPU
这个项目里,ADC采集我用了两个通道:PA0采集MQ135烟雾电压,PA1采集一个NTC热敏电阻分压作为备用测温。一开始我直接用阻塞方式轮询ADC,发现只要采集一启动,主循环就卡住几百微秒,显示刷新、按键扫描全都不流畅。后来改成ADC多通道+DMA循环采样,效果立竿见影。
具体配置流程是这样的:在CubeMX里把ADC1的两个通道的采样时间拉长到239.5周期,开启Scan Conversion Mode和Continuous Conversion Mode,然后使能DMA的Circular模式,数据宽度都是Half Word(16位),内存地址递增。DMA的Buffer长度设为2,对应两个通道。
因为DMA是循环模式,硬件会持续把ADC转换结果搬运到内存数组里,CPU完全不用介入。需要读数据时,直接从数组里取最新值就行。比如:
uint16_t adc_buf[2] = {0}; // 在while循环里读最新数据 uint16_t mq135_raw = adc_buf[0]; uint16_t ntc_raw = adc_buf[1];注意,在CubeMX里CIRCULAR模式的DMA,HAL库会自动维护一个半传输和全传输中断,你可以利用这两个中断做双缓冲,但我这个数据量很小,直接循环读数组就够了,不需要额外处理。
3.3 串口空闲中断:接收ESP8266回传的不定长数据
串口接收不定长数据,是STM32开发里非常经典的问题。以前用标准库的时候,很多人都是一次接收一个字节到数组里,然后靠定时器或自定义协议判断一帧数据结束了没有。现在用HAL库配合空闲中断(IDLE Interrupt)可以非常优雅地解决。
思路是这样的:串口接收每产生一个字节中断,DMA就把数据搬到接收缓冲区,而空闲中断是当串口线在一段时间内没有数据传输时触发的,刚好代表“一帧数据从开始到结束”。我在USART1上使能了空闲中断,然后在中断回调函数里处理一帧完整数据:
void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t Size) { if (huart->Instance == USART1) { esp_rx_len = Size; memcpy(esp_rx_buf, esp_dma_buf, Size); esp_rx_ok = 1; HAL_UARTEx_ReceiveToIdle_DMA(&huart1, esp_dma_buf, ESP_RX_MAX_LEN); } }这个方案的核心是,我先开启一次HAL_UARTEx_ReceiveToIdle_DMA,之后所有收到的数据会通过DMA自动存到缓冲区,空闲中断一次就回调一次,Size参数就是这一帧数据的大小。处理完一帧之后,再重新开启下一次接收。
实测下来,这个方案接收ESP8266发来的不定长AT指令回包非常稳定,不会丢帧,也不会把两帧粘在一起。如果你还在用HAL_UART_Receive_IT一个字节一个字节地接,建议赶紧换掉。
3.4 传感器驱动编写:SHT30的CRC校验与MQ135的标定
传感器驱动这块,SHT30虽然I2C协议简单,但ST官方的HAL库函数有一点需要注意:SHT30读取的6个字节数据最后两位是CRC校验,很多教程里都是直接忽略校验只拿前4个字节。虽然大多数时候数据是准的,但在电磁环境复杂的仓储现场,偶尔会出现一个跳变的错误值,这时候CRC校验就很有意义了。
SHT30的CRC校验用的是CRC-8多项式0x31,HAL库自带HAL_CRC,但直接计算有点麻烦,我写了一个轻量的软件CRC:
uint8_t sht30_crc8(uint8_t *data, uint8_t len) { uint8_t crc = 0xFF; for (uint8_t i = 0; i < len; i++) { crc ^= data[i]; for (uint8_t j = 0; j < 8; j++) { if (crc & 0x80) crc = (crc << 1) ^ 0x31; else crc <<= 1; } } return crc; }MQ135的标定是个大课题。它的输出是0~5V的模拟电压,气体浓度越高电压越大,但这个关系不是线性的。网上能搜到MQ135的灵敏度特性曲线是横轴为浓度、纵轴为电阻比的曲线,实际工程里很少做精确标定,更常用的方法是用阈值判断烟雾是否超标。我在程序里先采集洁净空气中的基准电压(比如预热10分钟后读取到1.2V),然后设定一个偏移量(比如0.5V),当电压超过基准+偏移时判定为烟雾报警。这种“相对阈值法”虽然测不出绝对浓度,但作为火灾预警完全够用。
这里要特别提醒,MQ135上电后需要预热5分钟左右,输出才会稳定,所以程序里要加一个开机初始化延时,否则刚开机那两秒钟读取的数据会虚高,导致误报警。
3.5 FreeRTOS任务划分:采集、显示、上报互不阻塞
这个项目的软件架构如果全写在一个while循环里也能跑,但逻辑会变得很难维护。比如,OLED刷新需要几十毫秒,如果在这个时间里去读ADC、发串口,就会出现数据延迟或丢包。所以我用了FreeRTOS,把系统拆成几个独立任务:
| 任务名 | 优先级 | 周期 | 功能 |
|---|---|---|---|
| SensorTask | 3 | 500ms | 读取SHT30/BH1750/MQ135 |
| DisplayTask | 2 | 1000ms | 刷新OLED显示 |
| AlertTask | 4 | 事件驱动 | 超限报警与继电器控制 |
| CommTask | 1 | 2000ms | 通过ESP8266上报数据 |
任务之间通过FreeRTOS队列传递数据。SensorTask把采集结果打包成一个结构体,发送到队列;DisplayTask和CommTask分别从队列中读取数据并处理。这样采集任务不会等待显示和通信,实时性有了保证。
串口打印和显示抢资源的问题也顺便解决了,因为每个任务都有自己的数据源,不需要用同一个全局变量。这里有一条经验:FreeRTOS里任务函数的局部变量尽量用静态或动态分配,不要在任务栈里放大数组,比如char buf[512],很容易把任务栈压爆。我每个任务的栈大小都设成了256字(Word),实测足够。
4. 数据通信与上位机方案
4.1 ESP8266使用体验与TCP上报
ESP8266现在几乎是STM32联网的标准搭档,唯一的麻烦是它的AT指令模块型号众多,固件版本也乱。我用的ESP-01S,经典模块,GPIO口就两个,适合做纯透传。第一次用的时候先接USB转TTL在PC上测试,确认AT固件支持AT+CIPSTART和AT+CIPSEND,再接到STM32上。
因为STM32的USART1是3.3V电平,ESP8266也是3.3V电平,理论上可以直连。但ESP-01S的WiFi天线和走线容易引入干扰,我实际使用中碰到过不少次通信异常,最后检查发现是电源纹波太大。ESP8266的供电必须干净,我的做法是单独用一个AMS1117-3.3给它供电,并在模块附近加一个470uF电解电容和0.1uF瓷片电容组合,实测掉线率降低了很多。
STM32和ESP8266之间我用的是透传模式,STM32往USART1发JSON格式字符串,ESP8266直接转发到TCP服务器。JSON格式如下:
{"dev":"W001","t":25.6,"h":58.4,"smoke":1.35,"lux":230}服务器端我写了一个简单的Python TCP服务脚本,监听指定端口,收到数据后存MySQL并推送Web端展示。如果你不想自己写服务器,可以接巴法云、OneNET这类物联网平台,用MQTT协议上报,ESP8266刷MQTT固件就能直接连。不过如果用MQTT,STM32这边的代码需要做相应的MQTT协议打包,比TCP透传要多一点工作量。
4.2 上位机与数据可视化
做数据可视化,最省事的就是用Node-RED或者Grafana。我在本地Windows机器上装了Node-RED,弄一个MQTT Broker(Mosquitto),然后ESP8266通过MQTT发布主题warehouse/sensor,Node-RED订阅这个主题,把数据转存到InfluxDB,再用Grafana画曲线。全程都是开源工具,不花钱,效果却很像商业系统。
这里有个小的坑:ESP8266的MQTT库(PubSubClient)默认的KeepAlive是15秒,如果WiFi信号不稳定,很容易在两次心跳之间掉线,导致Server端显示“Connection Lost”。把KeepAlive调大到60秒,或者干脆在程序里加一个重连机制,掉线后自动重新连接。
4.3 报警推送:微信还是邮件?
报警推送是这个系统里比较受关注的一块。最简单粗暴的实现是让ESP8266直接通过HTTP GET请求第三方推送接口(比如Server酱、企业微信机器人)发消息到微信。这个方案的优点是实现起来只用一个HTTP请求,但缺点是依赖第三方服务,稳定性看运气。
更稳妥的方案是自建MQTT服务器,利用MQTT的遗嘱消息(Last Will and Testament)来检测设备离线。当STM32突然断电或者网络断开时,MQTT Broker会代替设备发布一条遗嘱主题,服务器端收到后立刻发报警邮件或短信。这个机制在工业级场景里比较常用,也值得在智能仓储这类项目里借鉴。
5. 常见问题与排查技巧实录
5.1 STM32延时函数卡死
这个问题的搜索结果非常多,说明大家都遇到过。我用HAL库的时候,习惯用HAL_Delay(),但这个函数在某些情况下会卡死,尤其是中断里调用HAL_Delay()的时候。原因是HAL_Delay依赖HAL_IncTick()来维护一个全局变量uwTick,而这个函数是在SysTick中断里被调用的。如果在高优先级中断里调用HAL_Delay,SysTick中断又恰好被阻塞,uwTick不再递增,延时函数就永远等不到目标值。
解决办法有两个:一是不要在中断里调用HAL_Delay,改成标志位+超时轮询;二是用DWT的Cycle Counter来做高精度延时,完全不依赖SysTick。DWT是Cortex-M3内核自带的调试单元,可以像定时器一样数CPU周期数,实现微秒级延时:
void delay_us(uint32_t us) { DWT->CYCCNT = 0; DWT->CTRL |= DWT_CTRL_CYCCNTENA_Msk; uint32_t start = DWT->CYCCNT; uint32_t ticks = us * (SystemCoreClock / 1000000); while (DWT->CYCCNT - start < ticks); }这段代码在F103上实测很稳,我后来把显示刷新和传感器读操作里的所有延时都换成了DWT版本。
5.2 ADC采样数值跳变
数值跳变是ADC应用里最典型的坑。我一开始直接用PA1读MQ135,发现数据在1.0V~1.5V之间来回跳,完全没法用。检查了硬件和软件,最终定位为两个问题:
第一,ADC参考电压不够稳定。STM32的VREF+内部连到VDDA,如果VDDA上有高频噪声,ADC结果肯定会抖。我在VDDA和VSSA之间加了LC滤波,效果立竿见影。
第二,采样时间不够长。MQ135的内阻有几十千欧,如果ADC采样时间太短,采样电容还没充满就开始转换了,误差会非常大。我在CubeMX里把采样时间从1.5周期改成了239.5周期,效果很明显。
另外,ADC结果还应该做软件滤波。我用了中位值平均滤波:连续采样10次,去掉最大最小值再求平均。处理之后的数据曲线平滑很多,也不会太迟钝。
5.3 OLED显示花屏与闪烁
0.96寸OLED在I2C模式下,偶尔会出现花屏,特别是在电机、继电器动作瞬间。排查了很久发现是电源瞬间跌落导致OLED内部控制器复位,但MCU没有复位,两边状态不一致了。解决办法是给OLED供电也加一个100uF电容,然后软件上每隔一段时间重新初始化一次OLED,比如每小时强制刷新一次初始化序列。虽然治标不治本,但能保证画面始终是正常的。
还有一个小技巧是,用I2C的OLED显示大数据量内容时,如果单次刷屏间隔太短,容易造成I2C总线拥堵。我的做法是把显示任务周期设为800ms~1s,每次只更新变化的部分(比如只刷新温湿度的数字区域),画面明显流畅了。
5.4 ESP8266通信不稳定一例
有一次客户反馈设备经常连不上服务器,我远程排查发现ESP8266经常处于“AT+CWJAP连接失败”的状态。后来过去现场才发现,仓库里有一台大功率对讲机,一发射就干扰WiFi。这个跟硬件不好没关系,纯粹是现场环境问题。解决办法是在ESP8266的电源脚上加强滤波、把天线位置抬高,并增加自动重连逻辑:每次上电先连WiFi,如果5秒没连上就重启ESP8266,再试。
另外,AT指令模式下的ESP8266有一个常见的坑:模块上电后会先输出一长串乱码式启动信息,如果你在MCU侧等待“ready”字符串再发指令,很容易因为时序问题失败。我的程序里直接用一个状态机:如果200ms内收到任何包含“OK”或“ready”的字符串,就认为模块已启动;如果收到“ERROR”或超时,就发送“AT+RST”重启模块。
6. 项目延展:从“能跑”到“好用”
6.1 增加更多传感器与执行器
这个系统的框架其实可以很容易扩展。比如仓储里要测VOC或二氧化碳,可以挂SGP30或SCD30;要测水浸,可以接一个水浸传感器到GPIO;要监测门禁状态,加一个干簧管就行了。因为主控的IO和I2C总线都有富余,我后来还加了一个GPS模块做位置定位(用于户外移动仓储箱),也是挂USART2上,和调试串口共用,只是调试时切换一下引脚复用。
6.2 本地存储:SD卡和Flash轮询记录
仓储数据讲究可追溯,光靠Grafana上的云端数据不够,断网时还需要本地存储。这块我实现了两个方案:一个是SD卡,通过SPI接口读写,文件系统用FatFS,每小时生成一个CSV文件,方便后用Excel分析;另一个是在STM32内部Flash里做一个环形缓冲区,保存最近24小时的关键数据,掉电不丢失。内部Flash方案更简单,不需要外挂硬件,但容量有限,只能存关键告警数据而不是全量数据。
6.3 低功耗与电池供电
如果你需要在没有外部电源的仓库里部署,低功耗设计就绕不开。STM32F103有STOP模式,可以把整体功耗降到微安级别。我的做法是:MCU默认进入STOP模式,靠RTC闹钟每5分钟唤醒一次,唤醒后采集数据、发送报文、再回STOP。传感器这边,SHT30本身有单次测量模式,也支持掉电模式,MQ135的加热电阻功耗大,只能从硬件上通过MOS管开关控制,测量时再通电。这样整体下来平均功耗能控制在10mA以内,用18650电池加太阳能板就能维持数周。
7. 写在最后的几点实战心得
做完这个项目之后,我最大的体会是:STM32项目真正做到最后,难的不是单片机本身,而是传感器数据怎么采集干净、通信怎么稳定、现场问题怎么排查。如果你正在做一个类似的项目,建议你在前期就把电源设计、传感器标定、通信协议结构想清楚,这几个地方一旦出问题,后面改起来成本非常高。
最后再分享一个小技巧:调试阶段不要直接上FreeRTOS,先在裸机while循环里把所有外设调通,再切换到RTOS。这样能大幅降低出bug排查的复杂度。等你把裸机版本跑通了,再引入任务划分、队列通信,整个系统会清晰很多。
这套系统到现在我已经迭代了三版,从最初的面包板飞线,到现在两层PCB加外壳,已经在朋友的一个小型零配件仓库里稳定运行了三个多月,只出现过两次ESP8266掉线自动重连的情况,其余时间都运行正常。它的硬件成本加起来不到两百块,却解决了一个需要专人每天跑几趟仓库去查看温湿度、检查烟雾报警的痛点。我觉得这种“花小钱解决真实问题”的嵌入式项目,才是STM32最具魅力的应用场景。
本文还有配套的精品资源,点击获取