用ESP32和MicroPython玩转MQ136硫化氢传感器:从接线到数据读取的保姆级教程
2026/5/9 10:42:19 网站建设 项目流程

ESP32与MicroPython实战:MQ136硫化氢传感器全流程开发指南

硫化氢检测在工业安全、环境监测等领域具有重要价值。对于创客和物联网开发者来说,ESP32搭配MicroPython的组合为快速原型开发提供了绝佳平台。本文将带您从零开始,完成一个完整的MQ136传感器应用开发流程,涵盖硬件连接、固件烧录、代码编写到数据可视化的全链路实践。

1. 硬件准备与电路搭建

MQ136传感器模块通常采用4针设计,包含VCC、GND、AO(模拟输出)和DO(数字输出)接口。我们主要使用AO引脚进行模拟量采集。ESP32开发板选择上,推荐使用带有GPIO引脚引出的基础型号,如ESP32 DevKitC或NodeMCU-32S。

关键接线步骤:

  • MQ136 VCC → ESP32 5V输出引脚
  • MQ136 GND → ESP32 GND引脚
  • MQ136 AO → ESP32 GPIO32(ADC1通道4)
  • 可选:MQ136 DO → 任意GPIO(用于阈值报警)

注意:ESP32的ADC参考电压默认为3.3V,而MQ136工作电压为5V。虽然AO输出可以直接连接,但建议在AO和ESP32之间加入分压电路(如1kΩ+2kΩ电阻分压)以获得更精确的测量范围。

传感器预热是保证数据准确性的关键环节。MQ136内部加热元件需要约20秒达到工作温度,这段时间内读数会逐渐稳定。实际测试中,环境温度会影响预热时间:

环境温度(℃)建议预热时间(秒)
10-2025-30
20-3020-25
>3015-20

2. MicroPython环境配置

为ESP32刷写MicroPython固件是项目起点。最新稳定版固件可从MicroPython官网获取。刷写工具推荐使用esptool.py,这是最可靠的ESP系列芯片编程工具。

固件烧录步骤:

  1. 安装esptool.py:pip install esptool
  2. 擦除闪存:esptool.py --port COM3 erase_flash
  3. 写入固件:esptool.py --port COM3 --baud 460800 write_flash -z 0x1000 esp32-20220618-v1.19.1.bin

烧录完成后,通过串口工具(如PuTTY或Thonny IDE)连接ESP32,应该能看到MicroPython交互提示符(>>>)。首次使用时建议执行:

import machine import esp esp.osdebug(None) # 关闭调试输出以提升性能

MQ136驱动库需要手动上传到ESP32文件系统。将mq136.py文件通过Thonny IDE的文件管理器拖放至设备,或使用ampy工具:

ampy --port COM3 put mq136.py

3. 传感器数据采集编程

MicroPython的ADC类提供了模拟量读取接口。ESP32的ADC具有12位分辨率(0-4095),对应0-3.3V电压范围。针对MQ136的典型采集代码如下:

from machine import ADC, Pin import time import mq136 # 初始化ADC adc = ADC(Pin(32)) adc.atten(ADC.ATTN_11DB) # 设置满量程为3.3V # 创建传感器实例 sensor = mq136.MQ136(adc) # 预热阶段 print("传感器预热中...") for i in range(20, 0, -1): print(f"剩余预热时间: {i}秒") time.sleep(1) # 持续读取 while True: voltage = sensor.getVoltage() # 获取电压值(mV) ppm = (voltage - 400) * 0.5 # 简易转换公式 print(f"电压: {voltage}mV | 估算浓度: {ppm:.2f}ppm") time.sleep(1)

代码关键点解析:

  1. adc.atten()设置ADC衰减,ATTN_11DB对应最大3.3V输入范围
  2. 预热期间避免使用读数,因传感器未达到工作温度
  3. 简易ppm转换公式需根据实际校准调整
  4. 采样间隔建议≥1秒以保证数据稳定性

更精确的浓度转换需要考虑传感器特性曲线。MQ136的电阻比(Rs/R0)与气体浓度关系近似满足:

ppm = a * (Rs/R0)^b

其中a、b为传感器特性参数,R0为清洁空气中的传感器电阻。完整校准程序应包括:

  1. 在清洁空气中测量R0值
  2. 使用标准气体测试获取多个数据点
  3. 通过曲线拟合确定a、b参数

