基于ESP32与RainMaker的智能燃气报警器:从传感器到云端报警

📅 2026/8/20 2:45:51
基于ESP32与RainMaker的智能燃气报警器:从传感器到云端报警
1. 项目缘起为什么需要一个“会打电话”的燃气报警器几年前我租住在一个老小区厨房用的是罐装液化石油气。有一次出差回来刚进楼道就闻到一股淡淡的、类似臭鸡蛋的味道心里咯噔一下。冲到厨房发现是连接灶具的软管老化出现了极其微小的泄漏。万幸的是当时窗户开着浓度没积累起来。但那次经历让我后怕了很久——如果当时家里没人或者窗户紧闭后果不堪设想。市面上的传统燃气报警器大多只能在本地发出高分贝的声光报警。这对于家里有人的情况是有效的但如果家中无人或者住户在熟睡、戴着耳机报警就形同虚设。我需要的是一个能突破空间限制把警报直接送到我手机上的设备。这就是我动手打造这个“Smart LPG Detector with ESP RainMaker Phone Alert”项目的初衷。简单来说这个项目就是一个基于ESP32微控制器的智能液化石油气探测器。它的核心能力不仅仅是检测泄漏更在于能通过Wi-Fi连接到云端并借助乐鑫官方的ESP RainMaker平台在检测到危险时向绑定的手机发送推送通知甚至在未来可以扩展为拨打电话或发送短信。ESP RainMaker解决了物联网设备开发中最头疼的后端服务器、设备管理、用户绑定和消息推送等一系列问题让我们可以专注于传感器和报警逻辑本身。最近在开发者社区里关于ESP32和RainMaker的讨论也热了起来。有人问“esp32 的rainmaker有人用吗”答案是肯定的而且用起来比想象中要简单。也有人遇到“ubuntu安装 esp被删了”这类环境配置问题这恰恰说明了从零开始搭建一个完整项目时稳定的开发环境是第一步。至于“esp能接tp4056使用吗”这涉及到供电方案对于需要长期监测、可能安装在角落的燃气报警器来说一个可靠的电源比如TP4056充电模块搭配锂电池至关重要这能避免频繁更换电池或依赖固定的插座。2. 核心组件选型与设计思路一个可靠的智能燃气报警器硬件选型是基石。它不能只是一个简单的联网玩具而必须是一个稳定、准确、低功耗的安防设备。我的设计思路是分模块化构建便于调试和后期维护。2.1 大脑为什么是ESP32主控芯片我毫不犹豫地选择了ESP32系列具体型号是ESP32-S3。选择它基于几个核心考量第一是双核处理器与充足的资源。ESP32-S3拥有两个240MHz的Xtensa LX7核心这意味着我可以将一个核心专门用于处理复杂的Wi-Fi连接和与RainMaker云端的通信协议另一个核心则专注于实时读取传感器数据、执行报警算法和控制本地声光报警器。这种分工能确保网络波动不会影响本地的安全监测这是安全设备的生命线。相比之下如果使用ESP8266单核处理所有任务在网络重连或数据同步时传感器采样可能会有延迟这是不能接受的。第二是集成的Wi-Fi与蓝牙。Wi-Fi用于连接家庭路由器和ESP RainMaker云端这是实现远程报警的通道。蓝牙则在大规模生产或调试时有用例如可以通过蓝牙进行设备的快速配网虽然RainMaker也提供了基于Wi-Fi的智能配网。内置的无线模块减少了外围电路提高了可靠性。第三是丰富的IO与低功耗模式。ESP32拥有足够的GPIO来连接传感器、报警器和状态指示灯。更重要的是它支持深度睡眠Deep Sleep模式。在燃气报警器的实际应用中气体浓度在绝大部分时间是正常的主控芯片可以大部分时间处于深度睡眠仅定时唤醒传感器进行采样。当传感器检测到浓度异常时通过中断引脚唤醒ESP32使其进入全速工作状态连接网络并发送警报。这种设计能极大延长电池供电时的使用寿命。2.2 嗅觉MQ系列气体传感器的原理与选型检测液化石油气LPG我选用的是MQ-2或MQ-5气体传感器。这里需要深入解释一下它们的工作原理因为理解原理才能正确使用。MQ系列传感器属于半导体式气敏传感器。它的核心是一个用二氧化锡SnO2等金属氧化物制成的敏感元件。在清洁空气中二氧化锡的氧离子吸附在表面导致电子耗尽层电阻较高。当接触到可燃气体如LPG、甲烷、氢气时这些气体会与吸附的氧发生反应释放出电子从而降低敏感元件的电阻。电阻的变化幅度与气体浓度在一定范围内呈正相关。MQ-2 vs MQ-5两者都对LPG敏感但侧重点不同。MQ-2对LPG、丙烷、烟雾的灵敏度都很高范围更广MQ-5则对LPG和天然气的灵敏度更专一抗酒精等干扰气体的能力稍强。对于家庭LPG泄漏检测两者均可我最终选择了MQ-5希望它在厨房环境下对烹饪产生的酒精蒸汽有更好的抗干扰性。注意MQ传感器需要预热这是新手最容易忽略的一点。新的传感器或长时间断电后首次上电需要预热老化24-48小时其读数才会稳定。在预热期间电阻值会持续下降此时的读数没有参考价值。因此在产品化设计中首次安装后应有明确的“预热中请等待”提示。传感器的输出是模拟量电阻变化。我们需要通过一个简单的分压电路将电阻变化转换为ESP32的ADC模数转换器可以读取的电压值。通常的做法是将传感器与一个负载电阻RL串联测量两者中间点的电压。RL的阻值选择很重要它会影响传感器的灵敏度和线性范围对于MQ-5数据手册推荐使用20kΩ的负载电阻。2.3 云端与通信ESP RainMaker如何简化一切如果没有ESP RainMaker我们需要自己租用云服务器、编写设备端和服务端的通信协议如MQTT、搭建数据库、开发手机App并集成推送服务。这是一个庞大的工程。RainMaker将这些基础设施全部打包提供了一个完整的物联网平台。RainMaker的核心工作流程设备端我们在ESP32上烧写一个集成了RainMaker SDK的固件。这个固件包含了与RainMaker云端安全通信的所有逻辑。云端乐鑫维护的RainMaker云负责设备管理、用户绑定、数据路由和推送通知。客户端用户使用官方的“ESP RainMaker”手机AppiOS/Android扫描设备生成的二维码即可完成Wi-Fi配网和设备绑定。在我们的项目中ESP32上的固件会定义一个“设备”和一个“服务”。这个设备有一个关键参数gas_concentration气体浓度。我们可以设置这个参数的属性比如它是只读的手机App只能查看并且可以设置一个“告警阈值”。当ESP32读取的传感器电压值经过换算得到的浓度值超过这个阈值时固件逻辑会触发一个“事件”。这个事件会被上报到RainMaker云端云端随即向所有绑定了该设备的手机App发送一条推送通知。整个过程我们几乎不用关心网络协议细节只需要在固件代码里关注“如何读取传感器值”、“如何判断是否超阈值”、“超阈值后如何触发RainMaker告警事件”。这种抽象层级极大地提高了开发效率。2.4 供电与续航TP4056的角色“esp能接tp4056使用吗” 当然可以而且这是一个非常经典的组合。TP4056是一款单节锂电池线性充电管理芯片它最大的优点是电路简单、成本低廉、外围元件少。对于这个燃气报警器项目理想的供电方案是TP4056充电模块 18650锂电池 5V USB电源。平时设备插着USB电源可以是手机充电器或充电宝TP4056同时为锂电池充电并为整个系统供电。当遇到停电意外时系统自动切换为由锂电池供电保证监测不间断。ESP32的深度睡眠功能可以让它在电池供电下工作数周甚至数月。接线时需要注意TP4056模块的OUT和OUT-接系统的电源输入正负极。电池的正负极接在模块的B和B-上。USB口输入5V。这样就构成了一个完整的、带断电保护的供电系统。3. 从零开始的实战搭建硬件连接与固件开发理论清楚了我们开始动手。这个过程会涉及到硬件焊接、环境搭建和代码编写我会把每一步的细节和容易踩的坑都讲清楚。3.1 硬件电路连接详解首先准备好所有元件ESP32-S3开发板、MQ-5传感器模块如果买的是模块通常已集成负载电阻和比较器输出有模拟量AO和数字量DO、有源蜂鸣器、LED灯、TP4056充电模块、18650电池座、杜邦线若干。连接清单如下元件连接至ESP32引脚说明MQ-5 AOGPIO4 (ADC1_CH3)模拟信号输出用于读取浓度值MQ-5 DO不接或接GPIO用于简单报警数字输出模块内部比较器结果本项目不依赖它MQ-5 VCC3.3V切记勿接5VESP32的ADC参考电压是3.3VMQ-5 GNDGND共地有源蜂鸣器GPIO15通过三极管或MOS管驱动切勿直接接IO口有源蜂鸣器-GNDLED长脚()GPIO2内置LED串联一个220Ω限流电阻LED短脚(-)GNDTP4056 OUTESP32 Vin/5V为整个系统供电TP4056 OUT-ESP32 GND共地18650电池接入TP4056的B和B-重要提示驱动蜂鸣器或继电器等感性负载时一定要使用三极管如S8050或MOS管进行隔离驱动并在蜂鸣器两端并联一个反向的续流二极管如1N4148。直接连接IO口可能会因瞬间电流过大而损坏ESP32芯片。焊接或连接好之后先不要急着上电用万用表通断档检查一下电源正负极之间有没有短路。这是保证不“烧板子”的第一步。3.2 开发环境搭建与“ubuntu安装 esp被删了”问题解决固件开发我们使用乐鑫官方的ESP-IDF框架。这是开发ESP32系列芯片最强大、最正宗的环境。在Ubuntu上安装官方推荐使用一键安装脚本。但很多朋友遇到了“ubuntu安装 esp被删了”的问题这通常是因为安装脚本需要从GitHub下载资源而网络连接不稳定导致的。更可靠的方法是手动安装。手动安装ESP-IDF以v5.1版本为例# 1. 安装依赖包 sudo apt-get update sudo apt-get install git wget flex bison gperf python3 python3-pip python3-venv cmake ninja-build ccache libffi-dev libssl-dev dfu-util libusb-1.0-0 # 2. 创建并进入esp目录克隆ESP-IDF仓库 mkdir -p ~/esp cd ~/esp git clone -b v5.1 --recursive https://github.com/espressif/esp-idf.git # 3. 进入esp-idf目录运行安装脚本 cd ~/esp/esp-idf ./install.sh esp32s3 # 这里指定我们需要的目标芯片为esp32s3 # 4. 设置环境变量 # 每次打开新终端都需要执行或者将其写入~/.bashrc . $HOME/esp/esp-idf/export.sh完成以上步骤后输入idf.py --version应该能正常显示信息。如果克隆仓库太慢可以考虑使用Gitee的镜像源。手动安装虽然步骤稍多但能清晰看到每一步在做什么出了问题也容易排查。3.3 RainMaker项目创建与设备端代码解析接下来我们基于ESP-IDF和RainMaker SDK创建一个新项目。乐鑫提供了丰富的示例我们可以从rainmaker示例开始修改。cd ~/esp cp -r $IDF_PATH/examples/rainmaker/switch my_lpg_detector cd my_lpg_detector这个“switch”示例实现了一个简单的开关。我们需要将其改造成燃气探测器。核心修改在main/app_main.c和main/app_priv.h/.c文件中。第一步定义设备参数在app_priv.h中我们定义设备类型和参数。RainMaker中的“设备”由多个“参数”组成。// app_priv.h #define ESP_RMAKER_DEF_DEVICE_NAME Smart LPG Detector #define ESP_RMAKER_DEF_DEVICE_TYPE sensor.lpg // 定义参数名字符串常量 static const char *PARAM_GAS_CONC gas_concentration; static const char *PARAM_ALERT_THRESHOLD alert_threshold; static const char *PARAM_ALERT_ENABLE alert_enable;第二步初始化设备并添加参数在app_priv.c的app_priv_init()函数中我们创建设备并为其添加参数。// app_priv.c esp_rmaker_device_t *lpg_sensor; esp_rmaker_param_t *gas_conc_param, *threshold_param, *alert_enable_param; void app_priv_init(void) { // 1. 创建设备 lpg_sensor esp_rmaker_device_create(ESP_RMAKER_DEF_DEVICE_NAME, ESP_RMAKER_DEF_DEVICE_TYPE, NULL); // 2. 创建“气体浓度”参数只读浮点数单位ppm gas_conc_param esp_rmaker_param_create(PARAM_GAS_CONC, ESP_RMAKER_VAL_TYPE_FLOAT, esp_rmaker_float(0.0), PROP_FLAG_READ | PROP_FLAG_TIME_SERIES); esp_rmaker_device_add_param(lpg_sensor, gas_conc_param); // 3. 创建“报警阈值”参数可读可写浮点数单位ppm默认值2000 threshold_param esp_rmaker_param_create(PARAM_ALERT_THRESHOLD, ESP_RMAKER_VAL_TYPE_FLOAT, esp_rmaker_float(2000.0), PROP_FLAG_READ | PROP_FLAG_WRITE); esp_rmaker_device_add_param(lpg_sensor, threshold_param); // 4. 创建“报警使能”参数可读可写布尔值默认true alert_enable_param esp_rmaker_param_create(PARAM_ALERT_ENABLE, ESP_RMAKER_VAL_TYPE_BOOLEAN, esp_rmaker_bool(true), PROP_FLAG_READ | PROP_FLAG_WRITE); esp_rmaker_device_add_param(lpg_sensor, alert_enable_param); // 5. 将设备添加到RainMaker节点 esp_rmaker_node_add_device(rmaker_node, lpg_sensor); }第三步读取传感器并更新参数值我们需要一个定时任务周期性地读取MQ-5传感器的ADC值将其转换为ppm浓度并更新到RainMaker参数中。同时要判断是否超过阈值并触发报警。ADC读取和转换是关键。首先ESP32的ADC是12位精度0-4095对应0-3.3V电压。MQ-5模块的AO引脚输出电压Vout与气体浓度Rs/R0的关系需要参考其数据手册中的曲线图。通常我们需要先在洁净空气中测量一个基准电压V0计算出对应的R0。然后根据实时电压Vout计算Rs再通过Rs/R0的比值在曲线图上查找或通过公式估算ppm值。这是一个近似过程。一个简化的处理流程代码如下位于一个单独的传感器任务中// sensor_task.c #include “driver/adc.h” #include “esp_adc_cal.h” static esp_adc_cal_characteristics_t *adc_chars; static float baseline_voltage 0.0; // 洁净空气下的基准电压 void sensor_task(void *pvParameter) { // 1. ADC初始化通道4 12位 3.3V量程 adc1_config_width(ADC_WIDTH_BIT_12); adc1_config_channel_atten(ADC1_CHANNEL_3, ADC_ATTEN_DB_11); // GPIO4 对应 ADC1_CHANNEL_3 adc_chars calloc(1, sizeof(esp_adc_cal_characteristics_t)); esp_adc_cal_characterize(ADC_UNIT_1, ADC_ATTEN_DB_11, ADC_WIDTH_BIT_12, 1100, adc_chars); // 参考电压1100mV // 2. 在设备启动预热后读取100次取平均作为洁净空气基准电压V0 vTaskDelay(pdMS_TO_TICKS(30000)); // 等待30秒预热 int sum 0; for(int i0; i100; i) { sum adc1_get_raw(ADC1_CHANNEL_3); vTaskDelay(pdMS_TO_TICKS(10)); } baseline_voltage esp_adc_cal_raw_to_voltage(sum/100, adc_chars) / 1000.0; // 转换为伏特 while(1) { // 3. 周期性读取当前电压 int raw adc1_get_raw(ADC1_CHANNEL_3); float current_voltage esp_adc_cal_raw_to_voltage(raw, adc_chars) / 1000.0; // 4. 简化计算电压比反映电阻比。浓度越高传感器电阻Rs越低分压点电压Vout越高。 // 假设在洁净空气中 Rs/R0 1 Vout Vcc * RL/(R0RL)。 // 当气体存在时Rs变小Vout变大。我们可以用一个简单的线性关系来模拟ppm ≈ k * (V_current - V_baseline) // 这里的k需要根据传感器特性和电路实际校准。这里用一个示例系数。 float estimated_ppm 5000.0 * (current_voltage - baseline_voltage); if(estimated_ppm 0) estimated_ppm 0; // 5. 更新RainMaker参数值 esp_rmaker_param_update_and_report(gas_conc_param, esp_rmaker_float(estimated_ppm)); // 6. 读取当前的阈值和报警使能状态需要从RainMaker参数中获取这里简化表示 float threshold get_current_threshold_from_rainmaker(); // 需要实现此函数 bool alert_enabled get_current_alert_enable_from_rainmaker(); // 7. 判断并触发报警 if(alert_enabled estimated_ppm threshold) { // 触发本地声光报警 gpio_set_level(BUZZER_GPIO, 1); gpio_set_level(LED_GPIO, 1); // 触发RainMaker告警事件 esp_rmaker_raise_alert(“gas_leak_detected”, “Danger! LPG concentration exceeded safe limit.”, ESP_RMAKER_ALERT_SEVERITY_CRITICAL); // 报警持续直到浓度降低 while(estimated_ppm threshold * 0.8) { // 降到阈值的80%以下才停止 vTaskDelay(pdMS_TO_TICKS(1000)); // ... 重新读取浓度 } gpio_set_level(BUZZER_GPIO, 0); gpio_set_level(LED_GPIO, 0); } vTaskDelay(pdMS_TO_TICKS(2000)); // 每2秒采样一次 } }第四步编译与烧录代码修改完成后回到项目根目录进行配置、编译和烧录。# 设置目标芯片 idf.py set-target esp32s3 # 打开配置菜单重要在这里配置Wi-Fi和RainMaker idf.py menuconfig在menuconfig中需要配置Component config - ESP RainMaker - RainMaker MQTT Configuration启用。Example Configuration设置Wi-Fi SSID和密码用于首次配网后续可通过App更改。根据你的开发板配置正确的串口端口。# 编译 idf.py build # 烧录到设备 idf.py -p /dev/ttyUSB0 flash monitor # 指定你的串口并打开串口监视器烧录成功后设备会重启。在串口监视器中你会看到设备启动并打印出一个二维码和一组配对码。4. 设备配网、手机绑定与报警测试硬件和固件就绪后最后一步是让设备融入你的智能家居网络并在手机上接收警报。4.1 使用ESP RainMaker App完成配网与绑定在手机应用商店搜索“ESP RainMaker”并安装。打开App注册/登录你的乐鑫账号。确保手机连接到2.4GHz Wi-Fi网络ESP32不支持5GHz。在App首页点击“”添加设备选择“扫描二维码”。用手机摄像头扫描串口监视器中显示的二维码。App会自动获取设备的配对码。按照App指引选择你要让设备连接的家庭Wi-Fi网络并输入密码。等待片刻配网成功。设备会出现在你的设备列表中名称是“Smart LPG Detector”。现在点击这个设备你就能在App里看到我们定义的三个参数当前气体浓度gas_concentration、报警阈值alert_threshold和报警开关alert_enable。你可以直接在App上修改阈值和开关状态修改会实时同步到设备上。这就是RainMaker带来的便捷交互。4.2 模拟泄漏测试与报警验证安全测试不要用真实的液化气进行测试。我们可以用打火机气体丁烷或高度白酒挥发的酒精蒸汽来模拟因为它们的主要成分也能被MQ-5检测到。在App中将报警阈值暂时调低到一个容易触发的值比如500 ppm模拟测试用实际LPG报警阈值通常在1000-5000 ppm范围内需参考安全标准。确保alert_enable为开启状态。取少量测试气体如轻轻按压打火机但不要点火在传感器附近缓缓释放。观察设备本地蜂鸣器应该立刻响起LED闪烁。几乎同时你的手机应该会收到一条来自“ESP RainMaker”的推送通知标题和内容就是我们代码里设置的“Danger! LPG concentration exceeded safe limit.”。移开测试气体等待浓度下降。浓度低于阈值后本地报警停止。至此一个完整的、具备远程手机报警功能的智能LPG探测器就成功运行了。你可以把它安装在厨房靠近地面LPG比空气重的位置接通USB电源它就会7x24小时默默守护。5. 深入优化与生产级考量一个能用的原型和一台可靠的产品之间还有很长的路要走。如果你打算把这个项目做得更扎实甚至小规模使用以下几个方面的优化至关重要。5.1 传感器校准与数据滤波前面的简化计算ppm ≈ k * (V_current - V_baseline)在实际应用中误差会很大。真正的校准需要标准气体。业余条件下我们可以采用“两点校准法”来逼近第一点零点在确信洁净的空气中记录此时的电压V_clean。认为此时浓度为0 ppm。第二点标定点购买一瓶已知浓度如2000 ppm的LPG标准气体小容量实验用或者用一个更专业、已校准的便携式检测仪作为参考。向传感器通入该气体稳定后记录电压V_2000。计算斜率kk 2000 / (V_2000 - V_clean)。应用公式ppm k * (V_current - V_clean)。这样得到的数值会比简单线性系数准确得多。此外ADC读取存在波动需要对原始数据进行软件滤波。常用的有滑动平均滤波或中值滤波。例如连续读取10次去掉最大最小值后求平均能有效消除偶发的尖峰干扰。5.2 低功耗深度睡眠策略为了实现电池供电下的超长续航必须利用ESP32的深度睡眠功能。MQ-5传感器本身功耗不低约150mA不能一直开着。改进方案如下使用数字输出DO引脚将MQ-5的DO引脚连接到ESP32的一个GPIO配置为外部中断引脚。在MQ-5模块上通过电位器设置一个较低的硬件比较阈值。常态深度睡眠ESP32配置为深度睡眠模式仅RTC模块和少数GPIO用于唤醒的GPIO保持供电。中断唤醒当气体浓度超过MQ-5模块自设的硬件阈值时其DO引脚电平翻转例如从高变低这个变化触发ESP32的外部中断将其从深度睡眠中唤醒。唤醒后处理ESP32唤醒后首先开启完整的传感器供电然后使用ADC进行高精度采样和计算确认浓度是否真的超过我们设定的软件阈值。如果确认则启动Wi-Fi连接RainMaker发送警报。如果没有超过则等待一段时间后再次进入深度睡眠。这种“硬件粗判 软件精判”的模式可以确保99.9%的时间ESP32都在深度睡眠中功耗可能低于100μA极大地延长了电池寿命。5.3 提高系统可靠性看门狗与状态恢复物联网设备最怕死机。尤其是涉及安全的设备必须要有自我恢复的能力。硬件看门狗ESP32内置了硬件看门狗定时器。在固件中启用它并在主循环中定期“喂狗”。如果程序跑飞或陷入死循环看门狗超时会导致系统自动重启。网络异常处理Wi-Fi连接可能失败与RainMaker云端的连接也可能中断。代码中必须有健全的重试机制和超时判断。例如尝试连接Wi-Fi最多3次每次间隔30秒如果都失败则进入一个“故障安全模式”——仅保持本地高灵敏度报警并闪烁LED指示网络故障。参数掉电保存用户通过App设置的报警阈值应该保存在ESP32的NVS非易失性存储中。这样即使设备断电重启也能恢复之前的设置而不是变回代码里的默认值。5.4 功能扩展从推送到电话与多平台集成RainMaker的推送通知已经很实用但万一手机没网或通知被屏蔽呢我们可以进一步扩展集成电话报警服务可以使用像Twilio、Nexmo这样的第三方云通信服务。当RainMaker触发告警事件后可以通过这些服务提供的API直接拨打预设的电话号码播放语音警报。这需要在RainMaker的Webhook功能或者自己搭建一个简单的云函数来实现事件转发。接入其他智能家居平台通过RainMaker的API可以将设备状态同步到Google Home、Amazon Alexa或苹果HomeKit。这样你除了收到手机推送还可以让家里的智能音箱大声播报警报。历史数据记录与分析RainMaker支持将设备参数的时间序列数据存储一段时间。你可以定期查看气体浓度的变化曲线了解厨房环境的基线情况甚至发现微小的、缓慢的泄漏趋势。这个项目从一次安全担忧开始到最终成为一个功能完备的智能安防设备整个过程充满了硬件、软件和云端联调的挑战与乐趣。它不仅仅是一个简单的传感器读数上传更涉及了传感器特性理解、低功耗设计、物联网协议、云平台集成和用户体验等多个层面的知识。最重要的是通过自己的双手打造了一个真正能守护家人安全的实用工具这种成就感是无可替代的。在实际部署时请务必定期测试其报警功能并至少每年检查一次传感器是否失效因为任何安全设备维护和测试都与安装同等重要。