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引脚的电平变化即可。这种“即插即用”的特性,非常适合物联网项目的快速原型开发。

整个系统的工作流可以概括为一个 事件驱动的状态机模型 :

  1. 感知层 :HC-SR501持续监测环境红外辐射变化。当有效移动(如人体)进入其菲涅尔透镜构成的探测区域时,模块内部电路被触发。
  2. 控制与逻辑层 :ESP32通过指定的GPIO引脚(如GPIO14)检测到传感器输出从LOW变为HIGH。这个上升沿信号就是“运动事件”。
  3. 响应与输出层 :ESP32在检测到事件后,同步执行三项任务:
    • 本地可视化 :控制连接在另一GPIO(如GPIO2)上的LED点亮,提供直接的物理反馈。
    • 网络服务 :更新其内嵌Web服务器的状态页面,任何连接在同一局域网的设备(手机、电脑)访问该网页都能实时看到状态变化。
    • 远程通知 :通过SMTP协议,向预设的邮箱地址发送一封包含事件发生时间的告警邮件。

这个设计实现了 本地与云端联动、即时与远程通知结合 的立体化响应,确保了告警信息的可靠送达。

2.2 硬件选型与电路设计解析

一份清晰的物料清单和正确的连接方式是项目成功的基石。以下是核心组件的深度解析与连接要点。

核心组件清单与选型考量:

  1. ESP32开发板 :市面上型号繁多,如ESP32 DevKitC、NodeMCU-32S、Wemos D1 R32等。对于本项目,选择任何一款引出足够GPIO且带有USB转串口芯片的型号均可。我个人常用 ESP32 DevKitC V4 ,因为它引脚标注清晰,且通常自带自动下载电路,烧录程序非常方便。
  2. HC-SR501 PIR传感器模块 :注意其工作电压为 5V-20V ,但输出信号为3.3V兼容。虽然ESP32的GPIO可耐受5V输入,但为稳妥起见,我们仍将其VCC接至ESP32的 5V引脚 ,OUT接GPIO,GND共地。模块上有两个可调电阻: 灵敏度调节 (探测距离,约3-7米)和 延时调节 (输出高电平保持时间,约5秒至数分钟)。初次使用时,建议将延时调至中间位置。
  3. LED与限流电阻 :LED颜色不限。限流电阻阻值计算是关键。ESP32的GPIO输出电压约为3.3V,假设LED正向压降(Vf)为2V(红光典型值),期望电流(If)为10mA(足够明亮且安全)。根据欧姆定律: R = (Vcc - Vf) / If = (3.3V - 2V) / 0.01A = 130Ω 。选择最接近的标准值 220Ω 是稳妥且常见的做法,它能将电流限制在约6mA,既保证亮度又延长LED寿命。
  4. 面包板与跳线 :用于无焊接原型搭建。建议使用质量较好的面包板,避免接触不良。杜邦线建议使用公-公头。
  5. 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中。

  1. 添加ESP32开发板支持 :

    • 打开Arduino IDE,进入 文件 -> 首选项 。
    • 在“附加开发板管理器网址”中,填入以下网址(如果已有其他,用逗号分隔): https://raw.githubusercontent.com/espressif/arduino-esp32/gh-pages/package_esp32_index.json
    • 点击“好”保存。
    • 进入 工具 -> 开发板 -> 开发板管理器... 。
    • 在搜索框中输入“esp32”,找到由 Espressif Systems 提供的“ESP32”开发板包,点击“安装”。这个过程可能需要下载一段时间,请保持网络通畅。
  2. 安装必要的库 : 本项目需要两个核心库来处理邮件发送和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()); // 打印邮件发送状态信息
}

