拓冰建站拓冰建站
首页 / 资讯中心 / 正文

STM32+ESP8266+OneNET+小程序,手把手搭建厨房烟雾监测物联网系统

厨房是家庭用水用电和燃气最集中的区域燃气泄漏、烟雾超标、忘关灶火这类隐患靠传统烟感报警器只能解决本地提醒无法在主人不在家时及时推送。基于 STM32 的厨房安全监测系统就是把传感器检测、MCU 逻辑控制、Wi-Fi 上云、手机小程序展示串联成一个完整物联网项目既能作为毕业设计、电子设计大赛作品也能扩展成真正可用的家庭安防设备。这篇文章按一条完整的技术主线展开STM32 读取烟雾传感器数据通过 ESP01SESP8266 的 AT 固件版本连上 OneNET 物联网平台再把数据用微信小程序展示出来同时保留本地蜂鸣器报警和按键控制。整个方案包含硬件连接、MCU 编程、平台配置、小程序开发、PCB 设计五块内容每一块都会给出可复现的代码或配置。先说明适合哪些读者正在准备物联网方向毕业设计的学生、打算参加电子设计竞赛或计算机设计大赛的团队、想从单片机裸机开发进入物联网项目开发的工程师。你把本文的结构和代码消化之后能独立搭出一套“传感器采集 MCU 处理 Wi-Fi 上云 手机端展示”的最小物联网系统。1. 系统技术架构从传感器到小程序的完整数据链路1.1 一条数据要经过哪些环节才能显示到手机整个系统的数据链路并不复杂但每一环都决定了后面能不能跑通。传感器端先由 MQ-2 或同类模拟量烟雾传感器输出一个随气体浓度变化的电压信号STM32 通过 ADC 把电压信号转成数字量做滤波和阈值判断之后把处理结果拼成约定格式的数据帧通过串口发给 ESP01S。ESP01S 内部运行的是乐鑫出厂 AT 固件它负责两件事一是连接家庭路由器二是通过 MQTT 协议与 OneNET 服务器建立长连接。数据到达 OneNET 之后平台侧会解析并保存设备上传的数据点微信小程序再通过云开发中间层调用 OneNET 的开放接口读取设备最新数据并渲染到页面上。反向链路同样重要。当平台下发命令时小程序的请求先到 OneNETOneNET 通过 MQTT 长连接把消息推给 ESP01SESP01S 收到 AT 指令后通过串口转发给 STM32STM32 再执行继电器断电、蜂鸣器消音、LED 切换等动作。用一句话概括数据上行用 MQTT命令下行也用 MQTTMCU 和 Wi-Fi 之间只通过串口沟通。1.2 核心器件选型为什么是 STM32、ESP01S、OneNET、小程序这套方案并不是唯一选择但作为毕业设计和竞赛作品它有很明显的综合优势。组成选择选择理由常见替代主控 MCUSTM32F103C8T6Cortex-M3 内核12 位 ADC资源多资料丰富采购和焊接成本低STM32F407、GD32F103、APM32F103无线模块ESP-01S体积小出厂带 AT 固件开发阶段可以不写 Wi-Fi 固件减少工作量ESP-12F、ESP32-S3、Air724 4G 模块云平台OneNET国内服务器访问速度快物联网平台提供设备管理、数据存储、API 查询阿里云 IoT、腾讯云 IoT、EMQX 私有化手机端微信小程序免安装开发周期短云开发能省去自建后端服务器Uni-App、H5、Android App烟雾传感器MQ-2模拟输出直接接 ADC响应速度快价格低教材案例多MQ-135、MH-Z19 二氧化碳传感器从学习角度讲这套组合覆盖了嵌入式开发中最关键的几个能力点寄存器与外设库编程、ADC 采样、串口通信、AT 指令解析、MQTT 协议、云平台 API 调用、小程序前后端开发。从竞赛答辩角度讲它既有硬件实物又有云平台数据还有手机端展示系统完整度足够。1.3 开发工具与版本准备开始写代码之前先把工具链准备好。下面的工具清单是最小集合不涉及额外插件工具用途说明Keil MDK5编写和编译 STM32 工程建议用 5.30 以上版本兼容 F1 系列STM32CubeMX初始化引脚和时钟不是必须但能减少配置错误USB 转 TTL 模块给串口调试或给 ESP01S 发 AT 指令需要支持 3.3V 电平常见 CH340 模块串口调试助手查看 STM32 打印、ESP01S 回复XCOM、SSCOM 均可微信开发者工具编写和预览小程序需要注册小程序账号嘉立创 EDA 或 Altium Designer设计 PCB新手优先用嘉立创 EDA 国产工具实际开发时先用面包板和杜邦线验证整个链路再画 PCB 打样这样做能避免“电路图画错了直接做板子”的高成本返工。2. 硬件准备与电路连接2.1 元器件清单整个系统硬件成本不高核心元件集中在传感器、Wi-Fi 模组和主控上。元器件清单如下元器件规格/型号数量用途MCU 主控STM32F103C8T6 最小系统板1主控制器运行采集与逻辑代码烟雾传感器MQ-2 模拟输出模块1检测烟雾和可燃气体浓度Wi-Fi 模组ESP-01S出厂 AT 固件1连接路由器并接入 OneNET电源芯片AMS1117-3.3V15V 转 3.3V 给 MCU 和 Wi-Fi 供电蜂鸣器有源蜂鸣器1本地声光报警三极管S8050 或 D8821驱动蜂鸣器按键轻触开关2报警消音与测试触发LED红色、绿色各 1 个2状态显示电容0.1uF、10uF、100uF若干电源去耦和滤波连接排针2.54mm 排针/端子若干外接传感器和模块注意MQ-2 模块如果购买的是“带比较器输出”的版本它同时有模拟输出 AOUT 和数字输出 DOUT。本系统只用模拟输出把 DOUT 悬空即可。2.2 STM32 与外围模块的引脚连接关系下面是一套验证过的引脚分配方案使用 STM32F103C8T6 的 USART1 与 ESP01S 通信使用 ADC1 的通道 1 读取 MQ-2 模拟量。STM32 引脚功能连接的模块说明PA1ADC1_IN1MQ-2 模块 AOUT烟雾浓度模拟量输入PA9USART1_TXESP01S 的 RXSTM32 发送 AT 指令PA10USART1_RXESP01S 的 TXSTM32 接收 ESP01S 回复PB12普通 GPIO 输出蜂鸣器驱动三极管基极高电平触发报警PB13普通 GPIO 输入消音按键按键按下时关闭报警PB14普通 GPIO 输入测试按键模拟烟雾触发流程3.3V电源ESP01S VCC、CH_PDCH_PD 必须接高电平GND电源地所有模块共地通信必须共地这里有一个新手容易忽略的坑ESP01S 的 VCC 只支持 3.3V不能接 5V。很多开发板引出 3.3V 之后电流能力有限而 ESP01S 在射频发射瞬间电流可能冲到 300mA 左右如果电源设计不好会出现 Wi-Fi 反复重启、AT 指令无响应的问题。2.3 供电与最小系统设计STM32F103C8T6 最小系统板通常自带 3.3V LDOCPU 主频设为 72MHz使用 8MHz 外部晶振。如果采用自制 PCB 方案最小系统必须包含8MHz 晶振负载电容选 10pF 到 22pF具体值按照晶振规格书配置NRST 复位电路10K 电阻上拉0.1uF 电容到地BOOT0 下拉到地从 Flash 启动3.3V 电源去耦电容靠近 VDD 引脚放置SWD 下载接口SWDIO 和 SWCLK 引出方便烧录和调试注意ESP01S 和 STM32 都是 3.3V 逻辑可以直接用串口连接。但如果 STM32 板子上有 5V 引脚不要把 5V 接到 ESP01S 上否则会烧掉模组。3. STM32 端程序实现传感器读取、阈值判断与串口发送3.1 工程结构与基础初始化先按标准库组织工程包含延时、串口、ADC、GPIO 四个模块。如果你用 CubeMX 生成可以省去人工建工程的时间但核心代码逻辑一样。工程内至少要有以下文件Project/ ├── User/ │ ├── main.c │ ├── delay.c │ └── usart.c ├── HARDWARE/ │ ├── adc.c │ ├── smoke.c │ ├── alarm.c │ └── esp01s.c └── STM32F10x_FWLib/ └── 标准外设库在 main.c 里初始化顺序是系统时钟、延时函数、串口、ADC、GPIO、ESP01S。先初始化时钟再操作外设这是 STM32 开发的基本纪律。3.2 烟雾 ADC 采样与滑动滤波MQ-2 传感器通电后需要预热前几十秒读到的值会一直漂移。程序里不要直接用单次采样值做判断必须做滤波处理。这里给出一个基于标准外设库的 ADC 初始化与读取函数#include stm32f10x.h #include delay.h #include usart.h #define SMOKE_ADC_PORT GPIOA #define SMOKE_ADC_PIN GPIO_Pin_1 #define SMOKE_ADC_CHANNEL ADC_Channel_1 static uint16_t smoke_filtered 0; void Smoke_ADC_Init(void) { GPIO_InitTypeDef gpio_init; ADC_InitTypeDef adc_init; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_ADC1, ENABLE); gpio_init.GPIO_Pin SMOKE_ADC_PIN; gpio_init.GPIO_Mode GPIO_Mode_AIN; GPIO_Init(SMOKE_ADC_PORT, gpio_init); adc_init.ADC_Mode ADC_Mode_Independent; adc_init.ADC_ScanConvMode DISABLE; adc_init.ADC_ContinuousConvMode DISABLE; adc_init.ADC_ExternalTrigConv ADC_ExternalTrigConv_None; adc_init.ADC_DataAlign ADC_DataAlign_Right; adc_init.ADC_NbrOfChannel 1; ADC_Init(ADC1, adc_init); ADC_Cmd(ADC1, ENABLE); ADC_ResetCalibration(ADC1); while (ADC_GetResetCalibrationStatus(ADC1)); ADC_StartCalibration(ADC1); while (ADC_GetCalibrationStatus(ADC1)); } uint16_t Smoke_ADC_GetRaw(void) { ADC_RegularChannelConfig(ADC1, SMOKE_ADC_CHANNEL, 1, ADC_SampleTime_55Cycles5); ADC_SoftwareStartConvCmd(ADC1, ENABLE); while (ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC) RESET); return ADC_GetConversionValue(ADC1); } uint16_t Smoke_ADC_GetFiltered(void) { if (smoke_filtered 0) { smoke_filtered Smoke_ADC_GetRaw(); } else { /* 一阶低通滤波当前值占 70%历史值占 30% */ smoke_filtered (uint16_t)(Smoke_ADC_GetRaw() * 0.7f smoke_filtered * 0.3f); } return smoke_filtered; }这段代码里最值得注意的就是滤波函数。如果不滤波MQ-2 的 ADC 值会在正常空气环境中上下跳几十甚至上百阈值判断很容易误报。一阶低通滤波实现简单计算量低适合 F1 系列这种主频不高但做单通道采样绰绰有余的场景。3.3 串口发送数据给 ESP01SSTM32 和 ESP01S 之间用字符串通信。为了让 OneNET 和小程序容易解析统一使用简化 JSON 格式。发送内容包括烟雾 ADC 值、滤波后的值、报警状态#include stdio.h #include string.h void Send_Data_To_ESP01S(uint16_t smoke, uint8_t alarm_state) { char buf[64] {0}; sprintf(buf, {\smoke\:%d,\alarm\:%d}\r\n, smoke, alarm_state); /* 这里通过串口 1 发送实际项目中可以封装成 uart_send_string */ for (uint16_t i 0; i strlen(buf); i) { while (USART_GetFlagStatus(USART1, USART_FLAG_TXE) RESET); USART_SendData(USART1, (uint8_t)buf[i]); } }注意ESP01S 的 AT 指令要求以\r\n结尾但这里发送的是数据帧不是 AT 指令所以协议里自定义以\r\n作为一帧数据的结束标志。STM32 端把数据发给 ESP01S 后ESP01S 并不解析 JSON它只负责把收到的串口数据作为 MQTT 消息上报到 OneNET解析工作由 OneNET 云平台完成。3.4 报警输出与按键处理报警逻辑放在主循环中。阈值需要根据你的实际传感器和安装环境现场标定没有统一标准。下面给出一套可运行的判定流程#define SMOKE_THRESHOLD 1800 #define ALARM_DURATION_MS 3000 void Alarm_Process(uint16_t smoke) { static uint32_t alarm_start_time 0; if (smoke SMOKE_THRESHOLD) { if (alarm_start_time 0) { alarm_start_time Get_Tick(); } if (Get_Tick() - alarm_start_time ALARM_DURATION_MS) { GPIO_SetBits(GPIOB, GPIO_Pin_12); } else { GPIO_ResetBits(GPIOB, GPIO_Pin_12); } } else { alarm_start_time 0; GPIO_ResetBits(GPIOB, GPIO_Pin_12); } }这里做了两个关键设计报警持续 3 秒后自动停止避免蜂鸣器一直响影响体验按键消音逻辑只要把报警状态位清掉并在状态报文里把 alarm 字段置 0 即可。实际项目中还可以加入“首次报警必须手动确认”的模式避免危险状态下自动静音。4. OneNET 平台配置与 ESP01S 接入4.1 在 OneNET 控制台创建产品和设备OneNET 平台的使用流程比较固定但控制台的细节会根据版本调整所以文章里不写死按钮位置只描述核心步骤和需要记录的信息。第一步注册并登录 OneNET 平台进入控制台。第二步创建产品时协议选择 MQTT接入方式选择“设备直连”。第三步在产品下添加设备设备名称自行命名比如kitchen_device_01并记下产品 ID、设备 ID、APIKey 或鉴权信息。创建完成后平台通常会提供一组 MQTT 连接参数包括参数示例说明MQTT 服务器地址控制台页面显示的地址旧版 OneNET 常见为 mqtts.heclouds.com 或 IPMQTT 端口1883非加密端口产品 ID控制台分配的一串数字或字符串用于标识产品设备名称kitchen_device_01设备唯一标识APIKey/鉴权信息控制台生成的密钥连接时作为密码字段注意OneNET 不同版本对 MQTT 接入参数的格式要求不一样。动手连接之前先去产品概览页查看官方给出的接入示例以控制台显示为准。4.2 ESP01S 进入 AT 模式并联网ESP01S 出厂时已经烧录 AT 固件上电后默认进入 AT 命令模式。用 USB 转 TTL 模块连接 ESP01STX 接模块 RXRX 接模块 TX共地VCC 和 CH_PD 接 3.3V。打开串口调试助手波特率通常选 115200发送下面的命令AT返回OK表示 AT 固件正常。然后配置为 Station 模式并连接家庭路由器ATCWMODE1 ATCWJAP你的WiFi名称,你的WiFi密码连接成功后先不急着做 MQTT确认 ESP01S 能获取到局域网 IPATCIFSR这一步能看到 ESP01S 的 IP 地址比如192.168.1.100。如果看不到 IP说明 Wi-Fi 连接失败先检查路由器名称、密码、频段。ESP-01S 只支持 2.4GHz Wi-Fi不支持 5GHz。4.3 MQTT 接入 OneNET 的 AT 指令流程ESP01S 的 AT 固件从较高版本开始支持ATMQTTUSERCFG和ATMQTTCONN可以将 MQTT 客户端配置集成在模组内部。接入 OneNET 时典型流程是ATMQTTUSERCFG0,1,产品ID或用户名,APIKey或鉴权密码,,0,0, ATMQTTCONN0,tcp://mqtt服务器地址:1883,1命令里的参数含义参数作用第一个 0选择 TCP 连接 ID一般固定为 0第二个 1启用 MQTT 功能用户名按 OneNET 平台要求填写产品 ID密码填写 APIKey 或设备鉴权信息服务器地址端口必须与平台控制台一致连接成功后串口会返回OK再手动查询连接状态ATMQTTCONN?如果返回MQTTCONN: 0,1表示连接成功。出现连接失败时优先检查用户名、密码、服务器地址是否与控制台一致其次检查 ESP01S 是否已经拿到局域网 IP。4.4 数据点上报与命令下发格式OneNET 平台通过 MQTT 主题区分不同用途。设备上报数据的主题和下发命令的主题在控制台接入文档中会明确写出不同版本可能有所区别。以旧版 OneNET MQTT 为例发布数据的常见方式是把数据作为 UTF-8 字符串发布到设备数据主题内容使用 JSON 格式{smoke:1024,alarm:0}STM32 发送给 ESP01S 的串口数据帧已经和这个 JSON 格式对齐所以 ESP01S 可以一边通过串口接收数据一边用ATMQTTPUB发布到平台ATMQTTPUB0,设备数据主题,{\smoke\:1024,\alarm\:0},1,0命令中最后一个1表示 QoS1保证消息至少送达一次。0表示不保留消息。命令下发时OneNET 通过 MQTT 发布消息给设备端ESP01S 收到平台推送后会在串口输出类似数据MQTTDATA或MQTTSUBRECV开头的报文。STM32 在串口中断里识别这些前缀再从字符串中提取命令内容执行对应动作。5. 微信小程序端开发5.1 小程序整体页面结构小程序端不直接保存 OneNET 的 APIKey原因是小程序代码运行在用户手机上密钥一旦内置任何人反编译都能拿到安全性很差。推荐做法是用微信云开发作为中间层小程序调用云函数云函数再请求 OneNET 开放 API。小程序页面结构保持精简至少包含三个区域当前烟雾浓度数值显示报警状态和最近更新时间手动刷新按钮或自动刷新机制页面数据流是小程序 JS 调用云函数云函数请求 OneNET 接口OneNET 返回设备最新数据点云函数处理后返回给小程序页面。5.2 云开发中间层的函数实现在微信开发者工具中开通云开发创建一个云函数命名为getDeviceData。云函数内部通过 HTTP 请求 OneNET 的设备数据点 API。具体请求地址和鉴权头需要参考 OneNET 开放平台文档但模式固定// 云函数 getDeviceData/index.js const cloud require(wx-server-sdk) const axios require(axios) cloud.init({ env: cloud.DYNAMIC_CURRENT_ENV }) exports.main async (event, context) { const oneNetUrl https://api.XXX.heclouds.com/devices/设备ID/datapoints const res await axios.get(oneNetUrl, { headers: { api-key: 你的APIKey }, params: { datastream_id: smoke,alarm, limit: 1 } }) const datastreams res.data.data.datastreams || [] const result {} datastreams.forEach(item { if (item.id smoke item.datapoints.length 0) { result.smoke item.datapoints[0].value } if (item.id alarm item.datapoints.length 0) { result.alarm item.datapoints[0].value } }) return result }实际部署时APIKey 不要直接写在云函数代码里可以配置到云函数的环境变量中每次调用从process.env读取降低泄漏风险。5.3 页面显示与自动刷新逻辑小程序页面 JS 采用定时刷新保证用户打开页面后能实时看到最新状态。下面是一个简化版实现// pages/index/index.js Page({ data: { smoke: 0, alarm: false, updated: --, timer: null }, onShow() { this.fetchData() this.data.timer setInterval(() { this.fetchData() }, 5000) }, onHide() { clearInterval(this.data.timer) }, fetchData() { wx.cloud.callFunction({ name: getDeviceData, data: {} }).then(res { this.setData({ smoke: res.result.smoke || 0, alarm: !!res.result.alarm, updated: new Date().toLocaleTimeString() }) }).catch(err { console.error(获取设备数据失败, err) }) } })对应的 WXML 用最简单的文本框展示数据即可不必引入复杂 UI 库view classcontainer view classvalue{{smoke}}/view view classlabel烟雾浓度 ADC 值/view view classstatus {{alarm ? danger : normal}} {{alarm ? 危险烟雾超标 : 正常}} /view view classtime更新于 {{updated}}/view button bindtapfetchData手动刷新/button /view这样小程序端就完成了一个最小闭环每 5 秒请求一次云函数云函数从 OneNET 拉取最新数据点页面实时更新数值和报警状态。开发者在真机预览前需要在微信公众平台配置域名白名单放行 OneNET API 所在域名。6. PCB 设计与打样要点6.1 电源电路与去耦电容布置自制 PCB 时最先设计的应该是电源部分而不是 MCU 引脚。电源设计不合理后续调试会浪费大量时间。整套系统只需要一路 5V 外部输入。5V 经过 AMS1117-3.3 稳压到 3.3V供 MCU 和 ESP01S 使用。AMS1117 手册要求输入输出端都要有电容输入端放置 10uF 电解电容输出端放置 10uF 钽电容或直插电容并在 AMS1117 附近的 3.3V 和 GND 之间并联 0.1uF 陶瓷电容。ESP01S 射频瞬间电流较大建议在 ESP01S 的 VCC 引脚就近放置一个 100uF 电解电容和一个 0.1uF 陶瓷电容防止模组工作瞬间拉低 3.3V 电压。如果 PCB 面积允许电源走线尽量加宽至少 1mm过孔数量也要充足减少压降。6.2 布局布线中的关键规范针对这个项目有五条布局布线规范必须遵守第一晶振走线要短。8MHz 晶振尽量靠近 STM32 的 OSC_IN 和 OSC_OUT 引脚晶振下方不要铺其它信号线电容靠近晶振放置。第二ESP01S 天线区域净空。ESP01S 板载 PCB 天线附近不要布铜、不要放置金属件、不要走平行长线否则会明显衰减 Wi-Fi 信号。第三模拟地与数字地分开处理。MQ-2 输出的是模拟信号如果 ADC 采样值波动异常很可能是数字电路噪声通过地线串入了模拟部分。设计时可以用 0 欧电阻或磁珠把模拟地和数字地单点连接。第四按键和蜂鸣器加保护。蜂鸣器是感性负载S8050 三极管集电极要并联一个续流二极管防止关断瞬间产生反向感应电压损坏三极管和 MCU。第五预留测试点。SWD 下载接口、串口 TX、串口 RX、ADC 采样脚都要引出排针或测试点方便软件调试。不要做出一块无法调试的“黑盒子”板子。6.3 生成生产文件与焊接顺序使用嘉立创 EDA 完成原理图和 PCB 之后检查设计规则检查确认没有未连接的引脚导出 Gerber 文件后再下单打样。首次打样建议数量控制在 5 到 10 片成本不高万一改版也不心疼。焊接顺序建议从电源开始先焊 AMS1117 及电容上电测量 3.3V 是否正常再焊 STM32 最小系统用 ST-Link 连接 SWD测试程序下载确认 MCU 能跑通流水灯之后再焊传感器、蜂鸣器、按键最后焊 ESP01S 座子插上模组做网络调试。这样分段焊接的好处是每焊一层就测试一层问题定位范围被限制在很小的区间里。7. 系统联调与验证7.1 按阶段验证的六个检查点整套系统联调时不要直接打开全部设备要按阶段逐个验证。下面是一个推荐顺序阶段验证内容检查方法1STM32 程序运行下载程序后串口能输出测试信息2烟雾传感器采样对着 MQ-2 喷少量烟雾或打火机气体串口 ADC 值明显上升3ESP01S AT 联网串口发送 AT 指令返回 OK能查到 IP4OneNET 设备上线平台控制台显示设备在线5数据点上报OneNET 数据流中能看到 smoke 值变化6小程序展示手机小程序显示和小程序本一致的数值完成前五步说明 MCU、Wi-Fi、平台这条链路是通的。第六步上线后项目核心功能就算全部完成。7.2 正常联调时的预期现象整个系统正常工作时可以看到一组稳定的数据链路现象STM32 串口每隔 1 到 2 秒输出一行 JSON{smoke:412,alarm:0}ESP01S 模组上的蓝色 LED 闪光频率与数据上报频率一致OneNET 控制台设备状态为在线数据流中不断有新的数据点写入小程序页面每 5 秒刷新一次显示数值与串口输出的 smoke 值基本一致用打火机放气或点燃少量纸张靠近 MQ-2ADC 值明显上升超过阈值后蜂鸣器鸣响小程序 alarm 显示为危险状态如果其中任何一环的数据对不上不要急着修改代码先确认上游数据是否正常。比如小程序显示数值异常先看 OneNET 控制台里的数据点是否正确OneNET 数据不对先看 ESP01S 收到的串口数据是什么。只有从上游往下游逐级排查才能准确找到断点。7.3 学习环境与生产环境的差异学习环境下使用 USB 供电、面包板飞线、手动重启设备都可以接受。但如果要把这套系统放到生产或比赛现场长期运行必须补齐三块内容场景学习环境生产/比赛环境供电USB 转 TTL 供 5V独立 5V 电源适配器输入输出带保护连接杜邦线、面包板焊接 PCB插件压紧外观完整稳定性手动重启STM32 内部看门狗自动复位MQTT 断线重连数据安全APIKey 写在代码里云函数环境变量或服务端保存密钥比赛或展示环境中还建议打印一个外壳把 PCB、传感器、电源模块装进去只露出 MQ-2 进气孔和按键。实物观感会直接影响答辩和演示评分。8. 常见问题排查从现象定位根因8.1 STM32 程序下载与运行问题项目过程中最常见的报错是下载程序时出现类似Error: Target not found或No STM32 Target Found的提示。这个现象的原因通常不是芯片坏了而是下载器根本没有与芯片建立连接。优先检查四个位置SWDIO 和 SWCLK 是否接反在 ST-Link 上SWDIO 接芯片 SWDIOSWCLK 接芯片 SWCLK数据线和时钟线不能交换目标板是否供电ST-Link 的 3.3V 输出电压能力很弱如果板子功耗较大要单独供电BOOT0 是否被拉高如果 BOOT0 处于 1 状态芯片会进入系统存储器模式Flash 程序不会被运行下载器驱动是否安装Keil 中能识别到 ST-Link 设备但不能保证驱动正常。问题现象常见原因处理建议No STM32 Target FoundSWDIO/SWCLK 接反或接触不良重新核对线路检查杜邦线是否松动程序下载成功但板子无反应时钟配置错误或 BOOT0 拉高检查 BOOT0 是否接 GND检查晶振是否起振上电后 ADC 读数为 0 或 4095MQ-2 模块供电异常或 AOUT 没接对用万用表测量 AOUT 电压是否随浓度变化串口打印乱码波特率不匹配或共地缺失STM32 和 USB 转 TTL 必须共 GND8.2 ESP01S 与 OneNET 连接问题ESP01S 出现 AT 指令无响应时先检查供电电压。用万用表在 ESP01S 的 VCC 和 GND 之间量电压如果低于 3.2V很可能是电源带载能力不足。解决办法是在 3.3V 和 GND 之间并联 100uF 电容或者改用单独的 3.3V 线性稳压芯片给 ESP01S 供电。设备一直连不上 OneNET 时按这条链路排查AT 指令是否返回 OK不返回则先处理串口接线和电源。ATCWJAP是否连接路由器成功失败则确认 Wi-Fi 频段是否为 2.4GHz密码是否正确。ATCIFSR是否拿到 IP拿不到说明 STA 模式配置有问题。ATMQTTCONN是否连接成功失败则检查用户名、密码、服务器地址和端口。连接成功后 MQTT 掉线则检查 MEAN 信号强度ESP01S 天线区域是否被金属遮挡。实际上 OneNET 连接失败的很大比例不是协议写错而是用户名密码字段填错位置或者平台新旧版本鉴权规则变化。遇到这类问题先从控制台复制官方示例逐字对比命令再排查。8.3 数据上报与小程序显示问题OneNET 平台数据点没有新增时先确认 ESP01S 是否确实执行了发布命令。如果串口里能看到发布后返回OK但平台端没数据大概率是主题名或 JSON 格式不匹配。OneNET 对数据格式要求严格字段名要和平台定义的数据流名称一致数据值类型也要匹配不要把字符串发到整数数据流里。小程序显示不出来时优先级最高的问题是小程序能不能访问 OneNET 的接口。开发阶段可以在微信开发者工具里勾选“不校验合法域名”但如果要发布上线必须在微信公众平台后台的一级域名白名单中配置 OneNET 接口域名。另外一个隐蔽问题是云函数环境变量没有正确配置APIKey 为空时请求会 401 报错。问题现象可能原因检查方式解决方案OneNET 有数据但小程序显示为 0小程序取错数据流 ID 或字段名查看云函数返回结果统一 smoke/alarm 字段命名小程序真机访问失败域名未加白名单查看控制台网络请求报错配置 request 合法域名云函数调用超时OneNET API 响应慢查看云函数日志设置合理超时时间失败时重试一次上报数据平台显示异常JSON 转义错误用串口抓取 ESP01S 发布内容核对字符串转义打印完整报文8.4 报警逻辑不触发问题报警不触发先确认是采样值没超过阈值还是阈值判断后没有执行报警动作。把 STM32 串口打印出来的 smoke 值和程序里的 SMOKE_THRESHOLD 对比这是最快定位方法。如果 smoke 值已经高于阈值但蜂鸣器不响检查 PB12 引脚是否被配置成输出模式三极管基极串联电阻是否在 1K 到 10K 之间蜂鸣器正负极是否接反。有源蜂鸣器只有正负极正确时才会鸣响无源蜂鸣器还需要 MCU 输出一定频率的方波信号不能用简单的 GPIO 高电平驱动。这个坑出现在很多竞赛作品里焊接前先确认自己用的是有源还是无源蜂鸣器。9. 项目包装、扩展与练习建议9.1 面向毕业设计和大赛的功能扩展当前版本已经是一个完整最小系统但毕业设计和大赛答辩通常需要更多功能亮点。建议按优先级扩展第一加入本地显示。用 OLED 屏幕显示当前烟雾值、报警状态、Wi-Fi 连接状态和平台在线状态现场演示时不用依赖手机和电脑展示感更强。第二加入继电器联动。当烟雾超标时STM32 控制继电器切断燃气电磁阀或排风扇电源形成“本地报警 远程通知 自动处置”的完整闭环。第三加入历史数据存储和趋势图。OneNET 自带数据存储能力小程序端可以通过 API 拉取一段时间内的数据绘制曲线图体现数据分析能力。第四加入多传感器融合。在厨房场景中补充温湿度传感器 DHT11 或 SHT30、火焰传感器、人体红外传感器形成更完整的厨房安全监测矩阵。9.2 代码健壮性与可维护性建议把代码从“能跑”提升到“稳”需要做三件事。第一引入看门狗。STM32 程序中加入独立看门狗主循环里定期喂狗一旦程序卡死或死循环芯片自动复位恢复。这对无人值守的厨房监测场景非常重要。第二MQTT 断线重连。ESP01S 掉线后不能只靠用户手动重启STM32 要在串口收到异常连接状态时主动重新执行 ATCWJAP 和 ATMQTTCONN恢复网络。第三数据发送节奏控制。烟雾检测周期建议 1 秒一次但上报到 OneNET 的频率不需要那么高可以 5 秒或 10 秒上报一次降低平台流量消耗和 ESP01S 功耗。代码结构上不要把 AT 指令字符串散落在主循环里建议把 ESP01S 操作封装成独立的模块对外只提供ESP01S_Init()、ESP01S_SendData()、ESP01S_SendCommand()三个接口。这样更换云平台或更换 Wi-Fi 方案时只需要改一个文件。9.3 练习建议与下一步方向如果这是你第一个物联网项目重点练习串口数据解析把 ESP01S 的MQTTSUBRECV报文读懂理解 MCU 如何从一堆字符串中提取有效命令。串口通信是物联网嵌入式开发中最值得花时间的底层能力。如果已经能跑通全部功能下一步建议研究 MQTT 协议的 QoS 语义。本项目中 QoS1 意味着消息至少送达一次但可能出现重复消息STM32 端如何做消息去重是进阶必学内容。如果目标是做出产品级设备则要把目光放在低功耗、OTA 升级、设备生命周期管理上。ESP01S 本身不适合做低功耗产品可以考虑替换为 ESP32-C3、ESP32-S3 或 4G 模组将 Wi-Fi 协议栈从“AT 黑盒”切换为“SDK 自主开发”。那又是一个新的项目了但数据链路和平台对接经验完全可以复用。把这条链路从 STM32 到 OneNET 再到小程序的每一个环节都亲手走通之后你收获的不只是一个“能交差的毕设”而是一套适用于大多数物联网项目的通用技术骨架。后续无论是换传感器、换云平台还是换手机端框架核心思路都不会变。
分享:

看完干货,该让你的企业上线了

免费需求沟通 · 48 小时内出具建站方案 · 河南本地可上门