基于 ESP8266 的适合听障人士需求的 domotic 系统(代码)


原标题:基于 ESP8266 的适合听障人士需求的 domotic 系统(代码)
一、系统概述
该基于ESP8266的智能家居(domotic)系统针对听障人士的特殊需求进行设计与开发。整个系统以ESP8266微控制器为核心,结合多种传感器、通信模块以及视觉与振动反馈装置,实现对家庭环境状态的实时监测与告警,并在告警发生时以灯光、OLED显示屏和振动马达等方式提醒听障用户。同时提供手机App或Web界面,使用户可远程查看家中各项数据并进行控制。系统的整体功能包含门窗开关监测、烟雾与气体泄漏检测、红外人体感应、室内温湿度采集、紧急按钮触发等;当出现异常时,通过LED光源闪烁、OLED图文显示或小型振动马达震动,迅速吸引听障用户注意。此外,系统支持与手机App进行Wi-Fi通信,可将过往告警记录存储在云端服务器,方便用户随时查询历史警报信息。
本系统设计目标是:硬件成本低廉且易于扩展;对听障人士友好,采用多种非声音方式告警;易于组网部署并兼容主流智能家居平台;具有可靠性、稳定性与可维护性。为了满足上述目标,本文从核心芯片选型、传感器与执行器优选、通信模块与电源设计、软件架构与代码实现等方面进行详细阐述,并给出核心代码示例与硬件连接示意。
二、核心控制单元:ESP8266微控制器
ESP8266是由乐鑫科技(Espressif Systems)推出的低成本、低功耗Wi-Fi系统级芯片(System on Chip,SoC),集成了TCP/IP协议栈及完整的Wi-Fi功能。其典型型号包括ESP-01、ESP-07、ESP-12E/ESP-12F等。其中,ESP-12E模块拥有8个通用输入输出(GPIO)引脚、丰富的SPI、I²C、UART接口,功耗低 (<170mA TX),价格在10元人民币左右,国内外均有大量供应,技术资料与社区支持十分完善。
选择ESP-12E的原因如下:首先,其具备高性能的32位处理器(基于Tensilica L106架构,80MHz主频),可满足多任务并发,如传感器数据采集、Wi-Fi通信、OLED显示与振动控制等;其次,其封装精巧(尺寸约为24mm×16mm),可直接焊接到开发板或自制PCB上;第三,其配备4MB闪存,足以存储固件、日志与网页静态资源;第四,电源电压3.3V,与多数传感器兼容;最后,Arduino Core for ESP8266开源生态成熟,开发者可快速移植Arduino风格代码,降低开发难度。
本设计以ESP-12E模块作为主控芯片,并选用Wemos D1 Mini开发板作为原型开发平台。Wemos D1 Mini的尺寸更小(约34.2mm×25mm)、自带USB转串口芯片(CH340G)、提供5V与3.3V稳压输出,便于通过Micro USB端口供电与固件烧录。使用Arduino IDE时,只需安装对应开发板管理器(Boards Manager)即可像UNO一样快速编写、上传代码。
三、电源设计与稳压模块
ESP8266在Wi-Fi通信高峰期工作电流可达300mA左右,建议预留至少500mA的电流裕度。因此,整个系统电源需设计为输出稳定的5V电压,再通过3.3V稳压器为ESP-12E及其他3.3V传感器供电。
优选元器件型号:
AMS1117-3.3V线性稳压器
器件作用:将外部5V电源(如手机充电器或充电宝灯座)稳定降压至3.3V,驱动ESP8266与大部分3.3V传感器。
选择理由:AMS1117-3.3V是一款常见的线性稳压器,输出电流可达800mA,封装为SOT-223或TO-252,散热面积足够。其输入最大电压15V,输出误差小(典型100mV),价格低廉(约1元人民币),易于采购。缺点是线性稳压转化效率较低,但在5V降至3.3V电压差不大时,功耗损耗可接受,且整体功耗不高于1W。
功能:为ESP8266及部分3.3V传感器(如DHT11、HC-SR501、MQ-2等)提供稳定电压。
LM2596S开关稳压模块(直插式)
器件作用:当系统电源为12V电源适配器或车载电源时,将输入电压高效转换至5V,用于为整个系统供电或为5V传感器供电。
选择理由:LM2596S可支持3A输出电流,效率可达90%以上,封装直插,广泛应用于DIY智能家居;具有过流、过热保护且价格便宜(约5元人民币)。对于需要更长供电时间的应用,可接配大容量电池组,使用开关稳压降低功耗。
功能:为整体系统(含USB转串口、5V继电器模块、视觉告警灯等)提供高效5V电压输出。
USB充电模块(Micro USB口引入)
器件作用:使用常见的5V手机适配器供电,直接为Wemos D1 Mini开发板供电。
选择理由:Wemos D1 Mini自带Micro USB接口,直接连接即可;节省设计工时与成本。若产品化可考虑在PCB上直接集成USB接口,并配合AMS1117-5.0V或更高效率的同步升压模块。
钛酸锂电池与TP4056充电模块(可选)
器件作用:当需要无线便携或断电情况下继续运行时,可选用锂电池供电;TP4056模块负责对锂电池进行恒流恒压充电管理。
选择理由:TP4056价格便宜(约3元人民币),支持1A充电电流,可通过USB给锂电池充电;锂电池容量可根据实际需求选定(如18650 2000mAh)。装置可实现断电后持续工作,提升系统可靠性。
功能:为ESP8266与传感器提供备用电源,实现断电通知与故障自救。
四、传感器模块优选
为了满足听障人士对家居安全与环境状态的可视化监测需求,系统设计中选用多种传感器模块,具体如下:
PIR人体红外传感器 (HC-SR501)
器件作用:检测人体活动,当有人在其监测范围内移动时输出高电平信号。可用于门厅、卧室、客厅等地点的入侵检测或人员进出监测。
选择理由:HC-SR501具有高灵敏度(可调灵敏度及延迟时间),输出信号为TTL电平,工作电压5V,静态功耗低(仅约50µA),带有定时器与灵敏度可调电位器,可实现从5秒至5分钟的延迟时间调节。其售价便宜(约5元人民币),市场应用广泛,配套资料齐全。
功能:在检测到人体时向ESP8266的GPIO口(3.3V容忍)输出高电平,触发OLED屏显示“有人活动”或闪烁LED灯并振动马达提醒听障者。
烟雾传感器 (MQ-2烟雾燃气传感器模块)
器件作用:检测空气中可燃气体(如天然气、液化气、酒精、烟雾)。当浓度超过一定阈值时输出模拟电压,可通过ADC口读取并判断是否超过告警值。
选择理由:MQ-2传感器灵敏度高、种类检测范围广(可检测丙烷、甲烷、丁烷、液化气、烟雾等),响应时间短(小于10秒),使用寿命长(约5年),标准化模块中已集成电平输出和模拟输出两种信号,输出端带LED指示。其工作电压为5V(模块自带电压调节),其价格约10元左右,广泛应用于DIY烟雾报警系统。
功能:当检测到烟雾浓度超过设定阈值时,通过ESP8266的模拟输入(A0)读取电压值并判断“烟雾告警”,触发OLED显示“烟雾浓度过高”、LED灯闪烁并通过振动马达提醒听障人士,并可发送告警信息至手机端。
可燃气体传感器 (MQ-135空气质量传感器模块)
器件作用:检测空气中氨气、硫化物、苯蒸气、烟雾等多种有害气体。适用于室内空气质量检测与安全告警。
选择理由:在厨房或家中燃气管道周围,MQ-135可实时监测有毒有害气体浓度,当浓度超标时发出告警;相比MQ-2,MQ-135更加灵敏于有害气体检测,适配室内空气质量监测需求;价格适中(约15元人民币),模块化方便;工作电压同样为5V。
功能:将模拟输出连接至ESP8266的ADC口,对空气质量进行周期性采样;当浓度超过设定值时触发告警。
温湿度传感器 (DHT22/AM2302)
器件作用:采集环境温度与相对湿度数据,并通过单线协议将数字量传输给ESP8266。
选择理由:相比DHT11(精度较低,湿度±5%,温度±2℃,测量范围有限),DHT22具有更高精度(湿度±2%,温度±0.5℃)、更宽测量范围(湿度0100%,温度-4080℃)、响应速度更快、可靠性更高。价格约25元左右,库函数成熟,硬件接线简单,直接连接到ESP8266的3.3V和GPIO引脚,极少占用资源,且功耗低。
功能:定时采集室内温湿度,若温度异常(如高于设定阈值或过低),可在OLED上显示相应提示并通过LED灯告知;数据上传至云端后,可在手机App中查看并进行远程调控(如启动空调或加湿器)。
门磁开关 (磁簧开关模块)
器件作用:由磁簧管与磁铁组成,安置在门框与门扇上,当门打开或关闭时,传感器开关状态变化,输出数字信号。
选择理由:磁簧开关成本低廉(约3元人民币),安装简便,可靠性高,抗干扰能力强;只有两根导线连接,直接接至ESP8266的GPIO口即可读取高低电平状态,形成“门开/门关”逻辑。
功能:实时监测门窗状态,若在特定时间(如夜间)检测到门窗异常打开,可触发提醒,以振动马达或者LED灯闪烁等方式告知听障者。
OLED显示屏 (SSD1306 0.96寸 I²C OLED 模块)
器件作用:基于SSD1306控制芯片,分辨率128×64,可通过I²C接口(接SDA、SCL)与ESP8266通信,显示文字、图形或图标。
选择理由:相比LCD,OLED功耗更低、对比度更高、显示效果更佳,可视角度大,室内光线暗时显示清晰。0.96寸尺寸适中,可放置于墙面或桌面供听障者近距离查看。模块价格约20元人民币,Arduino库(如U8g2)支持完善,易于绘制文字和简单图形。
功能:实时显示当前系统状态文字(如“烟雾正常”、“人体未检测到”、“门正常关闭”、“温度:25℃”等)及告警图标,当告警发生时可闪烁显示“告警”信息,提醒用户注意。
LED指示灯 (WS2812B全彩RGB LED灯带或简易单色高亮LED)
器件作用:用于视觉告警,通过不同颜色或闪烁频率表示不同状态。例如红色闪烁表示烟雾告警,黄色闪烁表示可燃气体告警,绿色常亮表示正常。
选择理由:WS2812B是数字信号控制,可通过单引脚控制多颗灯珠,灵活度高;若项目中需要多点分布式告警,可使用灯带并通过ESP8266对其进行寻址控制;若仅需单点提示,则选用高亮度单色LED(正向电压约2V,可限流电阻后直接与ESP8266 GPIO连接)。WS2812B模块价格在15元/1米左右;普通LED更便宜(几角到一两元不等)。
功能:在不同告警来源(烟雾、气体、门窗、人体)下,以不同颜色或者闪烁频率进行视觉提示。WS2812B还可以显示渐变动画,提升提示醒目度。
振动马达 (直径8mm偏心振子)
器件作用:将电信号转换为机械振动,贴附于床铺、桌面或腕带,当系统检测到紧急告警时,通过振动方式提醒听障者。
选择理由:振动马达体积小功耗低,可由GPIO通过电源驱动并且使用一个小型NPN三极管(如2N2222)做开关即可驱动5V振动马达;当LED灯或OLED提示不足以引起注意时,振动能确保用户在睡眠或远离显示屏时仍能收到告警。该振动马达售价仅约5元人民币,寿命长达数千小时,易于采购。
功能:在系统检测到烟雾浓度过高或可燃气体泄漏、门窗异常开启、紧急按钮按下等情况时,立即以频闪振动的形式提醒听障者前往检查。
紧急按钮模块(带背光指示灯的按键开关)
器件作用:当听障者遇到紧急情况(如跌倒、突发疾病等)需要呼救时,手动按下按钮,ESP8266检测到按键输入后,通过Wi-Fi向云服务器或手机App发送紧急呼叫信号,并触发家中视觉与振动告警装置。
选择理由:选用带背光的轻触按键(如9mm方形自锁式带LED背光的按键开关),可在暗光环境下仍能定位;开关触点质量好,可承受大于100万次按压。模块价格约10元人民币。
功能:用户按下紧急呼叫时,ESP8266检测到电平变化,将“紧急呼叫”指令发送至云端,并在本地触发振动马达与LED光源联合闪烁,同时OLED屏显示“紧急呼叫已发送”。
五、执行器与反馈装置
继电器模块 (SRD-05VDC-SL-C继电器×1路/4路模块)
器件作用:当需要远程控制高电压设备(如家用照明、电动门锁、抽油烟机等)时,通过ESP8266的GPIO信号驱动继电器线圈,实现对外部高压(220VAC或直流电路)的通断。
选择理由:常见的SRD-05VDC-SL-C继电器价格仅5-10元,支持10A/250VAC或10A/30VDC开关容量,可直接模块化使用(模块带光耦隔离、驱动三极管与指示LED),充分保证ESP8266安全。模块采用螺丝端子接线,便于改装与维护。
功能:当用户通过手机App下达“开灯”“关闭电器”指令时,ESP8266控制继电器模块,实现对家中电器的远程控制;在紧急情况下也可远程断电,保证安全。
蜂鸣器(仅作调试时使用,不用于正式告警)
器件作用:用于系统调试阶段的声音告警,帮助开发者了解逻辑流程正常与否;在发布给听力正常用户的场景下可通用。
选择理由:为了专门针对听障用户,本系统在正式环境中并不使用蜂鸣器。但在开发与调试阶段,借助蜂鸣器便于快速定位问题。常见独立式有源蜂鸣器价格低廉(约2元人民币)。
功能:当系统检测到异常时,蜂鸣器响起短促音,提示开发人员检查系统;产品化时可移除或不焊接蜂鸣器模块。
OLED与LED配合视觉告警
器件作用:通过OLED文字与图标直观向用户展示告警类型与状态;LED灯可在视线范围外仍然吸引注意力。
选择理由:视觉显示与闪烁灯光为听障者提供最直接、最强烈的告警方式;相比仅靠振动,视觉反馈可以传递更多丰富信息(例如“烟雾浓度:876ppm,危险等级高,请立即核实”;“门打开时间:2025-06-03 22:15”);OLED可持续显示信息无需外部背光;LED闪烁速度与颜色可自定义。
功能:在静默环境中,如果听障者在书房或卧室未带设备,可通过窗口或墙面上安装的LED灯闪烁与门口处的OLED屏体现告警,全方位覆盖家庭生活空间。
振动提示带(或腕带)
器件作用:将振动马达安装在腕带中,当系统触发紧急告警时,通过腕带振动让用户及时感知。
选择理由:振动腕带可随身携带,不受房间位置限制,即使身处浴室等听障者无法靠近主控单元,也能及时收到告警;市场常见振动腕带的振动强度与功耗均符合ESP8266 5V或3.3V供电需求,价格在20-30元人民币之间。
功能:紧急告警时,ESP8266通过Wi-Fi将信号发送给腕带(可集成一个小型另行控制的ESP8266-NORF模块或使用蓝牙模块ESP32/NRF52832),触发腕带振动。腕带可持续振动10-20秒,直到听障者查看告警。
六、通信方案与软件架构
为保证系统在Wi-Fi环境下的稳定性与可扩展性,软件架构分为以下几层:
底层驱动层(Sensors & Actuators)
包括DHT22、MQ-2、MQ-135、HC-SR501、门磁开关、继电器、OLED、WS2812B LED灯和振动马达的底层控制驱动。每个传感器与执行器通过统一的类或函数封装,实现初始化、读取/写入、状态更新与告警触发。此层代码基于Arduino库或自定义驱动函数。
逻辑控制层(Logic)
实现对各传感器数据进行定时采集、预处理与分析。例如,MQ-2的模拟量读取后需计算与基准值(EEPROM存储或者云端下发)的比值,判断是否达到告警阈值;HC-SR501触发后,可启动一个延时定时器,避免误报;门磁开关状态发生变化时,先对抖动进行软件消抖后再确认状态。逻辑层统一以“事件驱动”方式处理,当某个传感器状态变化超过阈值或出现梯度变化时,生成事件并传递至告警层与通信层。
告警与反馈层(Alert & Feedback)
紧急级别(如烟雾浓度急剧升高、门窗异常持续超过1分钟):同时触发OLED全屏红色闪烁提示、WS2812B红灯快速闪烁、振动马达连续振动、并向云端发送告警数据;
中等级别(如可燃气体浓度略高、人体红外检测到动态但在非报警时间段出现异常):在OLED屏显示黄色警示图标,LED灯缓慢闪烁,振动短促一次;
信息级别(如正常温湿度更新、门窗正常打开等):OLED小窗口滚动显示状态更新,无LED闪烁。
根据逻辑控制层传递的事件类型,决定告警方式与优先级。例如:
此层还负责记录事件日志(时间戳、事件类型、传感器数据)并写入EEPROM或SD卡(如ESP8266外接的SPI Flash或通过SPI连接的SD卡)。
通信与远程控制层(Communication)
MQTT协议:轻量级、QoS可定制,适合物联网场景,常用开源服务端如Mosquitto;手机App可使用MQTT客户端订阅相应主题(Topic),实时接收告警与数据更新。
HTTP/RESTful API:ESP8266可搭建简易Web Server,定义RESTful接口,如GET /status、POST /control,当手机App发起请求时,ESP8266返回JSON格式数据或执行相应命令。
利用ESP8266的Wi-Fi功能接入家庭路由器,实现与手机App或云服务器(MQTT Broker或HTTP Server)通信。通信协议可选:
本系统示例中选用MQTT协议,借助Public MQTT Broker(如test.mosquitto.org)进行测试,正式部署可搭建私有服务器(如树莓派+Mosquitto)。通信流程如下:
ESP8266启动后,通过Wi-Fi连接到预设SSID,获取动态IP;
登录MQTT Broker,并订阅主题“home/alert”和“home/control”;
当事件触发时,ESP8266将告警信息以JSON字符串形式发布到主题“home/alert”,内容包括“type”(烟雾/可燃气/人体/门窗/紧急呼叫)、“level”(0~2)、“value”(传感器原始数值)、“timestamp”;
手机App或其它客户端订阅到该主题后,在界面上弹出告警提示并保存历史记录;
当用户在App上发送控制指令(如“打开客厅灯”、“关闭继电器2”)时,以JSON格式发布至主题“home/control”,ESP8266订阅到后解析指令并控制继电器。
人机交互层(HMI)
在本地提供OLED显示以及LED灯光与振动马达反馈;同时在手机App或Web前端提供界面,显示实时传感器数据、告警历史记录、远程控制开关列表。App可采用Android Studio开发,或使用Blynk、Node-RED等低代码平台快速搭建界面,方便听障用户远程查看与控制。
七、电路连接与PCB设计建议
电源部分
设计从外部5V电源(如手机充电器、USB插口、DC电源模块)引入5V,先连接LM2596模块(若输入为12V)再输出5V。将5V分支:一部分输入至Wemos D1 Mini的USB或5V引脚供电;另一部分通过AMS1117-3.3V降压至3.3V,再分配给ESP-12E和所有3.3V传感器(需在每个传感器模块上并联规格为0.1µF–10µF电解电容和0.1µF陶瓷电容以滤波)。
ESP-12E引脚分配
GPIO0:连接MQTT配置按钮(短按进入Wi-Fi AP配置模式),平常拉高;
GPIO2:连接OLED的SDA;
GPIO14:连接OLED的SCL;
GPIO13:连接DHT22数据线;
GPIO12:连接MQ-2模块的模拟输出(A0仅有一个ADC,不够时可使用电平转换或者分时采样);若使用电平分压电路,则ADC0用于MQ-2与MQ-135兼容;
GPIO5:连接PIR输出(高电平表示有人移动);
GPIO4:连接门磁开关信号(常闭类型,门关时输出低电平);
GPIO15:连接继电器驱动模块输入端(通过光耦隔离);
GPIO16:连接MQTT配置指示LED;
GPIO0/2/15均需正确配置上拉/下拉电阻,保证模块正常启动(如GPIO15需下拉至GND,GPIO0和GPIO2需拉高至3.3V)。
传感器与执行器连线
DHT22:VCC→3.3V,GND→GND,DATA→GPIO13,DATA与VCC之间上拉4.7kΩ电阻;
MQ-2与MQ-135:模块VCC→5V,GND→GND,模拟输出A0接至ESP8266的ADC(仅有一个ADC,如需多路ADC可选购外置ADS1115 I²C ADC模块,价格约30元)。若使用内置ADC,则在硬件上加装一个简单多路模拟开关(如CD4051B,约5元),由GPIO控制多路切换并串接ADC;
HC-SR501:VCC→5V,GND→GND,OUT→GPIO5;OUT高电平时GPIO5读取到3.3V电平(需测试是否直接匹配,若输出5V则需串联一个限流电阻或电平转换模块);
门磁开关:常开或常闭输出端(无源接口)一端接3.3V,另一端接GPIO4和一个10kΩ下拉电阻;不开关时GPIO4读取低电平,关门时磁铁吸合GPIO4短接3.3V。
OLED (SSD1306):VCC→3.3V,GND→GND,SDA→GPIO2,SCL→GPIO14;
WS2812B LED:VCC→5V,GND→GND,DIN→GPIO0或任意支持PWM的GPIO;在DIN与GPIO之间串联一个330Ω电阻以抑制信号振荡,LED旁并联一个1000µF/6.3V电解电容进行电源滤波;
振动马达:VCC→5V,通过NPN三极管(2N2222)集成到地图板上,基极接至GPIO12(需加1kΩ限流电阻),发射极接GND;这样当GPIO12输出高电平时,驱动三极管导通,振动马达获得5V电压;
继电器模块:VCC→5V,GND→GND,IN→GPIO15,通过模块上的光耦隔离与三极管驱动实现ESP8266与220VAC/直流设备的安全隔离。
PCB设计建议
采用双面板设计,将ESP-12E模块放置于PCB一侧中部,预留USB母座接口区域,用于固件更新。
在ESP8266电源输入处与AMS1117-3.3V稳压器之间放置输入电容(10µF)与输出电容(22µF)以稳定电压;同时在AMS1117输出端并联0.1µF陶瓷电容消除高频噪声。
将模拟信号(A0)与大功率继电器、振动马达等部分隔离布局,防止干扰,模拟信号线尽量走短并靠近接地平面。
在继电器与振动马达电路部分增加二极管(1N4007)作为线路反向浪涌保护,并且在继电器驱动脚并联0.1µF陶瓷电容抑制电磁干扰;
在关键传感器(如MQ-2、MQ-135)模块附近预留可调电位器空间,以调整灵敏度;在PIR与门磁开关等数字传感器输入引脚处并联一个104(0.1µF)去耦电容,消除高频抖动;
在PCB边缘预留2×4针排针,用于连接外部OLED、按钮与继电器等,方便拆装与调试;同时为方便扩展,可预留I²C、UART与SPI接口引出。
八、软件实现与代码示例
本节以Arduino IDE为开发环境,使用C++语言编写ESP8266固件。主要逻辑包含:Wi-Fi与MQTT连接管理、传感器初始化与读取、事件触发与告警处理、远程控制命令解析。本示例代码适用于ESP-12E开发板(Wemos D1 Mini亦可直接移植,仅需在开发板选择中选定“LOLIN(Wemos) D1 R2 & Mini”)。
/**************************************************
* 文件名:deaf_friendly_domotic.ino
* 功能:ESP8266实现针对听障人士的智能家居系统
* 硬件:ESP-12E (或Wemos D1 Mini)、DHT22、MQ-2、MQ-135、
* HC-SR501、门磁开关、SSD1306 OLED、WS2812B RGB LED、
* 振动马达、继电器模块、紧急按钮(按键)
* 开发环境:Arduino IDE 1.8.x
* 依赖库:ESP8266WiFi.h、PubSubClient.h、Adafruit_SSD1306.h、
* Adafruit_GFX.h、DHT.h、FastLED.h
**************************************************/
#include <ESP8266WiFi.h>
#include <PubSubClient.h>
#include <Adafruit_SSD1306.h>
#include <Adafruit_GFX.h>
#include "DHT.h"
#include <FastLED.h>
/*-------------------宏定义区-------------------*/
#define DHTPIN D1 // DHT22数据引脚连接至GPIO5(D1)
#define DHTTYPE DHT22 // DHT22型号
#define PIR_PIN D5 // HC-SR501输出引脚GPIO14(D5)
#define MAGNET_PIN D4 // 门磁开关信号GPIO2(D4)
#define RELAY_PIN D8 // 继电器输入GPIO15(D8)
#define VIB_PIN D6 // 振动马达驱动GPIO12(D6)
#define BUTTON_PIN D3 // 紧急按钮输入GPIO0(D3)
#define LED_PIN D7 // WS2812B数据引脚GPIO13(D7)
#define NUM_LEDS 8 // WS2812B灯珠数量
#define SCREEN_WIDTH 128 // OLED宽度
#define SCREEN_HEIGHT 64 // OLED高度
#define OLED_RESET -1 // OLED重置脚,-1表示无
#define ANALOG_PIN A0 // ESP8266内置ADC
#define WIFI_SSID "Your_SSID" // Wi-Fi名称
#define WIFI_PASS "Your_PASS" // Wi-Fi密码
#define MQTT_SERVER "test.mosquitto.org" // 测试MQTT服务器
#define MQTT_PORT 1883
#define MQTT_CLIENTID "DeafDomotic_01"
#define MQTT_ALERT_TOPIC "home/alert"
#define MQTT_CONTROL_TOPIC "home/control"
#define TEMP_THRESHOLD 30 // 温度告警阈值(摄氏度)
#define HUM_THRESHOLD 70 // 湿度告警阈值(%)
#define GAS_THRESHOLD 300 // 可燃气体告警阈值(ADC值)
#define SMOKE_THRESHOLD 300 // 烟雾告警阈值(ADC值)
/*-------------------全局变量区-------------------*/
DHT dht(DHTPIN, DHTTYPE);
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
CRGB leds[NUM_LEDS];
WiFiClient espClient;
PubSubClient client(espClient);
bool pirState = false;
bool magState = false;
bool lastPirState = false;
bool lastMagState = false;
bool buttonState = false;
bool lastButtonState = false;
/*-------------------函数声明区-------------------*/
void setup_wifi();
void reconnect_mqtt();
void callback(char* topic, byte* payload, unsigned int length);
void readSensorsAndUpdate();
void publishAlert(const char* type, int value);
void displayStatus(const char* line1, const char* line2);
void visualAlert(uint8_t r, uint8_t g, uint8_t b, int flashes);
void vibrateAlert(int times, int duration);
int readGasSensor(); // 读取MQ-2/MQ-135模拟值
void handleControlCommand(char* payload, unsigned int length);
/*-------------------初始化函数-------------------*/
void setup() {
Serial.begin(115200);
pinMode(PIR_PIN, INPUT);
pinMode(MAGNET_PIN, INPUT_PULLDOWN_16);
pinMode(RELAY_PIN, OUTPUT);
pinMode(VIB_PIN, OUTPUT);
pinMode(BUTTON_PIN, INPUT_PULLUP);
digitalWrite(RELAY_PIN, LOW);
digitalWrite(VIB_PIN, LOW);
// 初始化WS2812B灯带
FastLED.addLeds<NEOPIXEL, LED_PIN>(leds, NUM_LEDS);
FastLED.clear();
FastLED.show();
// 初始化OLED
if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
Serial.println("OLED未连接");
while(true);
}
display.clearDisplay();
display.setTextSize(1);
display.setTextColor(SSD1306_WHITE);
// 初始化DHT传感器
dht.begin();
// 连接Wi-Fi与MQTT
setup_wifi();
client.setServer(MQTT_SERVER, MQTT_PORT);
client.setCallback(callback);
delay(2000);
displayStatus("系统初始化完成", "等待传感器数据");
delay(1000);
}
/*-------------------主循环函数-------------------*/
void loop() {
if (!client.connected()) {
reconnect_mqtt();
}
client.loop();
readSensorsAndUpdate();
delay(2000); // 每2秒更新一次数据
}
/*-------------------Wi-Fi连接函数-------------------*/
void setup_wifi() {
delay(10);
displayStatus("正在连接WiFi", WIFI_SSID);
WiFi.begin(WIFI_SSID, WIFI_PASS);
int retry = 0;
while (WiFi.status() != WL_CONNECTED && retry < 20) {
delay(500);
Serial.print(".");
retry++;
}
if (WiFi.status() == WL_CONNECTED) {
displayStatus("WiFi已连接", WiFi.localIP().toString().c_str());
Serial.println("");
Serial.println("WiFi已连接");
Serial.print("IP地址: ");
Serial.println(WiFi.localIP());
} else {
displayStatus("WiFi连接失败", "进入AP配置模式");
// 可扩展:进入AP模式,提供Web页面供用户重新配置Wi-Fi
}
}
/*-------------------MQTT重连函数-------------------*/
void reconnect_mqtt() {
while (!client.connected()) {
Serial.print("正在连接MQTT...");
if (client.connect(MQTT_CLIENTID)) {
Serial.println("已连接");
client.subscribe(MQTT_CONTROL_TOPIC);
displayStatus("MQTT已连接", "");
} else {
Serial.print("失败, rc=");
Serial.print(client.state());
Serial.println(" 尝试 5 秒后重连");
displayStatus("MQTT连接失败", "重连中...");
delay(5000);
}
}
}
/*-------------------MQTT消息回调函数-------------------*/
void callback(char* topic, byte* payload, unsigned int length) {
// 处理远程控制命令
handleControlCommand((char*)payload, length);
}
/*-------------------传感器读取与状态更新-------------------*/
void readSensorsAndUpdate() {
// 读取DHT22温湿度数据
float h = dht.readHumidity();
float t = dht.readTemperature();
if (isnan(h) || isnan(t)) {
Serial.println("DHT读取失败");
} else {
char buf1[32], buf2[32];
sprintf(buf1, "温度: %.1f C", t);
sprintf(buf2, "湿度: %.1f %%", h);
display.clearDisplay();
display.setCursor(0, 0);
display.print(buf1);
display.setCursor(0, 16);
display.print(buf2);
display.display();
Serial.println(buf1);
Serial.println(buf2);
// 判断温湿度告警
if (t > TEMP_THRESHOLD) {
publishAlert("TEMP_HIGH", (int)t);
visualAlert(255, 0, 0, 5); // 红色闪烁5次
vibrateAlert(3, 200); // 振动3次, 每次200ms
}
if (h > HUM_THRESHOLD) {
publishAlert("HUM_HIGH", (int)h);
visualAlert(255, 255, 0, 3); // 黄色闪烁3次
vibrateAlert(2, 200);
}
}
// 读取可燃气体与烟雾模拟值
int gasVal = analogRead(ANALOG_PIN); // 单ADC口示例,实际需多路切换
Serial.print("可燃气/烟雾 ADC: ");
Serial.println(gasVal);
if (gasVal > GAS_THRESHOLD) {
publishAlert("GAS_HIGH", gasVal);
visualAlert(255, 165, 0, 5); // 橙色闪烁5次
vibrateAlert(4, 150); // 振动4次
}
if (gasVal > SMOKE_THRESHOLD) { // 若需要区分可燃气与烟雾,可用分时采样或外接多路ADC
publishAlert("SMOKE_HIGH", gasVal);
visualAlert(255, 0, 0, 8); // 红色闪烁8次
vibrateAlert(5, 150); // 振动5次
}
// 读取PIR传感器
pirState = digitalRead(PIR_PIN);
if (pirState && !lastPirState) {
publishAlert("MOTION_DETECTED", 1);
displayStatus("检测到有人移动", "");
visualAlert(0, 0, 255, 3); // 蓝色闪烁3次
vibrateAlert(2, 100);
}
lastPirState = pirState;
// 读取门磁开关
magState = digitalRead(MAGNET_PIN);
if (magState != lastMagState) {
if (magState == HIGH) {
publishAlert("DOOR_OPEN", 1);
displayStatus("门已打开", "");
visualAlert(255, 255, 255, 4); // 白色闪烁4次
vibrateAlert(3, 100);
} else {
publishAlert("DOOR_CLOSED", 0);
displayStatus("门已关闭", "");
}
lastMagState = magState;
}
// 检测紧急按钮
buttonState = digitalRead(BUTTON_PIN) == LOW; // 按下时为低电平(下拉或上拉视电路而定)
if (buttonState && !lastButtonState) {
publishAlert("EMERGENCY", 1);
displayStatus("紧急呼叫中", "");
visualAlert(255, 0, 255, 10); // 紫色闪烁10次
vibrateAlert(10, 100); // 持续振动
}
lastButtonState = buttonState;
}
/*-------------------发布告警至MQTT-------------------*/
void publishAlert(const char* type, int value) {
char payload[128];
// 获取时间戳(此处仅用 millis() 示例,正式需要RTC或NTP同步)
unsigned long ts = millis() / 1000;
sprintf(payload, "{"type":"%s","value":%d,"timestamp":%lu}", type, value, ts);
client.publish(MQTT_ALERT_TOPIC, payload);
Serial.print("已发布告警: ");
Serial.println(payload);
}
/*-------------------OLED显示状态函数-------------------*/
void displayStatus(const char* line1, const char* line2) {
display.clearDisplay();
display.setTextSize(1);
display.setCursor(0, 0);
display.print(line1);
display.setCursor(0, 16);
display.print(line2);
display.display();
}
/*-------------------视觉告警函数(WS2812B)-------------------*/
void visualAlert(uint8_t r, uint8_t g, uint8_t b, int flashes) {
for (int f = 0; f < flashes; f++) {
for (int i = 0; i < NUM_LEDS; i++) {
leds[i].setRGB(r, g, b);
}
FastLED.show();
delay(200);
FastLED.clear();
FastLED.show();
delay(200);
}
}
/*-------------------振动告警函数-------------------*/
void vibrateAlert(int times, int duration) {
for (int i = 0; i < times; i++) {
digitalWrite(VIB_PIN, HIGH);
delay(duration);
digitalWrite(VIB_PIN, LOW);
delay(duration);
}
}
/*-------------------处理远程控制命令函数-------------------*/
void handleControlCommand(char* payload, unsigned int length) {
// 解析JSON(此处示例简化,生产环境推荐使用ArduinoJson库)
String cmd = String(payload).substring(0, length);
Serial.print("收到控制命令: ");
Serial.println(cmd);
if (cmd.indexOf("relay_on") >= 0) {
digitalWrite(RELAY_PIN, HIGH);
displayStatus("继电器已开启", "");
} else if (cmd.indexOf("relay_off") >= 0) {
digitalWrite(RELAY_PIN, LOW);
displayStatus("继电器已关闭", "");
}
// 可扩展:多继电器、多设备控制等
}
上述代码实现了:
Wi-Fi与MQTT连接管理:在
setup_wifi()
与reconnect_mqtt()
函数中完成Wi-Fi与MQTT Broker的连接与重连;多传感器数据采集:在
readSensorsAndUpdate()
函数中分别读取DHT22、MQ-2/MQ-135、HC-SR501、门磁开关、紧急按钮等传感器的数值;为方MQ-2与MQ-135采用同一模拟输入时,可在硬件中加装CD4051B多路开关或使用外置I²C ADC(如ADS1115);告警触发与反馈:当传感器数值超过阈值时,通过
publishAlert()
将告警信息发布至MQTT主题,并调用visualAlert()
与vibrateAlert()
函数进行视觉与振动提醒;OLED显示状态:通过
displayStatus()
函数实时更新OLED屏显示内容,包括Wi-Fi连接状态、传感器读数、告警类型等;远程控制:通过
callback()
函数接收来自MQTT主题“home/control”的控制命令(如“relay_on”或“relay_off”),并通过GPIO控制继电器模块;可根据项目需求扩展更多控制指令;事件去抖动与阈值判断:对PIR和门磁开关做了状态变化检测,避免抖动误报;对DHT22采样值进行合法性判断(isnan检查),防止传感器读数失败时误触发;MQ传感器部分可根据传感器预热时间(约2分钟)来忽略预热阶段读数。
九、手机App与云端交互
为了让听障用户能够远程查看家中状态并控制设备,本设计预留了两种方案:
基于MQTT的轻量级App
使用MIT Blynk或IoT MQTT Panel等开源客户端配置:输入Broker地址、端口、Topic与客户端ID即可;创建虚拟按钮(Virtual Button)与物理LED或Text Widget关联,当收到
home/alert
主题的消息时,在App中弹出通知并显示图标;当触发App上的按钮时,将对应Payload(如“relay_on”)发布至home/control
;优点:无需编写App代码,配置灵活,适合原型阶段;缺点:界面定制性差、专业度不足;
自定义Android App
使用Android Studio结合Paho MQTT Android客户端库开发:界面包含实时数据图表、告警列表、设备控制面板与历史记录查询等模块;用户通过触摸屏幕即可查看实时温湿度曲线、当前告警列表,并点击“开灯”“关灯”“急停”等按钮触发远程命令;
优点:界面可按听障用户需求设计(大字体、高对比度、多彩图标),实现多语言切换(如中文、手语插图等),易于推广;缺点:开发周期长,需要Android开发经验。
云端数据持久化与分析
在自有服务器或云服务(如AWS、阿里云、腾讯云等)上部署MongoDB或MySQL,将告警日志与传感器数据存储;比如,当ESP8266通过MQTT发布告警时,后端(使用Node.js或Python)接收后写入数据库;前端Web页面通过RESTful API拉取历史数据并以图表形式展示(采用Chart.js或Morris.js等库),便于用户回顾长期环境变化,提前预判风险;
结合机器学习(可选):对收集到的温湿度与气体浓度数据进行趋势分析,如发现异常涨幅后提前预警;
十、系统功能扩展与优化建议
电池备份与节能模式
增加锂电池与TP4056充电模块,实现断电后系统继续工作数小时;利用ESP8266深睡眠模式(Deep Sleep)降低空闲时功耗,仅在定时任务或事件触发时唤醒;可将睡眠间隔设置为30秒或1分钟,视对实时性的要求而定;对PIR等数字传感器,可在硬件上采用中断唤醒方式,降低睡眠期间功耗并提高响应速度。
多路ADC或外置ADC
ESP8266仅有一个10位ADC(0~1V),无法直接连接多个MQ系列模拟输出;可选择集成ADS1115(I²C 16位ADC)或MCP3008(SPI 10位ADC)等,实现4或8路模拟输入;ADS1115支持4路差分/单端测量,精度高达16位,可满足更精细化气体浓度检测需求。
增强安全性与稳定性
对MQTT通信进行TLS加密(借助ESP8266BearSSL库),保证云端与本地通信安全,防止数据被中间人攻击;
在固件中加入OTA功能(Over-The-Air),允许远程固件升级;可使用ArduinoOTA库或MQTT OTA升级方案;
对关键任务(如告警发布)实现重试机制,当网络断开时,将告警保存至SPIFFS文件系统,待网络恢复后重新上传,避免漏报。
更多传感器与设备扩展
增加水浸传感器、防盗窃磁力传感器、光线强度传感器(LDR)、环境PM2.5传感器等,实现全屋环境感知;
增加接近传感器或超声波测距模块(HC-SR04),为听障用户提供跌倒监测、家中老人行为监测等功能。
可视化交互界面与语义提示
在OLED基础上升级为更大尺寸或彩色屏幕(如1.3寸SSD1306升级SSD1309或SSD1331彩屏),使用图形与手语图标相结合的方式,为听障者提供更友好的视觉提示;
增加蓝牙或LoRa通信模块,实现房屋偏远区域或室外庭院的设备连接;
十一、总结
本设计基于ESP8266核心控制单元,为听障人士量身定制了一套智能家居系统,涵盖多种传感器(温湿度、可燃气体、烟雾、红外人体、门磁)、执行器(继电器、WS2812B LED、振动马达)、告警方式(视觉、振动)、通信方案(Wi-Fi+MQTT)、远程交互(App/云端)等模块,既保证了系统的低成本与易扩展,又充分考虑听障用户对非声响式告警的需求。文中从硬件选型(ESP-12E、AMS1117、LM2596、HC-SR501、MQ-2、MQ-135、DHT22、SSD1306、WS2812B、振动马达、继电器)、软件架构(底层驱动、逻辑控制、告警反馈、通信、HMI)、PCB与电路布局、核心代码实现,以及系统优化与扩展建议等方面进行了详尽阐述。
通过本方案,听障用户可在各个生活场景中及时获得安全与环境状态信息,并通过视觉与振动方式得到告警,避免因听力障碍而错过重要警示。该系统具有成本低、开发门槛低、功能丰富、可扩展性强的特点,未来可根据用户实际需求,提高系统智能化程度(如AI语义识别、数据分析与预测),进一步提升听障人士的生活质量与居家安全感。
责任编辑:David
【免责声明】
1、本文内容、数据、图表等来源于网络引用或其他公开资料,版权归属原作者、原发表出处。若版权所有方对本文的引用持有异议,请联系拍明芯城(marketing@iczoom.com),本方将及时处理。
2、本文的引用仅供读者交流学习使用,不涉及商业目的。
3、本文内容仅代表作者观点,拍明芯城不对内容的准确性、可靠性或完整性提供明示或暗示的保证。读者阅读本文后做出的决定或行为,是基于自主意愿和独立判断做出的,请读者明确相关结果。
4、如需转载本方拥有版权的文章,请联系拍明芯城(marketing@iczoom.com)注明“转载原因”。未经允许私自转载拍明芯城将保留追究其法律责任的权利。
拍明芯城拥有对此声明的最终解释权。