关键配置点与解释:

  1. Wi-Fi配置 :务必填写正确的2.4GHz网络SSID和密码。ESP32对5GHz网络支持可能因型号而异,建议使用2.4GHz网络确保兼容性。
  2. 邮件服务配置 :这是最容易出错的部分。
    • SMTP_HOST 和 SMTP_PORT :不同邮箱服务商不同。QQ邮箱是 smtp.qq.com 和 465 (SSL)。Gmail是 smtp.gmail.com 和 465 。请根据你的发件邮箱查询其SMTP服务器地址和端口。
    • AUTHOR_PASSWORD : 绝对不要填邮箱登录密码! 大部分邮箱服务商(如QQ、163、Gmail)都需要在设置中开启SMTP服务,并生成一个独立的 授权码 。使用这个授权码作为密码。
    • RECIPIENT_EMAIL :填写接收告警的邮箱地址,可以和发件邮箱相同。
  3. 引脚定义 : pirPin 和 ledPin 必须与你的实际硬件连接一致。
  4. 运动复位逻辑 :代码中我添加了一个 10秒 后自动复位的逻辑( if (motionDetected && (millis() - lastDetectionTime > 10000)) )。这是因为HC-SR501模块自身的延时可能很长(通过电位器调节),导致Web页面长时间显示“检测到运动”。这个软件复位可以确保状态更及时地更新。你可以根据需要调整这个时间( 10000 毫秒)。
  5. 时间戳问题 : getDateTimeString() 函数返回的是设备运行时间,并非真实时钟。对于安防应用,强烈建议集成NTP(网络时间协议)客户端来获取准确的北京时间。这需要引入 NTPClient 库并连接至NTP服务器,代码量会增加,但告警信息会更有价值。

4. 项目烧录、测试与系统验证

代码编写并配置完成后,就可以将其烧录到ESP32并进行全面测试了。

4.1 代码编译与烧录步骤

  1. 硬件连接 :确保ESP32通过Micro USB线连接到电脑,且所有硬件连线检查无误。
  2. 选择开发板与端口 :
    • 在Arduino IDE中,进入 工具 -> 开发板 ,选择你使用的ESP32型号(如“ESP32 Dev Module”)。
    • 进入 工具 -> 端口 ,选择对应的串口(Windows下通常是 COMx , macOS/Linux下是 /dev/cu.usbserial-xxx )。如果端口列表是灰色的,检查USB线或驱动。
  3. 编译与上传 :
    • 点击左上角的“√”(验证)按钮编译代码。确保底部状态栏显示“编译完成”。
    • 点击“→”(上传)按钮将代码烧录到ESP32。 在烧录过程中,你可能需要手动按下ESP32板上的 BOOT 按钮 (具体操作因板而异,有些板子会自动进入下载模式)。观察底部状态栏输出“上传成功”。
  4. 打开串口监视器 :上传完成后,点击右上角的“放大镜”图标打开串口监视器。将右下角的波特率设置为 115200 。如果看到乱码,检查波特率是否匹配。

4.2 系统功能测试与验证

