
简介本资源是一套完整的基于STM32的物联网火灾烟雾报警系统毕业设计实现方案面向电子信息、自动化、物联网工程等专业的本科生及嵌入式初学者解决智能安防类毕设中硬件感知、无线组网、移动端交互与云平台联动等核心问题。压缩包含298个文件总计50.09MB涵盖98个C语言源码如stm32f10x_tim.c、cJSON.c、93个头文件.h、25个XML配置与界面描述文件、13个Java安卓端代码、4个Keil工程文件.uvprojx/.uvoptx及1个可直接安装的APP调试APK另有演示视频MP4、原理图PDF、使用说明DOCX和调试脚本BAT等结构完整、模块清晰。已有153人学习下载提供从STM32传感器采集温湿度/烟雾/火焰、OLED本地显示、ESP8266自动组网与断网重连、阿里云MQTT通信到Android端阈值远程配置、数据库时段查询、蜂鸣器远程开关的全链路实现配套详细使用说明与操作演示视频便于快速部署与二次开发。1. 项目概述与设计思路1.1 这个毕设到底在做什么先直接说结论这是一个以STM32单片机为核心控制器、借助ESP8266 WiFi模块接入物联网云平台实现了烟雾浓度实时监测、温度采集、本地声光报警以及远程手机端推送的火灾烟雾报警系统。项目压缩包里包含了完整的源码、使用说明和演示视频拿到手只需要按文档接线、烧录、配置WiFi就能跑起来。毕业设计选这个方向的人很多但真正能把“单片机传感器采集”和“物联网云平台”两端都讲清楚、做出来的并不算多。这套系统最大的优势是性价比高核心元件加起来不超过100元但功能完整、技术点密集无论做课程设计还是毕业设计都够撑场面。从答辩角度讲它涉及ADC采集、定时器、串口通信、PWM、中断、外部传感器驱动、ESP8266 AT指令、MQTT协议、JSON数据解析几乎把嵌入式方向本科阶段该露脸的知识点都覆盖了。1.2 为什么选择STM32加物联网方案选择STM32而不是51单片机不是因为51做不了而是因为现在的毕业设计越来越看重“新技术融合”。51单片机做烟雾报警器十几年前就有人做过了论文查重和答辩时都很难讲出新意。STM32作为ARM Cortex-M3内核的主流单片机既保留了单片机的底层层面寄存器、中断、GPIO、ADC又能接WiFi模块、能做协议栈处理整个项目可以往“物联网”方向包装价值感完全不一样。从实际掌握的难度来看STM32F103C8T6是学习资料最丰富、成本最低的选择网上教程、例程、封装库多到不行对需要快速出成果的毕设来说是最优解。而且这块芯片在毕业后找嵌入式相关工作面试时也是高频考点做完这个项目你至少能跟面试官聊清楚ADC采样、串口DMA、状态机这几件事投入产出比很高。1.3 系统整体架构设计整个系统的数据流向可以用一条线串起来STM32通过ADC读取MQ-2烟雾传感器的模拟电压经过软件滤波和标定换算得出烟雾浓度百分比同时读取DHT11温湿度数据STM32对数据做判断超过阈值就驱动蜂鸣器、LED和继电器所有数据通过串口发送给ESP8266ESP8266以MQTT协议连接到云平台云平台把数据推送到手机App或小程序。环节输入输出关键点传感器采集MQ-2模拟电压、DHT11总线数据ADC数值、温度湿度必须做滤波和标定数据处理ADC原始值烟雾浓度百分比阈值判定要有迟滞本地报警浓度数据蜂鸣器、LED、继电器声光联动远程上传串口帧数据MQTT报文需要JSON封包云端展示MQTT订阅数据小程序实时曲线云平台免费额度够用这个架构里STM32做的是边缘计算和本地控制云平台做的是远程监控和数据存储。即使WiFi断了本地报警功能依然能正常工作这是这套系统在真实场景中比纯云方案稳定得多的原因答辩时也可以专门强调这个设计取舍。2. 硬件选型与关键电路解析2.1 主控选型STM32F103C8T6的底气在哪STM32F103C8T6这类小蓝板Blue Pill几乎是国产嵌入式毕设的标配。它拥有72MHz主频、64KB Flash、20KB RAM外设接口包括3个USART、2个SPI、2个I2C、10个ADC通道对烟雾报警系统来说完全够用。选它的另一个原因是开发方式太灵活标准外设库、HAL库、寄存器操作都可以网上源码一抓一大把出了问题也容易排查。这里必须踩一个坑提醒市面上廉价小蓝板很多用的并不是正片ST芯片而是翻新片或国产兼容片这类芯片在ADC参考电压稳定性上可能存在偏差。传感器采集对ADC精度有依赖建议到手后先烧一个ADC校准例程看看读数是否稳定最好用万用表量一下板载3.3V实际输出电压再根据实际电压值去换算浓度。不要迷信默认的“4096对应3.3V”实际可能是3.28V或3.35V这种小误差会让浓度百分比偏移好几个点。2.2 烟雾传感器MQ-2和MQ-7怎么选市面上最常见的烟雾传感器有两种MQ-2和MQ-7。MQ-2对液化气、丙烷、丁烷、烟雾敏感是家庭烟雾报警的主流选择MQ-7对一氧化碳更敏感适合煤气泄漏检测场景。毕设选MQ-2的比较多因为它的灵敏度曲线在烟雾场景下更平滑标定起来也容易用打火机气体测试时反应很明显。MQ-2模块的模拟输出AO引脚接STM32的ADC引脚比如PA1。这里有一个容易忽略的细节MQ-2内部有加热电阻上电初期传感器化学材料没有达到稳定工作温度输出电压会持续漂移几分钟。程序里不能一上电就立刻把ADC值当作真实浓度需要在初始化后加上一段预热延时或者软件上做一个“上电跳过报警”的保护逻辑。我第一次上电调试的时候系统开机3秒内ADC直接拉满蜂鸣器疯响后来才发现是预热没做。MQ-2还有一个数字量输出DO引脚模块上带一个电位器可以调节数字输出翻转阈值。但毕设里不建议用DO因为阈值是硬件固定的没法在程序里动态调整灵活性太差。用AO接ADC才是正确玩法。2.3 WiFi模块ESP8266-01还是ESP-12F物联网部分选ESP8266系列模块是这个项目性价比最高的方案。ESP8266-01小巧但天线和Flash都弱一些ESP-12F是带PCB天线、大Flash、引脚引出完整的版本更稳定。我在实操中推荐ESP-12F原因很简单串口透传AT固件下连接稳定性比ESP-01明显好而且模块本来就是3.3V供电可以直接和STM32的电平对接不需要额外电平转换。ESP8266有几种工作模式AT指令模式出厂自带AT固件STM32通过串口发AT指令控制WiFi连接和网络数据收发最简单SDK二次开发模式直接在ESP8266上跑自己的程序需要单独开发环境透传模式配置好TCP或MQTT连接后串口数据直接转发到网络端省去每条指令的交互对于毕业设计用AT指令模式就够了代码集中在STM32端ESP8266只做一个网络桥接。这样逻辑清晰答辩时也好解释。不过要注意不同固件版本的AT指令集有差异有的MQTT固件支持ATMQTTCONN直接连MQTT broker有的只支持TCP透传需要自己在STM32里封装MQTT报文。买模块时最好直接问卖家要当前固件对应的指令手册。2.4 显示与报警执行单元显示模块建议用0.96寸OLEDI2C接口SSD1306驱动四根线就能接VCC、GND、SCL、SDA显示实时烟雾浓度、温度和报警状态。有人用LCD1602但LCD1602需要占用至少6个IO口还要调背光和对比度块头大、显示内容少在展示效果上远不如OLED。报警执行单元是蜂鸣器有源或无源均可、红色LED、继电器可接排风扇或电磁阀。这里必须提醒一个接线细节蜂鸣器和继电器如果是5V供电的不能直接接在STM32的GPIO上拉驱动必须通过三极管S8050/NPN或者ULN2003达林顿驱动。直接接GPIO会烧引脚这是新手最常犯的错误。继电器的驱动还要注意感性负载的反向电动势问题。如果继电器控制的负载是风扇、电磁阀这类感性负载开关瞬间会产生很高的反向电压可能把单片机复位甚至打坏IO口。解决办法是在继电器线圈两端并联一个1N4007续流二极管阴极接电源正极、阳极接电源负极这个二极管平时不导通但在关断瞬间能把反向尖峰钳位掉。3. 软件核心实现与代码逻辑3.1 传感器数据采集与滤波处理ADC采集这块核心思路是使用STM32的ADC1通道软件触发或定时器触发连续采样。MQ-2的模拟输出在稳定状态下依然会有微小波动直接拿单次采样的值做判断容易出现报警状态抖动的现象。我采用的做法是连续采集10次去掉最大值和最小值再对剩余8次求平均。下面是一段基于标准外设库的采集代码片段uint16_t Smoke_Get_ADC(void) { uint32_t sum 0; uint16_t sample[10]; uint8_t i, j; uint16_t temp; for(i0;i10;i) { sample[i] ADC_Get_Single_Value(); HAL_Delay(10); // 每次采样间隔10ms } // 简单冒泡排序去掉最大最小后求平均 for(i0;i9;i) { for(j0;j9-i;j) { if(sample[j] sample[j1]) { temp sample[j]; sample[j] sample[j1]; sample[j1] temp; } } } for(i1;i9;i) { sum sample[i]; } return (uint16_t)(sum / 8); }这段代码看起来朴素但实际工程里这种“中值平均”组合滤波对传感器噪声的抑制效果很明显。注意采样间隔不能太短MQ-2的反应时间本身在秒级没必要微秒级疯狂采样10ms的间隔足够平滑了。如果用HAL库ADC单次采集可以这么写static ADC_HandleTypeDef hadc1; void ADC_Init(void) { __HAL_RCC_ADC1_CLK_ENABLE(); hadc1.Instance ADC1; hadc1.Init.ScanConvMode DISABLE; hadc1.Init.ContinuousConvMode DISABLE; hadc1.Init.DiscontinuousConvMode DISABLE; hadc1.Init.ExternalTrigConv ADC_SOFTWARE_START; hadc1.Init.DataAlign ADC_DATAALIGN_RIGHT; hadc1.Init.NbrOfConversion 1; HAL_ADC_Init(hadc1); } uint16_t ADC_Get_Single_Value(void) { ADC_ChannelConfTypeDef sConfig {0}; sConfig.Channel ADC_CHANNEL_1; // PA1对应ADC通道1 sConfig.Rank 1; sConfig.SamplingTime ADC_SAMPLETIME_55CYCLES_5; HAL_ADC_ConfigChannel(hadc1, sConfig); HAL_ADC_Start(hadc1); HAL_ADC_PollForConversion(hadc1, 10); return (uint16_t)HAL_ADC_GetValue(hadc1); }采样时间选择55.5个周期是基于稳定性的考虑采样时间太短会导致采样电容没有完全充放电ADC结果会偏低且不稳定。对于10kΩ内阻的MQ-2输出55.5周期是比较稳妥的最低值。3.2 浓度标定与阈值判定机制MQ-2输出的ADC值0到4095本身不是浓度单位需要换算成烟雾浓度百分比。STM32内部ADC是12位的如果参考电压是3.3V那么float voltage (float)adc_value / 4095.0f * 3.3f; float smoke_percent (voltage - 0.1f) / (3.3f - 0.1f) * 100.0f;这个线性换算的前提是传感器输出电压大致与浓度呈正比。MQ-2实际曲线是类似对数的曲线在小浓度区间变化剧烈在大浓度区间趋于平缓严格来说要用分段查表或者指数拟合。但对毕业设计来说线性近似在报警阈值附近比如20%到50%区间的误差是可接受的因为这只是一个定性预警而不是精确计量设备。答辩时老师如果问精度问题你可以诚实说这是阈值型报警器不是计量仪器重点是趋势监测和报警可靠性。阈值判定不能只用一个固定值。我设计了三档状态状态烟雾浓度区间动作正常0%到15%绿灯常亮无报警预警15%到25%黄灯闪烁OLED显示预警报警大于等于25%红灯加蜂鸣器响继电器吸合上报云平台另外要在代码里加入“迟滞”逻辑比如浓度超过25%进入报警后要降到20%以下才能退出报警避免在阈值附近反复触发。这是工业报警器常用的做法答辩时讲出来很加分因为体现了工程思维而不仅仅是写了段if语句。迟滞逻辑的伪代码typedef enum {NORMAL, WARNING, ALARM} AlarmState; AlarmState currentState NORMAL; void Alarm_Update(float smoke_percent) { switch(currentState) { case NORMAL: if(smoke_percent 25.0f) currentState ALARM; else if(smoke_percent 15.0f) currentState WARNING; break; case WARNING: if(smoke_percent 25.0f) currentState ALARM; else if(smoke_percent 12.0f) currentState NORMAL; break; case ALARM: if(smoke_percent 20.0f) currentState WARNING; break; } }注意预警状态退出阈值是12%而不是15%报警退出阈值是20%而不是25%这是故意留出的迟滞区间防止状态在临界点来回跳。3.3 物联网云平台接入MQTT与JSON封包物联网部分可以选阿里云物联网平台也可以用巴法云这类免费MQTT服务。阿里云MQTT协议栈需要先做一机一密的认证注册产品和设备、生成三元组ProductKey、DeviceName、DeviceSecretMQTT的ClientID和Password都要用三元组加签名算法动态生成步骤繁琐但完整度更高论文里能写的东西更多。如果不想折腾签名过程巴法云的接入方式简单很多一个TCP地址、一个私钥Topic就能把自己自定义的数据推上去。STM32给ESP8266发的是AT指令。连接WiFi的核心流程是// 1. 配置ESP8266为Station模式 ATCWMODE1\r\n // 2. 连接WiFi ATCWJAP\mywifi\,\password123\\r\n // 3. 建立MQTT连接以巴法云/EMQX为例 ATMQTTCONN\broker.emqx.io\,1883\r\n // 4. 发布消息 ATMQTTPUB0,\smoke/topic\,\{\\\smoke\\\:35.6}\,0,0\r\n发送AT指令后要等待模块返回OK或者ERROR这些返回字符串的判断在代码里要有超时机制不能无限阻塞等待。最常用的方式是串口接收中断配合一个环形缓冲区主循环里解析收到的内容。在STM32端拼装JSON时要注意转义问题。我见过很多人在这个环节翻车因为C语言字符串里的双引号必须写成导致拼接过程容易出bug。更稳妥的做法是用sprintf先格式化数据再手动拼JSONchar json_buf[128]; char payload[128]; sprintf(payload, {\smoke\:%.1f,\temp\:%.1f,\status\:%d}, smoke, temp, alarm_status); sprintf(json_buf, ATMQTTPUB0,\smoke/topic\,\%s\,0,0\r\n, payload);注意payload里如果包含双引号sprintf之后要检查一下json_buf的长度ESP8266 AT指令的单条指令长度有上限一般是256字节超过会直接丢弃。所以字段不要塞太多烟雾浓度、温度、状态三个核心字段就够了。3.4 OLED显示与状态机逻辑显示逻辑不要写得太乱我用一个简单状态机来控制OLED刷新内容状态0正常第一行显示烟雾浓度百分比第二行显示温度湿度状态1预警第一行显示“预警 XX.X%”第二行提示检查环境状态2报警第一行显示“报警 XX.X%”第二行显示报警持续秒数OLED刷新频率不用太高每秒刷新一次足够刷新太快反而会在屏幕上出现闪烁还会占用单片机大量时间片。如果要显示报警持续秒数就在报警状态里用定时器累加计数而不是用HAL_Delay阻塞延时否则整个系统都会卡住。SSD1306的驱动可以用网上常见的软件I2C移植关键初始化序列是固定的只要保证I2C地址正确0x78或0x7A就可以了。这里有个小坑很多0.96寸OLED模块的地址根据背部电阻位置不同可能是0x78默认7位地址0x3C也可能是0x7A驱动代码里I2C地址写错的话屏幕会一直白屏。买模块时问清地址或者直接用I2C扫描例程扫出来最稳。4. 调试过程与常见问题排查4.1 MQ-2上电读数漂移严重怎么办这个问题几乎人人都会遇到。MQ-2内部有加热丝冷态上电时传感器温度没上来输出会从一个很高的电压慢慢回落。我第一次调试时上电3秒内ADC值直接冲到4095系统误报了十来秒后来才稳定在800左右。解决办法有三层第一硬件上让MQ-2先通电预热30秒以上再进行校准采样。如果是做演示提前把系统开机放一会别等答辩老师来了才上电传感器还没热就演示读数一定是飘的。第二程序里做一个启动保护上电后前20秒不做报警判定。用标志位控制20秒过后才进入正常工作流程。第三把“当前读数”和“上电稳定后的基准值”做差值或比值形成相对浓度而不是直接用绝对ADC值去比较。因为MQ-2的绝对输出电压会随着环境温湿度变化但相对变化量更能反映实际烟雾浓度变化这也是工业可燃气体报警器的常见做法。4.2 ESP8266连接路由器不稳定毕设现场的网络环境往往不是家里那种稳定WiFi而是教室、实验室里的大WiFi甚至手机热点。ESP8266这类低成本模块对2.4G信号比较挑剔5G频段直接不支持如果路由器开了5G合并发射同SSID双频合一模块可能连不上。排查思路整理成表格现象可能原因解决办法ATCWJAP返回ERROR密码错误或WiFi频段为5G确认2.4G信号密码无特殊字符连接成功但MQTT连不上Broker地址或端口被防火墙挡换一个MQTT broker或端口测试数据发送成功但手机收不到Topic订阅关系不对检查发布Topic和订阅Topic是否一致模块反复掉线供电不足或信号弱用独立3.3V稳压供电靠近路由器断网后程序卡死等待AT回复无超时所有AT发送都加超时重连机制供电不足是ESP8266最大的隐性问题。STM32板子的3.3V稳压芯片输出能力有限如果直接给ESP8266供电WiFi发射瞬间电流能达到300mA以上电压会跌落导致模块重启。正确做法是给ESP8266单独用一块AMS1117-3.3或MP1584降压模块供电共地但不共电源。如果现场网络太差提前准备好手机热点实测下来手机热点兼容性比公共WiFi好很多。热点名称和密码不要设置太复杂ESP8266的AT固件对特殊字符支持不好最好用纯字母数字。4.3 蜂鸣器误报和继电器抖动有源蜂鸣器的驱动方式很简单给高电平就响。但如果驱动三极管基极电阻选得不对或者GPIO在复位瞬间是高电平上电时会“嘀”一声响一下这在演示时很尴尬。解决办法是在初始化代码里第一时间把蜂鸣器引脚拉低同时在三极管基极加一个10k下拉电阻确保复位状态下三极管不会意外导通。继电器抖动主要出现在报警切换的瞬间。如果继电器直接驱动排风扇这类感性负载开关瞬间会产生反向电动势可能导致单片机复位。解决办法是前面提到的在继电器线圈两端并联1N4007续流二极管同时单片机控制继电器的引脚加上拉或下拉电阻防止复位瞬间误动作。还有一个隐蔽问题如果继电器和蜂鸣器共用一个电源继电器吸合瞬间的大电流会造成电源电压跌落蜂鸣器声音会变调甚至在极端情况下导致STM32复位。解决办法是把继电器供电单独走一路或者加一个100uF以上的电解电容做储能缓冲。这个问题在实验室电源上不明显但用USB供电时特别容易发生。5. 数据上云与远程监控展示5.1 云平台选型对比物联网平台的选型直接影响项目进度。我对比过几种常见方案平台接入难度免费额度展示效果适合场景阿里云物联网平台较难需要签名认证有免费试用可以做数据流转、可视化面板论文内容要充实的话选它巴法云简单Topic直接发布免费支持Web和App推送快速出效果EMQX公共broker简单零配置免费没有自带面板需自己写只做数据上报演示OneNET移动云中等有免费额度有基础图表稳定但界面比较旧巴法云对毕设来说是最友好的注册后给你一个私钥App端订阅Topic就能收到消息不需要复杂的设备身份认证30分钟能跑通。阿里云虽然复杂但它的“物联网平台-设备管理-数据解析-服务端订阅”整套流程写进论文里篇幅和深度都很可观如果你们学校对毕设工作量要求高建议上阿里云。5.2 手机端接收报警的两种方案手机端接收报警最常见的方案是小程序。用微信小程序配合云平台提供的API或者WebSocket接口订阅设备Topic实时刷新烟雾浓度曲线。云平台直接提供的App模板通常比较简单但胜在稳定也有推送通知功能。另一种是自己用App Inventor或安卓Studio写一个简单APP通过MQTT库直接订阅Topic。App Inventor做原型极快拖几个组件就能完成适合不会安卓开发的同学。安卓Studio自由度更高但整个项目会多出一大块内容答辩时如果老师追问APP逻辑你不熟悉的话反而扣分。我个人的建议是如果主要目标是嵌入式系统展示手机端用现成的小程序或者App模板就够了不必投入太多精力。5.3 演示视频录制要点这个项目压缩包里带了演示视频说明原设计者已经意识到了现场演示的不确定性。我录制演示视频的经验是至少录三段第一段是正常环境下的运行状态第二段是打火机靠近传感器触发报警并联动继电器的过程第三段是远程手机端收到推送的截屏录屏。拍摄时注意几个细节打火机不要离MQ-2太近大概5到10厘米距离放气太近会让传感器瞬间过载烟雾浓度直接打到100%造成“饱和”画面看起来不真实触发报警后要把打火机移开让系统演示浓度回落、报警解除的过程这样能展示迟滞逻辑和状态机恢复能力远程推送的画面要等数据真正刷新后再拍别让观众看到手机端一直转圈。6. 毕业设计答辩要点与项目扩展建议6.1 现场演示的细节和话术毕业设计答辩现场演示系统时最容易翻车的就是网络和传感器预热。如果你只准备了一台电脑开演示别指望现场WiFi一定给力最好提前准备好手机热点并且把热点名称和密码设成简单无特殊字符的组合。答辩老师大概率会问这几个问题提前准备好回答思路“你的系统报警之后会做什么” 答本地声光报警同时联动继电器默认可以接排风扇或电磁阀数据同步上传云端即使断网本地报警不受影响。“传感器精度怎么样” 答MQ-2是半导体气敏传感器精度不能和电化学传感器比但胜在成本低、响应快适合作为家庭级预警系统定为阈值型报警器不做精确计量。“如果网络断了怎么办” 答系统设计是本地优先断网不影响本地报警只是远程推送会延迟代码里实现了重连机制网络恢复后自动续传。“为什么选MQTT而不是HTTP” 答MQTT是轻量级发布订阅协议报文开销小适合低带宽、不稳定网络下的设备通讯HTTP请求响应式协议对频繁上报的场景太冗余。6.2 低成本加分扩展方向如果想在毕设里加分不需要大改硬件可以加下面几个功能用OLED显示最近24小时的烟雾浓度变化曲线本地存储历史数据加一个DHT11/DHT22温湿度采集让系统数据维度更多用ESP8266做固件远程升级配合STM32的Bootloader设计把报警记录写入STM32内部Flash掉电不丢失断电后可以查历史报警云平台加微信小程序或手机App的推送通知加一个按键一键布防/撤防模拟真实报警器的防误报逻辑我个人觉得第2个和第5个性价比最高改装量小、视觉效果明显而且是物联网方向答辩最喜欢问的东西。温湿度数据可以和烟雾浓度一起打包成JSON上报小程序端就能同时展示三个数据曲线信息量立刻翻倍。6.3 项目后续可以作为进阶的方向如果这套系统做完了还想继续深入可以往几个方向走一是把STM32换成ESP32直接把WiFi、蓝牙集成到主控上去掉ESP8266模块整体更简洁二是引入RTOS比如FreeRTOS把传感器采集、报警处理、网络上报拆成独立任务这才是工业级产品该有的软件架构三是加一个小型OLED曲线显示和TF卡数据记录功能把这个系统做成一个独立可用的家庭安防终端。从职业角度看完成这个项目后你对单片机外设驱动、无线通信协议、物联网云平台交互的理解会有一个质的提升。这个项目的底层能力在智能家居、工业监测、农业物联网等领域都能迁移应用不是毕业了就扔掉的“一次性代码”。最后再说一个实际体会。做这套系统最深的感受是项目难点往往不在某一个单独的技术点上而在于把传感器、主控、通信、云端这几条链路拧成一根绳。任何一个环节掉链子整个演示都会崩。所以我给的建议是先把本地报警功能调稳定了再碰物联网不要一上来就想着连平台。本地功能是保底远程功能是加分这个顺序搞反了前面的时间大概率会浪费在排查网络问题上。祝所有做这个题目的朋友一次点亮、永不白屏。本文还有配套的精品资源点击获取