ESP32物联网运动检测系统:从PIR传感器到邮件告警的完整实践
1. 项目概述与核心价值
如果你还在为传统运动检测系统繁琐的布线、高昂的安装成本和有限的扩展性而烦恼,那么是时候亲手打造一个基于ESP32的物联网运动检测系统了。这不仅仅是一个简单的DIY项目,更是一个理解现代物联网(IoT)技术如何将物理世界与数字世界无缝连接的绝佳实践。通过这个项目,你将构建一个集成了本地指示、远程Web监控和实时邮件告警的智能感知节点。它的核心价值在于,你能够以极低的硬件成本,获得一个可定制、可远程访问、且易于集成的智能安防或自动化触发模块。无论是用于家庭安防、智能照明触发,还是作为更复杂自动化场景的“感知器官”,这个系统都能胜任。
整个系统的核心是ESP32,这颗集成了Wi-Fi和蓝牙的微控制器芯片,让我们能够轻松地将传感器数据送上云端或局域网。而HC-SR501 PIR(被动红外)传感器,则是我们感知人体移动的“眼睛”。这个项目的魅力在于,它跳出了传统安防设备封闭的生态,将控制权和数据所有权完全交还给你。你可以决定何时告警、告警给谁、以及触发什么后续动作。接下来,我将从设计思路、硬件选型、软件实现到调试优化,完整地拆解这个项目,并分享我在多次搭建中积累的实操经验和避坑指南。
2. 系统整体设计与核心思路拆解
2.1 为什么选择ESP32 + PIR传感器方案?
在开始动手之前,理清设计思路至关重要。我们选择ESP32和HC-SR501的组合,背后有一系列经过权衡的考量。
首先看主控,ESP32相较于经典的Arduino UNO或NodeMCU(ESP8266),拥有更强大的双核处理能力、更丰富的外设接口(如DAC、触摸传感器、霍尔传感器)以及更低的功耗模式。对于本项目,其核心优势是 稳定的Wi-Fi连接性能 和 充足的GPIO与ADC资源 。这意味着我们可以在处理传感器数据、维持网络连接的同时,仍有余力运行一个轻量级的Web服务器,为系统提供本地化的人机交互界面,这是许多单一功能模块所不具备的。
其次,HC-SR501作为一款成熟且廉价的PIR传感器模块,其内部已经集成了信号放大、比较和延时控制电路,输出的是干净的数字信号(HIGH/LOW),极大简化了微控制器的编程逻辑。我们无需像处理模拟传感器那样进行复杂的AD转换和阈值判断,只需监听一个GPIO引脚的电平变化即可。这种“即插即用”的特性,非常适合物联网项目的快速原型开发。
整个系统的工作流可以概括为一个 事件驱动的状态机模型 :
- 感知层 :HC-SR501持续监测环境红外辐射变化。当有效移动(如人体)进入其菲涅尔透镜构成的探测区域时,模块内部电路被触发。
- 控制与逻辑层 :ESP32通过指定的GPIO引脚(如GPIO14)检测到传感器输出从LOW变为HIGH。这个上升沿信号就是“运动事件”。
-
响应与输出层
:ESP32在检测到事件后,同步执行三项任务:
- 本地可视化 :控制连接在另一GPIO(如GPIO2)上的LED点亮,提供直接的物理反馈。
- 网络服务 :更新其内嵌Web服务器的状态页面,任何连接在同一局域网的设备(手机、电脑)访问该网页都能实时看到状态变化。
- 远程通知 :通过SMTP协议,向预设的邮箱地址发送一封包含事件发生时间的告警邮件。
这个设计实现了 本地与云端联动、即时与远程通知结合 的立体化响应,确保了告警信息的可靠送达。
2.2 硬件选型与电路设计解析
一份清晰的物料清单和正确的连接方式是项目成功的基石。以下是核心组件的深度解析与连接要点。
核心组件清单与选型考量:
- ESP32开发板 :市面上型号繁多,如ESP32 DevKitC、NodeMCU-32S、Wemos D1 R32等。对于本项目,选择任何一款引出足够GPIO且带有USB转串口芯片的型号均可。我个人常用 ESP32 DevKitC V4 ,因为它引脚标注清晰,且通常自带自动下载电路,烧录程序非常方便。
- HC-SR501 PIR传感器模块 :注意其工作电压为 5V-20V ,但输出信号为3.3V兼容。虽然ESP32的GPIO可耐受5V输入,但为稳妥起见,我们仍将其VCC接至ESP32的 5V引脚 ,OUT接GPIO,GND共地。模块上有两个可调电阻: 灵敏度调节 (探测距离,约3-7米)和 延时调节 (输出高电平保持时间,约5秒至数分钟)。初次使用时,建议将延时调至中间位置。
-
LED与限流电阻
:LED颜色不限。限流电阻阻值计算是关键。ESP32的GPIO输出电压约为3.3V,假设LED正向压降(Vf)为2V(红光典型值),期望电流(If)为10mA(足够明亮且安全)。根据欧姆定律:
R = (Vcc - Vf) / If = (3.3V - 2V) / 0.01A = 130Ω。选择最接近的标准值 220Ω 是稳妥且常见的做法,它能将电流限制在约6mA,既保证亮度又延长LED寿命。 - 面包板与跳线 :用于无焊接原型搭建。建议使用质量较好的面包板,避免接触不良。杜邦线建议使用公-公头。
- Micro USB线 :用于供电和程序烧录。务必使用 数据线 而非仅充电线。
电路连接详解与安全注意事项:
注意:连接电路前,请确保ESP32未通电。错误的连接可能会瞬间损坏芯片。
参照电路图,具体连接如下:
-
HC-SR501模块
:
-
VCC引脚 -> 连接至ESP32的5V引脚(注意:是5V输出引脚,不是3.3V)。 -
GND引脚 -> 连接至ESP32的任意GND引脚。 -
OUT引脚 -> 连接至ESP32的GPIO14引脚(可根据代码定义更改,但需保持一致)。
-
-
LED指示电路
:
-
LED阳极(长脚)-> 先串联一个220Ω电阻,电阻另一端连接至ESP32的GPIO2引脚(该引脚在开发板上常连接有内置LED,方便双重确认)。 -
LED阴极(短脚)-> 直接连接至ESP32的GND引脚。
-
- 供电 :通过Micro USB线为整个系统供电。
连接完成后的检查清单 :
- [ ] 确认所有电源(VCC/5V)和地(GND)连接正确,无短路。
- [ ] 确认PIR传感器的OUT信号线连接到了正确的GPIO(14)。
- [ ] 确认LED的极性未接反(电阻需串联在正极通路)。
- [ ] 确认面包板插孔接触牢固,无虚接。
3. 软件开发环境配置与核心代码解析
硬件搭好只是骨架,软件才是赋予其灵魂的关键。我们将使用Arduino IDE进行开发,因为它生态丰富,对ESP32支持友好。
3.1 Arduino IDE环境搭建与库管理
首先,确保你安装了最新版本的Arduino IDE。接着,需要将ESP32的开发板支持包添加到IDE中。
-
添加ESP32开发板支持 :
-
打开Arduino IDE,进入
文件->首选项。 -
在“附加开发板管理器网址”中,填入以下网址(如果已有其他,用逗号分隔):
https://raw.githubusercontent.com/espressif/arduino-esp32/gh-pages/package_esp32_index.json - 点击“好”保存。
-
进入
工具->开发板->开发板管理器...。 - 在搜索框中输入“esp32”,找到由 Espressif Systems 提供的“ESP32”开发板包,点击“安装”。这个过程可能需要下载一段时间,请保持网络通畅。
-
打开Arduino IDE,进入
-
安装必要的库 : 本项目需要两个核心库来处理邮件发送和Web服务器。
- ESP-Mail-Client :用于通过SMTP协议发送邮件。
-
WebServer
库(通常随ESP32核心包自带,无需单独安装)。
安装库的方法:
工具->管理库...,打开库管理器,分别搜索上述库名并安装。建议安装其最新稳定版本。
3.2 核心代码逐段解析与个性化配置
下面提供完整的代码,并穿插详细解释和配置说明。你需要修改其中标记为“需要修改”的部分。
// 1. 引入必要的库
#include <WiFi.h>
#include <WebServer.h>
#include <ESP_Mail_Client.h>
// 2. 网络凭证 - 必须修改!
const char* ssid = "你的Wi-Fi名称"; // 替换为你的2.4GHz Wi-Fi SSID
const char* password = "你的Wi-Fi密码"; // 替换为你的Wi-Fi密码
// 3. 邮件发送配置 - 必须修改!
// 以QQ邮箱为例,其他邮箱服务器地址不同
#define SMTP_HOST "smtp.qq.com"
#define SMTP_PORT 465 // QQ邮箱SSL端口
#define AUTHOR_EMAIL "你的发件邮箱@qq.com" // 替换为你的邮箱
#define AUTHOR_PASSWORD "你的授权码" // 注意:不是邮箱密码,是SMTP授权码!
#define RECIPIENT_EMAIL "收件邮箱@example.com" // 替换为接收告警的邮箱
// 4. 全局变量与对象定义
WebServer server(80); // 在80端口创建Web服务器对象
SMTPSession smtp; // 创建SMTP会话对象
// 引脚定义
const int pirPin = 14; // PIR传感器输出接GPIO14
const int ledPin = 2; // LED接GPIO2
bool motionDetected = false; // 运动状态标志
unsigned long lastDetectionTime = 0; // 上次检测到运动的时间戳
// 5. 邮件回调函数(用于获取发送状态)
void smtpCallback(SMTP_Status status);
void setup() {
Serial.begin(115200); // 初始化串口,用于调试输出
delay(1000); // 给串口一点启动时间
// 初始化GPIO
pinMode(pirPin, INPUT);
pinMode(ledPin, OUTPUT);
digitalWrite(ledPin, LOW); // 初始状态LED熄灭
// 连接Wi-Fi
Serial.println();
Serial.print("正在连接到: ");
Serial.println(ssid);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println();
Serial.println("Wi-Fi连接成功!");
Serial.print("设备IP地址: ");
Serial.println(WiFi.localIP()); // 打印ESP32获取到的IP,用于访问Web页面
// 初始化邮件服务配置
ESP_Mail_Session session;
session.server.host_name = SMTP_HOST;
session.server.port = SMTP_PORT;
session.login.email = AUTHOR_EMAIL;
session.login.password = AUTHOR_PASSWORD;
session.login.user_domain = ""; // 通常留空
// 注册状态回调函数
smtp.callback(smtpCallback);
// 配置Web服务器路由
server.on("/", handleRoot); // 当访问根目录时,调用handleRoot函数
server.begin(); // 启动Web服务器
Serial.println("HTTP服务器已启动");
}
void loop() {
server.handleClient(); // 处理来自客户端的Web请求
// 读取PIR传感器状态
int pirState = digitalRead(pirPin);
// 检测到运动(从低电平变为高电平)
if (pirState == HIGH && !motionDetected) {
motionDetected = true;
lastDetectionTime = millis(); // 记录当前时间
digitalWrite(ledPin, HIGH); // 点亮LED
Serial.println("运动已检测!");
// 发送邮件告警
sendEmailNotification();
// 由于Web请求处理是异步的,状态更新会在handleRoot中体现
}
// 运动状态复位逻辑(可选,也可依赖传感器本身的延时)
// 这里添加一个额外的复位逻辑,防止传感器延时过长导致Web状态一直显示“检测中”
if (motionDetected && (millis() - lastDetectionTime > 10000)) { // 10秒后复位
motionDetected = false;
digitalWrite(ledPin, LOW);
Serial.println("运动状态已复位。");
}
delay(100); // 短延时,降低CPU占用
}
// 6. 处理Web服务器根目录请求的函数
void handleRoot() {
String html = "<!DOCTYPE html><html><head><meta charset=\"UTF-8\">";
html += "<meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">";
html += "<title>ESP32运动监测系统</title>";
html += "<style>";
html += "body { font-family: Arial, sans-serif; text-align: center; margin-top: 50px; }";
html += ".status { font-size: 2em; padding: 20px; margin: 20px auto; width: 80%; border-radius: 10px; }";
html += ".detected { background-color: #ffcccc; color: #cc0000; }"; // 检测到运动时的样式
html += ".clear { background-color: #ccffcc; color: #006600; }"; // 无运动时的样式
html += "</style></head><body>";
html += "<h1>ESP32 实时运动监测</h1>";
html += "<p>设备IP: " + WiFi.localIP().toString() + "</p>";
if (motionDetected) {
html += "<div class=\"status detected\">⚠️ 检测到运动!</div>";
} else {
html += "<div class=\"status clear\">✅ 区域安全</div>";
}
html += "<p>最后更新: " + String(millis() / 1000) + " 秒前</p>";
html += "<p><small>页面自动刷新: <span id=\"countdown\">10</span> 秒</small></p>";
html += "<script>";
html += "let time = 10; function updateCountdown(){ document.getElementById('countdown').textContent = time; time--; if(time < 0) { location.reload(); } else { setTimeout(updateCountdown, 1000); } } updateCountdown();";
html += "</script>";
html += "</body></html>";
server.send(200, "text/html", html); // 发送完整的HTML页面给客户端
}
// 7. 发送邮件通知的函数
void sendEmailNotification() {
Serial.println("准备发送邮件...");
ESP_Mail_Session session;
session.server.host_name = SMTP_HOST;
session.server.port = SMTP_PORT;
session.login.email = AUTHOR_EMAIL;
session.login.password = AUTHOR_PASSWORD;
SMTP_Message message;
message.sender.name = "ESP32 Security"; // 发件人名称
message.sender.email = AUTHOR_EMAIL;
message.subject = "【告警】Motion Detected!"; // 邮件主题
message.addRecipient("Recipient", RECIPIENT_EMAIL); // 收件人
// 构建邮件正文,包含日期时间
String textMsg = "Warning: Motion was detected by your ESP32 system!\n";
textMsg += "Time: ";
textMsg += getDateTimeString(); // 调用函数获取当前时间字符串
textMsg += "\nPlease check the situation.";
message.text.content = textMsg.c_str();
message.text.charSet = "us-ascii";
message.text.transfer_encoding = Content_Transfer_Encoding::enc_7bit;
message.priority = esp_mail_smtp_priority::esp_mail_smtp_priority_high; // 设置高优先级
// 连接服务器并发送
if (!smtp.connect(&session)) {
Serial.println("邮件服务器连接失败!");
return;
}
if (!MailClient.sendMail(&smtp, &message)) {
Serial.println("邮件发送失败!");
} else {
Serial.println("邮件发送成功!");
}
}
// 8. 获取日期时间字符串的辅助函数(简化版,未同步网络时间)
String getDateTimeString() {
// 注意:这里使用的是设备上电后的毫秒数,并非真实世界时间。
// 如需精确时间,需要额外连接NTP服务器同步,代码会复杂很多。
unsigned long ms = millis();
int seconds = (ms / 1000) % 60;
int minutes = (ms / (1000 * 60)) % 60;
int hours = (ms / (1000 * 60 * 60)) % 24;
char buffer[20];
sprintf(buffer, "Uptime: %02d:%02d:%02d", hours, minutes, seconds);
return String(buffer);
}
// 9. 邮件发送状态回调函数
void smtpCallback(SMTP_Status status) {
Serial.println(status.info()); // 打印邮件发送状态信息
}
关键配置点与解释:
- Wi-Fi配置 :务必填写正确的2.4GHz网络SSID和密码。ESP32对5GHz网络支持可能因型号而异,建议使用2.4GHz网络确保兼容性。
-
邮件服务配置
:这是最容易出错的部分。
-
SMTP_HOST和SMTP_PORT:不同邮箱服务商不同。QQ邮箱是smtp.qq.com和465(SSL)。Gmail是smtp.gmail.com和465。请根据你的发件邮箱查询其SMTP服务器地址和端口。 -
AUTHOR_PASSWORD: 绝对不要填邮箱登录密码! 大部分邮箱服务商(如QQ、163、Gmail)都需要在设置中开启SMTP服务,并生成一个独立的 授权码 。使用这个授权码作为密码。 -
RECIPIENT_EMAIL:填写接收告警的邮箱地址,可以和发件邮箱相同。
-
-
引脚定义
:
pirPin和ledPin必须与你的实际硬件连接一致。 -
运动复位逻辑
:代码中我添加了一个
10秒后自动复位的逻辑(if (motionDetected && (millis() - lastDetectionTime > 10000)))。这是因为HC-SR501模块自身的延时可能很长(通过电位器调节),导致Web页面长时间显示“检测到运动”。这个软件复位可以确保状态更及时地更新。你可以根据需要调整这个时间(10000毫秒)。 -
时间戳问题
:
getDateTimeString()函数返回的是设备运行时间,并非真实时钟。对于安防应用,强烈建议集成NTP(网络时间协议)客户端来获取准确的北京时间。这需要引入NTPClient库并连接至NTP服务器,代码量会增加,但告警信息会更有价值。
4. 项目烧录、测试与系统验证
代码编写并配置完成后,就可以将其烧录到ESP32并进行全面测试了。
4.1 代码编译与烧录步骤
- 硬件连接 :确保ESP32通过Micro USB线连接到电脑,且所有硬件连线检查无误。
-
选择开发板与端口
:
-
在Arduino IDE中,进入
工具->开发板,选择你使用的ESP32型号(如“ESP32 Dev Module”)。 -
进入
工具->端口,选择对应的串口(Windows下通常是COMx, macOS/Linux下是/dev/cu.usbserial-xxx)。如果端口列表是灰色的,检查USB线或驱动。
-
在Arduino IDE中,进入
-
编译与上传
:
- 点击左上角的“√”(验证)按钮编译代码。确保底部状态栏显示“编译完成”。
-
点击“→”(上传)按钮将代码烧录到ESP32。
在烧录过程中,你可能需要手动按下ESP32板上的
BOOT按钮 (具体操作因板而异,有些板子会自动进入下载模式)。观察底部状态栏输出“上传成功”。
-
打开串口监视器
:上传完成后,点击右上角的“放大镜”图标打开串口监视器。将右下角的波特率设置为
115200。如果看到乱码,检查波特率是否匹配。
4.2 系统功能测试与验证
烧录成功后,系统会自动运行。请按以下步骤逐一验证所有功能:
-
观察串口输出 :
- 正常情况:你会先看到“正在连接到: [你的Wi-Fi]”,随后是一串“....”,最后显示“Wi-Fi连接成功!”和“设备IP地址: 192.168.x.x”。记下这个IP地址。
- 如果卡在连接Wi-Fi,请检查SSID、密码是否正确,以及网络是否为2.4GHz。
- 如果显示“HTTP服务器已启动”,说明Web服务器启动成功。
-
测试Web服务器 :
-
在连接
同一局域网
的电脑或手机浏览器中,输入上一步记下的IP地址(如
http://192.168.1.100)。 - 你应该能看到一个简洁的网页,标题为“ESP32运动监测系统”,中间有一个状态框。初始状态应为“✅ 区域安全”。页面右下角有一个10秒倒计时,结束后会自动刷新。
-
在连接
同一局域网
的电脑或手机浏览器中,输入上一步记下的IP地址(如
-
触发运动检测 :
- 用手在HC-SR501传感器前方缓慢挥动(距离1-3米内)。
- 本地LED :观察连接到GPIO2的LED是否立即点亮。
- 串口监视器 :应打印出“运动已检测!”。
- Web页面 :刷新或等待自动刷新后,状态应变为“⚠️ 检测到运动!”。等待约10秒(或你设定的复位时间)后,状态应自动恢复为“区域安全”,LED也应熄灭。
-
验证邮件告警 :
- 触发运动后,观察串口监视器。在“运动已检测!”后,应陆续出现“准备发送邮件...”、连接服务器、发送状态等信息。最终显示“邮件发送成功!”。
-
立即检查
你设置的
RECIPIENT_EMAIL收件箱(包括垃圾邮件箱)。应该能收到一封主题为“【告警】Motion Detected!”的邮件,正文包含设备运行时间。 -
邮件发送失败排查
:这是最常见的问题。请依次检查:
- 网络连接:ESP32是否真的连上了网?可以尝试Ping它的IP地址。
- SMTP配置:服务器地址、端口(尤其是465 SSL端口)是否正确?
- 邮箱授权码:是否使用了正确的SMTP授权码,而非邮箱密码?
- 邮箱安全设置:发件邮箱是否已开启SMTP服务?某些邮箱(如Gmail)可能需要允许“不够安全的应用”访问(不推荐)或使用OAuth2.0验证(更复杂)。
5. 深度优化、扩展思路与避坑指南
一个能跑通的系统只是开始,要让其稳定、可靠、实用,还需要进行优化和功能扩展。这里分享一些进阶思路和实践中踩过的坑。
5.1 稳定性优化与功耗考量
-
Wi-Fi连接稳定性
:在实际部署中,Wi-Fi可能不稳定。可以在
loop()函数开头加入Wi-Fi重连逻辑。if (WiFi.status() != WL_CONNECTED) { Serial.println("Wi-Fi断开,尝试重连..."); WiFi.reconnect(); delay(5000); // 等待重连 } -
邮件发送防重入与队列
:当前代码中,每次检测到运动都会立即尝试发送邮件。如果在传感器延时内多次触发,会发送多封邮件。可以增加一个“冷却时间”标志位,例如发送邮件后,设置一个
lastEmailSentTime,在接下来几分钟内不再发送新邮件。 -
降低功耗
:如果希望用电池供电,需要大幅降低功耗。
- 使用ESP32的深度睡眠模式 :可以让ESP32大部分时间休眠,仅由PIR传感器的输出信号(通过外部中断)唤醒。唤醒后,快速连接Wi-Fi、发送数据、然后再次进入睡眠。这需要重新设计电路(PIR的OUT引脚需连接到ESP32的RTC GPIO,如GPIO33),并编写相应的深度睡眠代码。
-
关闭不必要的外设
:在睡眠前,使用
WiFi.mode(WIFI_OFF)关闭Wi-Fi。 - 调整PIR传感器 :HC-SR501本身功耗不低(约65uA-1mA)。有更低功耗的PIR传感器模组可选。
5.2 功能扩展思路
-
集成精准的NTP时间
:如前所述,使用
NTPClient库获取真实时间,让告警邮件包含“2023-10-27 14:30:25”这样的准确时间戳,而非设备运行时间。 -
添加其他传感器
:ESP32的GPIO和ADC资源丰富,可以轻松集成:
- 温湿度传感器(DHT11/DHT22) :在告警邮件中附带环境温湿度信息。
- 光线传感器(BH1750) :实现“仅在暗光条件下触发告警”的智能判断。
- 声音传感器 :构成“动静结合”的双重验证,减少误报。
-
接入物联网平台
:将数据上报到更强大的平台进行可视化或复杂规则处理。
- Home Assistant :通过MQTT协议,将ESP32的运动状态发布到Home Assistant,实现与家中其他智能设备的联动(如检测到运动自动开灯、录像)。
- Blynk / ThingSpeak :快速创建手机App控制面板或数据图表。
- 启用HTTPS与身份验证 :当前的Web服务器是HTTP明文传输。为提高安全性,可以启用HTTPS(需要证书),并为网页添加简单的登录密码验证。
- 使用蜂鸣器或继电器 :将LED替换为有源蜂鸣器,实现声音告警;或者连接一个继电器模块,直接控制大功率设备(如电灯、报警器)的开关。
5.3 常见问题与排查技巧实录
以下是我在多次项目中遇到的典型问题及解决方法,整理成速查表:
| 问题现象 | 可能原因 | 排查步骤与解决方案 |
|---|---|---|
| ESP32无法连接Wi-Fi |
1. SSID/密码错误
2. 网络是5GHz 3. 路由器设置了MAC过滤 4. 信号太弱 |
1. 仔细核对代码中的SSID和密码,注意大小写。
2. 确保连接2.4GHz网络。 3. 查看路由器后台,将ESP32的MAC地址加入白名单。 4. 将设备靠近路由器测试。 |
| 串口监视器无输出或乱码 |
1. 波特率不匹配
2. 串口被占用 3. USB线或驱动问题 |
1. 确认波特率设置为
115200
。
2. 关闭其他可能占用串口的软件(如其他串口工具、平台IDE)。 3. 尝试更换USB线或端口,安装正确的CH340/CP2102驱动。 |
| PIR传感器一直输出高电平/无反应 |
1. 传感器延时电位器调得太长
2. 传感器灵敏度调得太高/太低 3. 接线错误 4. 传感器前方有热源干扰 |
1. 调整“延时”电位器逆时针旋转,缩短保持时间。
2. 调整“灵敏度”电位器,找到合适位置。 3. 用万用表测量VCC是否有5V,OUT引脚电压是否随触发变化。 4. 避免将传感器对准暖气、窗户(阳光)或发热电器。 |
| Web页面无法访问 |
1. IP地址错误
2. 设备与客户端不在同一局域网 3. 防火墙/路由器设置阻止 |
1. 从串口监视器确认正确的IP地址。
2. 确保手机/电脑连接的是同一个Wi-Fi。 3. 尝试暂时关闭电脑防火墙。 |
| 邮件发送失败 |
1. 网络不通
2. SMTP服务器/端口错误 3. 邮箱授权码错误 4. 邮箱服务商安全限制 |
1. 确保ESP32能访问互联网(可尝试Ping外网)。
2. 核对
SMTP_HOST
和
SMTP_PORT
。
3. 重点检查 :是否使用了SMTP授权码而非邮箱密码。 4. 对于QQ邮箱,需在设置中“开启POP3/SMTP服务”。对于Gmail,可能需要配置“应用专用密码”或调整安全设置(不推荐降低安全性)。 |
| LED不亮 |
1. LED极性接反
2. 限流电阻阻值过大或虚焊 3. GPIO引脚定义错误 |
1. 确认LED长脚(阳极)接GPIO,短脚(阴极)接GND。
2. 用万用表测量LED两端电压,触发时应接近3.3V。 3. 检查代码中
ledPin
的定义与实际连接是否一致。
|
| 系统运行一段时间后死机 |
1. 内存泄漏(在回调函数中动态创建对象未释放)
2. 看门狗超时(长时间阻塞操作) 3. 电源不稳定 |
1. 检查代码,避免在
loop()
或中断中频繁动态分配内存。使用全局或静态变量。
2. 将长时间操作(如邮件发送)拆分成非阻塞状态机,或使用
yield()
、
delay()
让看门狗喂食。
3. 使用外部5V/2A以上的电源适配器为ESP32供电,避免USB口供电不足。 |
一个关键的实操心得
:在调试邮件功能时,
务必先使用串口监视器观察SMTP连接和发送的全过程日志
。ESP-Mail-Client库会通过回调函数
smptCallback
输出非常详细的连接、登录、发送各阶段状态。这些日志是定位问题最直接的依据,远比盲目猜测有效。例如,如果看到“Authentication failed”,那几乎可以肯定是授权码错了;如果看到“Connection failed”,则是网络或服务器地址/端口的问题。
这个基于ESP32的物联网运动检测系统,从一个简单的点子出发,通过硬件连接、软件编程、网络服务集成,最终成为一个功能完整的解决方案。它最大的意义在于提供了一个可扩展的框架。当你理解了传感器数据如何采集、ESP32如何作为中枢处理逻辑、并通过Wi-Fi与外界通信后,你就可以举一反三,用类似的架构去实现温度监控、湿度报警、智能开关等无数个物联网应用。动手去试,遇到问题就对照上面的表格排查,每一次解决问题的过程,都是对物联网技术更深一层的理解。
更多推荐


所有评论(0)