4. 数据可视化与报警系统

将传感器数据可视化能更直观地观察浓度变化。通过ESP32的WiFi功能,我们可以轻松实现数据上云或本地显示。

Web服务器实时显示方案:

import network import socket from machine import ADC, Pin import mq136 # WiFi连接 sta_if = network.WLAN(network.STA_IF) sta_if.active(True) sta_if.connect("SSID", "password") # 传感器初始化 adc = ADC(Pin(32)) sensor = mq136.MQ136(adc) # 创建TCP服务器 addr = socket.getaddrinfo('0.0.0.0', 80)[0][-1] s = socket.socket() s.bind(addr) s.listen(1) while True: cl, addr = s.accept() voltage = sensor.getVoltage() ppm = (voltage - 400) * 0.5 response = """HTTP/1.1 200 OK Content-Type: text/html <html> <body> <h1>MQ136监测数据</h1> <p>电压值: {} mV</p> <p>估算浓度: {:.2f} ppm</p> </body> </html> """.format(voltage, ppm) cl.send(response) cl.close()

访问ESP32的IP地址即可看到实时数据页面。更复杂的方案可以结合MQTT协议将数据发送到Node-RED等可视化平台,或使用MicroPython的urequests库直接上传到云服务。

本地报警系统实现:

from machine import ADC, Pin, PWM import mq136 import time # 初始化组件 adc = ADC(Pin(32)) buzzer = PWM(Pin(25), freq=1000, duty=0) led = Pin(26, Pin.OUT) sensor = mq136.MQ136(adc) # 报警阈值 ALARM_LEVEL = 10 # ppm while True: ppm = (sensor.getVoltage() - 400) * 0.5 if ppm > ALARM_LEVEL: # 声光报警 buzzer.duty(512) # 50%占空比 led.value(1) time.sleep(0.5) buzzer.duty(0) led.value(0) else: time.sleep(1)

实际部署时,报警阈值应根据安全标准设置。不同场景下的典型阈值参考:

应用场景建议报警阈值(ppm)暴露时间限制
工业环境108小时
短期工作区1515分钟
立即危险浓度100立即撤离

5. 项目优化与进阶技巧

提升系统稳定性和数据质量需要多方面的优化。电源质量对传感器性能影响显著,建议:

  • 使用线性稳压器(如AMS1117)替代开关电源
  • 在VCC和GND之间添加100μF电容
  • 为ADC参考电压添加0.1μF去耦电容

软件滤波算法能有效消除随机干扰。移动平均滤波简单有效:

from collections import deque class MovingAverage: def __init__(self, size=5): self.size = size self.buffer = deque(maxlen=size) def add(self, value): self.buffer.append(value) return sum(self.buffer) / len(self.buffer) # 使用示例 filter = MovingAverage() while True: raw_voltage = sensor.getVoltage() filtered = filter.add(raw_voltage) print(f"原始值: {raw_voltage} 滤波后: {filtered:.2f}") time.sleep(1)

对于需要更高精度的场景,可考虑卡尔曼滤波等高级算法。ESP32的双核特性允许我们将传感器读取和数据处理任务分配到不同核心:

import _thread from machine import ADC, Pin import mq136 # 共享变量 shared_data = {'voltage': 0, 'ppm': 0} def sensor_task(): adc = ADC(Pin(32)) sensor = mq136.MQ136(adc) while True: shared_data['voltage'] = sensor.getVoltage() shared_data['ppm'] = (shared_data['voltage'] - 400) * 0.5 time.sleep(0.5) _thread.start_new_thread(sensor_task, ())

低功耗设计对电池供电的应用至关重要。ESP32的深度睡眠模式可大幅降低能耗:

import machine import time from machine import ADC, Pin import mq136 # 初始化 adc = ADC(Pin(32)) sensor = mq136.MQ136(adc) # 工作循环 while True: voltage = sensor.getVoltage() print(f"当前读数: {voltage}mV") # 进入深度睡眠30秒 print("进入深度睡眠...") machine.deepsleep(30000)

实际测试中,这种模式可将平均电流从80mA降至约5mA,显著延长电池寿命。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询