MQ2烟雾传感器与STM32的智能联动:从数据采集到蓝牙传输

张开发
2026/4/10 10:30:43 15 分钟阅读

分享文章

MQ2烟雾传感器与STM32的智能联动:从数据采集到蓝牙传输
1. MQ2烟雾传感器与STM32的硬件连接MQ2烟雾传感器是智能家居和工业安全监测中常用的气体检测模块它能灵敏地检测液化气、丙烷、氢气等多种可燃气体。我第一次用STM32驱动MQ2模块时发现市面上主要有两种类型模拟输出型和串口输出型。这里重点讲串口型因为它更适合与STM32配合使用。串口型MQ2模块通常有4-6个引脚最关键的是VCC、GND、TX和RX。实际接线时要注意VCC接5V电源部分模块支持3.3VGND接地TX接STM32的RX如USART3的PB11RX接STM32的TX如PB10我遇到过模块不工作的情况后来发现是波特率设错了。MQ2模块默认波特率通常是9600但有些型号是115200建议先查手册确认。接线时推荐用杜邦线先测试稳定后再焊接。如果要用在工业环境最好加上TVS二极管做防浪涌保护。2. 串口通信协议解析MQ2的数据交互采用固定帧格式这是实际项目中最容易出错的部分。模块收到查询指令后会返回9字节数据其中包含浓度信息。具体协议如下请求帧STM32→MQ2FF 01 86 00 00 00 00 00 79这就像对传感器说嘿把当前数据告诉我。最后一个字节0x79是校验和计算方法是前面所有字节的和取反。响应帧MQ2→STM32示例FF 86 00 85 00 00 00 00 F5关键数据在第2、3字节0x00和0x85组合起来就是0x0085转换成十进制是133表示当前浓度值。我在代码里是这样处理的// 合并数据字节 raw_value (mq2_response[2] 8) | mq2_response[3]; // 转换为百分比 smoke_concentration (raw_value * 100) / 5000;注意要检查帧头FF 86和校验和。有次现场调试时数据老是跳变后来发现是没做校验和验证导致收到干扰数据。3. STM32双串口配置技巧要实现同时与MQ2通信和蓝牙传输需要配置两个串口。我习惯用USART3接MQ2USART2接蓝牙模块。初始化时要注意时钟使能别漏掉RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2 | RCC_APB1Periph_USART3, ENABLE);GPIO复用配置// USART3 (PB10TX, PB11RX) GPIO_PinAFConfig(GPIOB, GPIO_PinSource10, GPIO_AF_USART3); GPIO_PinAFConfig(GPIOB, GPIO_PinSource11, GPIO_AF_USART3);中断优先级设置 蓝牙串口的中断优先级应该比MQ2的高否则可能出现数据阻塞。我一般这样设NVIC_InitStruct.NVIC_IRQChannel USART2_IRQn; // 蓝牙 NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority 1; NVIC_InitStruct.NVIC_IRQChannel USART3_IRQn; // MQ2 NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority 2;调试时建议先用串口助手测试单个模块再组合使用。遇到过最头疼的问题是串口互相干扰后来发现是中断服务函数里没及时清除标志位。4. 蓝牙数据传输实战我用的是HC-05蓝牙模块手机端装个蓝牙串口助手APP就能接收数据。关键点在于数据格式设计。比如发送Smoke: 15%比直接发15更友好。发送逻辑要注意防冲突void send_smoke_concentration_to_bluetooth(void) { char buffer[20]; snprintf(buffer, sizeof(buffer), Smoke: %d%%\n, smoke_concentration); // 临时关闭中断防止冲突 USART_ITConfig(USART2, USART_IT_RXNE, DISABLE); for(int i0; buffer[i]!\0; i){ while(USART_GetFlagStatus(USART2, USART_FLAG_TXE)RESET); USART_SendData(USART2, buffer[i]); } USART_ITConfig(USART2, USART_IT_RXNE, ENABLE); }建议添加超时机制我遇到过蓝牙模块无响应导致程序卡死的情况。可以在while循环里加个计数器超过一定时间就跳出。5. 实际应用中的优化建议在智能家居项目中单纯传输浓度值还不够我通常会做这些优化数据滤波MQ2的输出会有波动可以用滑动平均滤波#define FILTER_SIZE 5 int filter_buffer[FILTER_SIZE]; int filter_index 0; int filtered_value(int new_value) { filter_buffer[filter_index] new_value; if(filter_index FILTER_SIZE) filter_index 0; int sum 0; for(int i0; iFILTER_SIZE; i){ sum filter_buffer[i]; } return sum/FILTER_SIZE; }报警阈值设置多级报警比如浓度20%黄色预警浓度50%红色报警浓度80%触发继电器切断气源低功耗设计如果不是持续监测可以设置采样间隔void enter_low_power_mode(void) { // 配置STM32进入睡眠模式 PWR_EnterSleepMode(PWR_Regulator_LowPower, PWR_SLEEPEntry_WFI); }数据日志添加SD卡模块记录历史数据方便事后分析。我用FATFS文件系统每小时生成一个CSV文件。6. 常见问题排查根据我的踩坑经验这些问题最常见模块无响应检查电源电压用万用表量VCC和GND确认TX/RX交叉连接尝试降低波特率数据乱码检查STM32和模块的波特率是否一致确认时钟配置正确特别是用外部晶振时查看电源是否稳定可加100uF电容滤波蓝牙连接不稳定确保模块进入AT模式时波特率正确通常是38400安卓手机需要位置权限才能使用蓝牙避免金属外壳屏蔽信号有次客户现场反馈数据不准最后发现是模块靠近空调出风口温度变化影响了传感器精度。后来加了温度补偿算法才解决。7. 进阶功能扩展基础功能实现后可以进一步扩展多传感器融合结合温湿度传感器如DHT11数据提高报警准确性。比如高温烟雾浓度骤升可能是火灾。云端监控通过ESP8266将数据上传到云平台我用过OneNET和阿里云IoT都支持MQTT协议。本地显示加个OLED屏显示实时浓度和状态。我用SSD1306驱动显示效果不错。语音报警接入SYN6288语音模块当浓度超标时播放危险请撤离等提示音。这些扩展都需要考虑资源占用问题。STM32F103C8T6只有64KB Flash如果程序太大可能需要换F4系列或者优化代码结构。

更多文章