烧录成功后,系统会自动运行。请按以下步骤逐一验证所有功能:

  1. 观察串口输出 :

    • 正常情况:你会先看到“正在连接到: [你的Wi-Fi]”,随后是一串“....”,最后显示“Wi-Fi连接成功!”和“设备IP地址: 192.168.x.x”。记下这个IP地址。
    • 如果卡在连接Wi-Fi,请检查SSID、密码是否正确,以及网络是否为2.4GHz。
    • 如果显示“HTTP服务器已启动”,说明Web服务器启动成功。
  2. 测试Web服务器 :

    • 在连接 同一局域网 的电脑或手机浏览器中,输入上一步记下的IP地址(如 http://192.168.1.100 )。
    • 你应该能看到一个简洁的网页,标题为“ESP32运动监测系统”,中间有一个状态框。初始状态应为“✅ 区域安全”。页面右下角有一个10秒倒计时,结束后会自动刷新。
  3. 触发运动检测 :

    • 用手在HC-SR501传感器前方缓慢挥动(距离1-3米内)。
    • 本地LED :观察连接到GPIO2的LED是否立即点亮。
    • 串口监视器 :应打印出“运动已检测!”。
    • Web页面 :刷新或等待自动刷新后,状态应变为“⚠️ 检测到运动!”。等待约10秒(或你设定的复位时间)后,状态应自动恢复为“区域安全”,LED也应熄灭。
  4. 验证邮件告警 :

    • 触发运动后,观察串口监视器。在“运动已检测!”后,应陆续出现“准备发送邮件...”、连接服务器、发送状态等信息。最终显示“邮件发送成功!”。
    • 立即检查 你设置的 RECIPIENT_EMAIL 收件箱(包括垃圾邮件箱)。应该能收到一封主题为“【告警】Motion Detected!”的邮件,正文包含设备运行时间。
    • 邮件发送失败排查 :这是最常见的问题。请依次检查:
      • 网络连接:ESP32是否真的连上了网?可以尝试Ping它的IP地址。
      • SMTP配置:服务器地址、端口(尤其是465 SSL端口)是否正确?
      • 邮箱授权码:是否使用了正确的SMTP授权码,而非邮箱密码?
      • 邮箱安全设置:发件邮箱是否已开启SMTP服务?某些邮箱(如Gmail)可能需要允许“不够安全的应用”访问(不推荐)或使用OAuth2.0验证(更复杂)。

5. 深度优化、扩展思路与避坑指南

一个能跑通的系统只是开始,要让其稳定、可靠、实用,还需要进行优化和功能扩展。这里分享一些进阶思路和实践中踩过的坑。

5.1 稳定性优化与功耗考量

  1. Wi-Fi连接稳定性 :在实际部署中,Wi-Fi可能不稳定。可以在 loop() 函数开头加入Wi-Fi重连逻辑。
    if (WiFi.status() != WL_CONNECTED) {
      Serial.println("Wi-Fi断开,尝试重连...");
      WiFi.reconnect();
      delay(5000); // 等待重连
    }
    
  2. 邮件发送防重入与队列 :当前代码中,每次检测到运动都会立即尝试发送邮件。如果在传感器延时内多次触发,会发送多封邮件。可以增加一个“冷却时间”标志位,例如发送邮件后,设置一个 lastEmailSentTime ,在接下来几分钟内不再发送新邮件。
  3. 降低功耗 :如果希望用电池供电,需要大幅降低功耗。
    • 使用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 功能扩展思路

  1. 集成精准的NTP时间 :如前所述,使用 NTPClient 库获取真实时间,让告警邮件包含“2023-10-27 14:30:25”这样的准确时间戳,而非设备运行时间。
  2. 添加其他传感器 :ESP32的GPIO和ADC资源丰富,可以轻松集成:
    • 温湿度传感器(DHT11/DHT22) :在告警邮件中附带环境温湿度信息。
    • 光线传感器(BH1750) :实现“仅在暗光条件下触发告警”的智能判断。
    • 声音传感器 :构成“动静结合”的双重验证,减少误报。
  3. 接入物联网平台 :将数据上报到更强大的平台进行可视化或复杂规则处理。
    • Home Assistant :通过MQTT协议,将ESP32的运动状态发布到Home Assistant,实现与家中其他智能设备的联动(如检测到运动自动开灯、录像)。
    • Blynk / ThingSpeak :快速创建手机App控制面板或数据图表。
  4. 启用HTTPS与身份验证 :当前的Web服务器是HTTP明文传输。为提高安全性,可以启用HTTPS(需要证书),并为网页添加简单的登录密码验证。
  5. 使用蜂鸣器或继电器 :将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与外界通信后,你就可以举一反三,用类似的架构去实现温度监控、湿度报警、智能开关等无数个物联网应用。动手去试,遇到问题就对照上面的表格排查,每一次解决问题的过程,都是对物联网技术更深一层的理解。

更多推荐