当前位置: 首页 > news >正文

ESP32 BLE接近检测:基于RSSI信号强度实现智能设备感知与自动化触发

1. 项目概述与核心价值

几年前,当我第一次尝试用ESP32做一个简单的门磁报警器时,我就在想,能不能把检测的对象从物理开关换成更“智能”的东西,比如我手腕上的那块智能手表。这个想法源于一个很实际的需求:我经常在书房工作时,手机调成静音,结果错过重要电话。如果手表靠近电脑时,能有一个明显的提示就好了。这就是今天要分享的“基于ESP32的BLE智能手表检测器”项目的由来。它本质上是一个基于蓝牙低功耗信号强度的接近检测器,核心逻辑是:当ESP32扫描到你的智能手表的BLE广播信号,并且信号强度(RSSI)达到预设的“足够近”的阈值时,就触发一个蜂鸣器发出提示音,同时点亮板载LED。

这个项目的价值远不止一个“手表探测器”。它为你打开了一扇门,让你理解如何让微控制器“感知”另一个智能设备的到来与离去。掌握了这套方法,你可以轻松地将触发条件从“手表靠近”替换成“手机回家”、“智能钥匙扣在范围内”或“特定的蓝牙信标出现”。而执行动作也可以从蜂鸣器扩展为控制继电器打开台灯、启动电脑、甚至发送一条网络通知。对于物联网爱好者和智能家居DIY玩家来说,这是一个绝佳的入门实践,它串联了无线通信、信号处理和硬件控制这几个关键环节。无论你是想为你的工作台增加一点自动化魔法,还是想深入学习ESP32的BLE功能,这个项目都能提供扎实的、可复现的动手经验。

2. 核心硬件与软件环境搭建

2.1 硬件清单与选型解析

工欲善其事,必先利其器。我们先来清点并理解每一件硬件的作用。

  1. ESP32开发板(核心):这是项目的大脑。我强烈推荐选择带有内置USB转串口芯片的型号,如ESP32 DevKitC V4或NodeMCU-32S。它们省去了外接下载器的麻烦,对新手极其友好。ESP32之所以是首选,是因为它原生双模蓝牙(经典和低功耗),且性能强大、价格亲民,社区支持完善。

  2. 有源蜂鸣器(执行器):注意,这里必须使用有源蜂鸣器。它与无源蜂鸣器的区别在于:有源蜂鸣器内部自带振荡电路,通电即响,频率固定;无源蜂鸣器则类似一个喇叭,需要外部输入特定频率的方波才能发声。本项目使用EasyBuzzer库,它主要通过控制引脚高低电平的持续时间来工作,更适合驱动有源蜂鸣器。购买时,选择工作电压为3.3V或5V的均可,ESP32的IO口输出3.3V,驱动3.3V蜂鸣器更稳妥。

  3. 面包板与杜邦线(连接器):用于快速搭建和测试电路,无需焊接。准备若干公对公杜邦线即可。

  4. 智能手表/手机(被检测设备):任何支持BLE广播的设备都可以作为被检测目标。智能手表、健身手环、智能手机是最常见的选择。你需要从中获取其蓝牙MAC地址。

注意:部分新款苹果设备(iPhone、Apple Watch)为了隐私保护,会使用随机MAC地址进行广播,这会导致我们无法通过固定MAC地址进行可靠过滤。本项目更适用于安卓设备、或已关闭随机MAC地址功能的苹果设备(通常在开发者选项里,且不推荐长期关闭)。

2.2 软件环境配置详解

软件环境是项目流畅进行的基础,一步错可能导致后续步步维艰。

2.2.1 Arduino IDE的安装与ESP32支持

首先,从Arduino官网下载并安装最新版Arduino IDE。安装完成后,打开IDE,进入“文件”->“首选项”。在“附加开发板管理器网址”中,填入以下网址:https://espressif.github.io/arduino-esp32/package_esp32_index.json(如果已有其他网址,用逗号隔开即可)。这一步是告诉Arduino IDE去哪里寻找ESP32的开发板支持包。

接着,打开“工具”->“开发板”->“开发板管理器”。在搜索框中输入“esp32”,找到由Espressif Systems提供的“ESP32”开发板包,点击安装。这个过程可能需要几分钟,取决于你的网络速度。

2.2.2 解决“Sketch Too Big”编译错误

这是ESP32项目开发中一个经典的坑。随着代码和库文件的增加,你可能会遇到编译错误,提示程序空间不足。这通常是因为Arduino IDE默认的“分区方案”不适合较大的项目。

解决方法:在Arduino IDE中,选择你的ESP32开发板后,在“工具”菜单下找到“Partition Scheme”(分区方案)选项。将其从默认的“Default”更改为“Huge APP (3MB No OTA/1MB SPIFFS)”。这个方案为程序代码分配了更大的空间(3MB),牺牲了OTA升级和文件系统的部分空间,对于本项目和大多数实验项目来说是完全足够的。

2.2.3 关键库的安装与配置

本项目需要两个核心库:

  • ESP32 BLE Arduino:这是由Espressif官方维护的库,提供了ESP32蓝牙功能的底层API。它通常随ESP32开发板包一起安装。你可以在“项目”->“加载库”->“管理库”中搜索“ESP32 BLE Arduino”确认。
  • EasyBuzzer:这是一个简化蜂鸣器控制的第三方库。我们需要手动安装它。
    1. 访问EasyBuzzer的GitHub仓库(通常搜索“EasyBuzzer Arduino”即可找到),下载ZIP文件。
    2. 在Arduino IDE中,点击“项目”->“加载库”->“添加.ZIP库…”,选择你刚下载的ZIP文件。

库文件的关键修改:根据原始资料,我们需要修改EasyBuzzer库的一个默认配置。找到你的Arduino库安装目录(Windows通常在C:\Users\[你的用户名]\Documents\Arduino\libraries\),进入EasyBuzzer库文件夹下的src子文件夹,找到Config.h文件。用文本编辑器打开它,找到这一行:#define DEFAULT_PIN 4将其修改为:#define DEFAULT_PIN 13这是因为我们计划将蜂鸣器连接在ESP32的GPIO13引脚上。这个修改是为了让库的默认引脚与我们实际硬件连接保持一致,方便测试。

2.2.4 获取目标设备的MAC地址

我们需要一个工具来“看到”周围BLE设备的广播信息,并获取其MAC地址。在安卓手机上,我强烈推荐使用nRF Connect这款应用(由Nordic Semiconductor开发,在应用商店即可下载)。它功能强大且免费。

操作流程:

  1. 打开手机蓝牙。
  2. 打开nRF Connect应用,点击右上角的“SCAN”按钮。
  3. 在设备列表中,找到你的智能手表或手环(通常以设备名称为标识,如“Mi Band 6”、“Galaxy Watch”)。
  4. 点击该设备条目,查看详细信息。其MAC地址(一个类似于E0:A1:07:B7:0B:95的字符串)会清晰地显示出来。请完整地记录下来。

3. 电路连接与硬件原理

硬件连接非常简单,但理解其背后的原理能让你在调试时事半功倍。

3.1 物理连接示意图

请按照以下方式连接:

  1. 蜂鸣器正极(+)->ESP32的GPIO13引脚
  2. 蜂鸣器负极(-)->ESP32的任意一个GND(接地)引脚
  3. ESP32的板载LED(通常连接在GPIO2上)在代码中已定义,无需额外接线,它会根据检测状态自动亮灭。

实操心得:在给ESP32通电进行连接操作前,务必断开USB数据线。连接好所有线路后,再插上USB线。这可以避免因误接导致的短路风险,保护你的开发板。对于有源蜂鸣器,正负极接反通常不会损坏它,但会导致不发声,检查时请留意。

3.2 核心硬件工作原理浅析

  • ESP32的BLE扫描机制:ESP32在代码中扮演一个“扫描者”的角色。它周期性地开启蓝牙射频接收器,监听特定无线电频段(2.4GHz ISM波段)上的广播数据包。所有BLE设备(如你的手表)都会间歇性地向外广播这些包含自身信息(如设备名、服务UUID、MAC地址、信号强度等)的小数据包。ESP32捕获到这些包后,会通过BLEAdvertisedDeviceCallbacks回调函数通知我们的程序。
  • RSSI(接收信号强度指示)的关键作用:RSSI值是一个负数,单位是dBm。它直观地反映了信号强弱。距离越近,障碍越少,RSSI值就越大(即负得越少)。例如,-40 dBm比-80 dBm的信号强得多。本项目正是利用RSSI值来判断设备是否“足够近”。代码中的if (Device.getRSSI() > -85)就是一个阈值判断,意思是“如果信号强度大于-85dBm(即比-85dBm强),则认为设备在范围内”。
  • GPIO驱动蜂鸣器:GPIO13引脚被设置为输出模式。当检测到目标设备时,代码会调用EasyBuzzer.beep(...)函数。这个函数内部会以我们设定的频率和间隔,循环地将GPIO13引脚置为高电平(3.3V)和低电平(0V)。对于有源蜂鸣器,高电平使其内部电路导通发声,低电平则停止。通过精确控制高、低电平的持续时间(onDuration,offDuration),我们就能制造出不同节奏的“嘀嘀”声。

4. 代码深度解析与定制化修改

原项目提供的代码是一个很好的起点,但其中有些细节和潜在问题需要我们深入理解并优化。下面我将逐段拆解,并提供增强版的代码思路。

4.1 库文件引入与全局变量定义

#include "BLEDevice.h" #include "EasyBuzzer.h" // --- 蜂鸣器参数配置 --- unsigned int frequency = 1000; // 频率 (Hz),对有源蜂鸣器无效,但需保留参数 unsigned int onDuration = 50; // 单次“嘀”声的持续时间 (ms) unsigned int offDuration = 100; // 两次“嘀”声之间的间隔时间 (ms) unsigned int beeps = 2; // 每次触发时,连续“嘀”的次数 unsigned int pauseDuration = 500; // 连续“嘀”完一组后的暂停时间 (ms) unsigned int cycles = 10; // 重复上述“组”的次数 // --- 硬件引脚定义 --- int LED = 2; // ESP32板载LED通常接在GPIO2 int BUZZER_PIN = 13; // 明确蜂鸣器引脚,增强可读性 // --- BLE相关变量 --- static BLEAddress *pServerAddress; BLEScan* pBLEScan; BLEClient* pClient; bool deviceFound = false; // --- 状态标志 --- bool LEDoff = false; // 用于记录LED状态,原代码命名易混淆,实际表示“LED该亮” // --- 核心:已知设备MAC地址列表 --- String knownAddresses[] = {"e0:a1:07:b7:0b:95"}; // 【必须修改】替换为你的设备MAC

修改与解析

  1. 我将蜂鸣器引脚单独定义为BUZZER_PIN,虽然EasyBuzzer库会使用我们修改后的默认引脚13,但显式定义能让代码意图更清晰。
  2. frequency参数对于有源蜂鸣器是无效的,因为它只能发出固定频率的声音。但这个参数必须保留,因为它是EasyBuzzer.beep()函数签名的一部分。
  3. knownAddresses是一个字符串数组。你可以在这里添加多个MAC地址,让ESP32同时检测多个设备。例如:String knownAddresses[] = {"MAC1", "MAC2", "MAC3"};(sizeof(knownAddresses) / sizeof(knownAddresses[0]))这段代码会自动计算数组的长度,这样添加或删除地址时,无需手动修改循环次数。

4.2 回调函数:BLE扫描的核心逻辑

这是整个项目的“大脑”,决定了ESP32如何识别你的设备。

class MyAdvertisedDeviceCallbacks: public BLEAdvertisedDeviceCallbacks { void onResult(BLEAdvertisedDevice advertisedDevice) { // 参数名更清晰 // 获取扫描到的设备地址 pServerAddress = new BLEAddress(advertisedDevice.getAddress()); // 调试:打印所有扫描到的设备(可选,打开后会刷屏) // Serial.print("Found: "); // Serial.println(advertisedDevice.toString().c_str()); bool isKnownDevice = false; // 遍历已知地址列表,进行匹配 for (int i = 0; i < (sizeof(knownAddresses) / sizeof(knownAddresses[0])); i++) { // 比较扫描到的地址与已知地址(转换为大写,避免大小写问题) if (strcasecmp(pServerAddress->toString().c_str(), knownAddresses[i].c_str()) == 0) { isKnownDevice = true; break; // 找到匹配项,立即跳出循环 } } if (isKnownDevice) { Serial.println("[INFO] Target device detected!"); Serial.print("[INFO] RSSI: "); Serial.println(advertisedDevice.getRSSI()); // 关键判断:根据RSSI设定触发距离 // RSSI > -60: 非常近 (约1米内) // RSSI > -70: 比较近 (约3-5米) // RSSI > -85: 中等距离 (约10米,隔墙效果会下降) int rssiThreshold = -70; // 【可调整】根据你的环境测试最佳值 if (advertisedDevice.getRSSI() > rssiThreshold) { deviceFound = true; Serial.println("[INFO] Device is WITHIN range. Triggering action."); } else { deviceFound = false; Serial.println("[INFO] Device is OUT OF range."); } // 停止本次扫描,准备执行动作或下一次扫描 advertisedDevice.getScan()->stop(); } } };

重要优化与解析

  1. 使用strcasecmp替代strcmp:原代码使用strcmp进行字符串比较,这是区分大小写的。但MAC地址的字符串表示有时可能大小写不一致。strcasecmp进行不区分大小写的比较,更加健壮。
  2. 引入break语句:一旦在已知列表中匹配到设备,立即用break跳出for循环,避免无意义的后续比较,提升效率。
  3. 可配置的RSSI阈值:我将阈值-85定义为一个变量rssiThreshold你必须根据实际环境测试并调整这个值。测试方法:上传代码后,打开串口监视器(波特率115200),拿着你的手表在不同距离移动,观察打印出来的RSSI值。确定一个你认为是“有效靠近”的数值(例如,走到桌子旁时RSSI约为-65,那就设-70)。
  4. 详细的串口输出:我增加了带标签的串口打印([INFO]),便于在众多日志中快速定位信息。

4.3 Setup()与Loop()函数流程

void setup() { Serial.begin(115200); Serial.println("\n[BOOT] ESP32 BLE Detector Initializing..."); // 初始化硬件引脚 pinMode(LED, OUTPUT); digitalWrite(LED, LOW); // 启动时LED熄灭 // EasyBuzzer库会自动初始化其默认引脚(我们已修改为13) // 初始化BLE BLEDevice::init(""); // 设备名称为空,因为我们只扫描不广播 pClient = BLEDevice::createClient(); pBLEScan = BLEDevice::getScan(); pBLEScan->setAdvertisedDeviceCallbacks(new MyAdvertisedDeviceCallbacks()); pBLEScan->setActiveScan(true); // 主动扫描,获取更多信息但更耗电 // pBLEScan->setInterval(100); // 可调整:扫描间隔(ms) // pBLEScan->setWindow(99); // 可调整:扫描窗口(ms),应小于等于间隔 Serial.println("[BOOT] Initialization complete. Starting scan loop..."); } void performScan() { // 将扫描逻辑封装成函数,比原名`Bluetooth`更贴切 Serial.println("[SCAN] --- Starting new BLE scan ---"); deviceFound = false; // 重置发现标志 // 开始扫描,持续5秒 BLEScanResults scanResults = pBLEScan->start(5, false); // 第二个参数false表示非阻塞式扫描(实际仍是阻塞,但API如此) // 扫描结束后,根据结果执行动作 if (deviceFound) { Serial.println("[ACTION] Triggering BUZZER & LED"); digitalWrite(LED, HIGH); EasyBuzzer.beep(frequency, onDuration, offDuration, beeps, pauseDuration, cycles); // 蜂鸣器会按照预设模式鸣叫,这是一个非阻塞调用 } else { Serial.println("[ACTION] No target in range. Turning off LED."); EasyBuzzer.stopBeep(); // 确保蜂鸣器停止 digitalWrite(LED, LOW); } // 短暂延迟,避免扫描过于频繁 delay(2000); // 【可调整】扫描周期 } void loop() { performScan(); // 执行一次完整的扫描-判断-动作流程 EasyBuzzer.update(); // 必须持续调用,以驱动蜂鸣器发出声音 // 其他非阻塞任务可以放在这里 }

流程详解与优化

  1. setup()函数负责一次性初始化。setActiveScan(true)启用主动扫描,这会向扫描到的设备发送扫描请求,以获取更多的响应数据(如设备名),功耗稍高但信息更全。如果只关心MAC和RSSI,可以设为false以省电。
  2. 我将主要的扫描和触发逻辑封装进performScan()函数,使loop()结构更清晰。
  3. pBLEScan->start(5)表示每次扫描持续5秒。这个时间越长,发现设备的概率越高,但每次检测的周期也越长。你需要根据设备广播间隔和应用场景权衡。智能手表广播通常比较频繁,2-3秒也足够。
  4. EasyBuzzer.update()是库函数要求的,必须放在loop()中频繁调用,它负责在后台更新蜂鸣器的状态,实现非阻塞的鸣叫效果。如果没有它,蜂鸣器将不会响。
  5. 扫描结束后,我添加了一个delay(2000)。这意味着一次完整的“扫描-执行”周期大约是“5秒扫描 + 2秒延迟 = 7秒”。你可以调整这个值来控制检测的灵敏度(频率)。

5. 高级调试技巧与实战问题排查

即使代码和连接都正确,在实际环境中你仍可能遇到各种问题。下面是我在多次实践中总结的排查清单。

5.1 常见问题速查表

问题现象可能原因排查步骤与解决方案
上传代码后,ESP32无任何反应1. 电源问题
2. 板子型号选择错误
3. 串口驱动问题
1. 检查USB线是否连接牢固,尝试更换USB口或数据线。
2. 在Arduino IDE的“工具”->“开发板”中,确认选择了正确的ESP32型号(如ESP32 Dev Module)。
3. 检查设备管理器中是否有未识别的端口,安装对应的CP210x或CH340驱动。
串口监视器看不到输出1. 波特率不匹配
2. 选错串口
3. 代码中Serial.begin()被禁用
1. 确保串口监视器右下角的波特率设置为115200
2. 在“工具”->“端口”中,选择正确的COM口(拔插USB线观察哪个端口出现/消失)。
3. 确认代码中Serial.begin(115200);语句存在且未被注释。
串口有输出,但始终找不到设备1. MAC地址错误
2. 设备未开启蓝牙或BLE广播
3. RSSI阈值设置过于苛刻
4. 扫描时间太短
1.【最关键】用nRF Connect重新确认MAC地址,检查代码中地址格式是否正确(冒号分隔,字母大写)。
2. 确保手表蓝牙已开,且未处于“飞行模式”或“剧院模式”(可能关闭广播)。
3. 先将阈值rssiThreshold调到一个非常宽松的值,如-100,看是否能发现设备。
4. 将pBLEScan->start(5)中的扫描时间增加到10秒。
能发现设备,但从不触发蜂鸣器1. RSSI阈值太高
2. 蜂鸣器接线错误或损坏
3.EasyBuzzer库未正确安装或修改
1. 查看串口输出的RSSI值,调整rssiThreshold低于该值。例如,设备在1米处RSSI为-65,则阈值应设为-66或更低。
2. 检查蜂鸣器正负极是否接反,尝试将蜂鸣器直接连接到3.3V和GND,看是否能响。
3. 确认EasyBuzzer库的Config.h文件中的DEFAULT_PIN已修改为13,并重启Arduino IDE。
蜂鸣器一直响,或触发后不停止1.deviceFound状态逻辑错误
2.EasyBuzzer.update()未调用
3. 扫描未正常停止
1. 检查if (deviceFound)的逻辑,确保在设备离开后deviceFound被重置为false
2. 确保loop()函数中调用了EasyBuzzer.update()
3. 在回调函数中,确认调用了advertisedDevice.getScan()->stop()
检测延迟高,反应慢1. 扫描周期(start参数)太长
2. 扫描后延迟(delay)太长
1. 减少pBLEScan->start()的持续时间,例如从5秒改为2秒。
2. 减少performScan()函数末尾的delay()时间。注意:周期太短可能导致功耗上升和CPU占用率高。

5.2 串口调试信息优化

为了更高效地调试,我建议在代码中添加不同等级的日志输出,并可以通过一个开关来控制。

// 在文件开头定义调试级别 #define DEBUG_LEVEL 2 // 0:无输出, 1:仅关键信息, 2:详细信息 #if DEBUG_LEVEL >= 1 #define LOG_I(x) Serial.println(x) #else #define LOG_I(x) #endif #if DEBUG_LEVEL >= 2 #define LOG_D(x) Serial.println(x) #else #define LOG_D(x) #endif // 在回调函数中使用 class MyAdvertisedDeviceCallbacks: public BLEAdvertisedDeviceCallbacks { void onResult(BLEAdvertisedDevice advertisedDevice) { pServerAddress = new BLEAddress(advertisedDevice.getAddress()); LOG_D("[DEBUG] Scanned: " + String(advertisedDevice.toString().c_str())); bool isKnownDevice = false; for (int i = 0; i < (sizeof(knownAddresses) / sizeof(knownAddresses[0])); i++) { if (strcasecmp(pServerAddress->toString().c_str(), knownAddresses[i].c_str()) == 0) { isKnownDevice = true; LOG_I("[INFO] MAC Matched: " + String(knownAddresses[i])); break; } } // ... 后续逻辑 } };

这样,在项目稳定后,你可以将DEBUG_LEVEL设为1或0,减少串口输出的干扰。

6. 项目扩展与进阶思路

这个基础项目就像一个乐高底座,你可以在此基础上搭建出各种有趣的应用。

6.1 硬件扩展:从蜂鸣器到继电器控制

将蜂鸣器替换为一个继电器模块,你就能控制交流电器。这是迈向智能家居的关键一步。

连接方式

  1. ESP32的GPIO13 -> 继电器模块的IN(或SIG)引脚。
  2. ESP32的5V引脚 -> 继电器模块的VCC引脚。
  3. ESP32的GND引脚 -> 继电器模块的GND引脚。
  4. 将你家用电器的电源线切断,一端接继电器模块的COM(公共端),另一端接NO(常开端)。这样,当GPIO13输出高电平时,继电器吸合,电路导通,电器通电。

代码修改: 只需将触发动作部分的代码从控制蜂鸣器改为控制继电器引脚。

#define RELAY_PIN 13 // 假设继电器接在13脚 void setup() { pinMode(RELAY_PIN, OUTPUT); digitalWrite(RELAY_PIN, LOW); // 初始状态为断开 // ... 其他初始化 } void performScan() { // ... 扫描逻辑 if (deviceFound) { LOG_I("[ACTION] Turning ON Relay"); digitalWrite(RELAY_PIN, HIGH); // 吸合继电器 digitalWrite(LED, HIGH); } else { LOG_I("[ACTION] Turning OFF Relay"); digitalWrite(RELAY_PIN, LOW); // 断开继电器 digitalWrite(LED, LOW); } // ... 后续逻辑 }

安全警告:操作220V交流电有生命危险!务必确保在完全断电的情况下进行接线,所有裸露的导线部分必须用绝缘胶带包裹好。如果你对强电不熟悉,建议先使用低压直流电器(如LED灯带、小风扇)进行练习。

6.2 软件优化:引入状态机与防抖机制

当前代码在设备处于临界距离时,可能会因为RSSI值在阈值上下波动,导致蜂鸣器频繁开关,形成“抖动”。引入一个简单的状态机和时间防抖可以解决这个问题。

// 新增全局变量 enum DetectorState { STATE_AWAY, STATE_NEAR }; DetectorState currentState = STATE_AWAY; unsigned long lastTriggerTime = 0; const unsigned long DEBOUNCE_DELAY = 3000; // 防抖时间,3秒内状态不变化 void performScan() { // ... 扫描逻辑,最终得到 deviceFound 布尔值 unsigned long currentTime = millis(); if (deviceFound && currentState == STATE_AWAY) { // 从未在范围内变为在范围内 if (currentTime - lastTriggerTime > DEBOUNCE_DELAY) { LOG_I("[STATE] Transition: AWAY -> NEAR"); currentState = STATE_NEAR; lastTriggerTime = currentTime; // 执行触发动作 digitalWrite(LED, HIGH); EasyBuzzer.beep(...); } } else if (!deviceFound && currentState == STATE_NEAR) { // 从在范围内变为不在范围内 if (currentTime - lastTriggerTime > DEBOUNCE_DELAY) { LOG_I("[STATE] Transition: NEAR -> AWAY"); currentState = STATE_AWAY; lastTriggerTime = currentTime; // 执行关闭动作 digitalWrite(LED, LOW); EasyBuzzer.stopBeep(); } } // 如果状态未发生变化,则什么也不做 }

这个机制确保了只有当设备稳定地进入或离开范围超过3秒后,才会触发状态切换和执行相应动作,有效避免了抖动。

6.3 网络集成:添加Wi-Fi与远程通知

ESP32具备Wi-Fi功能,可以轻松将检测事件发送到互联网。

思路

  1. 连接本地Wi-Fi:在setup()中加入Wi-Fi连接代码。
  2. 触发网络请求:当检测到设备时,除了本地蜂鸣,还可以使用HTTP客户端或MQTT客户端向一个网络服务器发送请求。
  3. 实现效果:你可以收到手机推送通知(通过IFTTT、Bark、Server酱等服务),或者在家庭自动化平台(如Home Assistant)中创建一个传感器实体,从而触发更复杂的自动化流程。

例如,使用HTTP GET请求发送到IFTTT的Webhooks:

#include <WiFi.h> #include <HTTPClient.h> const char* ssid = "你的Wi-Fi名称"; const char* password = "你的Wi-Fi密码"; const char* iftttURL = "https://maker.ifttt.com/trigger/watch_detected/json/with/key/YOUR_KEY"; void connectToWiFi() { WiFi.begin(ssid, password); while (WiFi.status() != WL_CONNECTED) { delay(500); Serial.print("."); } Serial.println("WiFi Connected!"); } void sendNotification() { if (WiFi.status() == WL_CONNECTED) { HTTPClient http; http.begin(iftttURL); int httpCode = http.GET(); if (httpCode > 0) { Serial.printf("[HTTP] Notification sent, code: %d\n", httpCode); } http.end(); } } // 然后在 deviceFound 为真时调用 sendNotification();

这个小小的改动,瞬间将你的本地探测器接入了广阔的物联网世界。

从我自己的使用体验来看,这个项目的稳定性很大程度上取决于RSSI阈值的校准和环境的蓝牙干扰程度。在办公室这种蓝牙设备密集的环境,阈值可能需要设得更高(如-60)来避免误触发。而在家里,-70左右通常就能很好地工作。另外,将ESP32的天线部分(板载PCB天线)朝向预计设备来的方向,也能稍微改善信号接收。最后,别忘了给它配一个好看的壳子,毕竟一个裸露着电路板和跳线的“探测器”,可算不上是合格的智能家居产品。

http://www.gsyq.cn/news/1454154.html

相关文章:

  • 2026年河北短视频获客与AI GEO全网推荐优化服务商深度对比指南 - 优质企业观察收录
  • 别再只会写脚本了!MATLAB函数文件(.m)从入门到实战(含匿名函数与全局变量避坑)
  • 2026年企业短视频培训深度测评:如何为你的企业匹配最佳方案 - 资讯纵览
  • 2026年 东魁杨梅/仙居杨梅品牌推荐榜:汁多味甜、个头饱满的产地直供与品控优选指南 - 品牌企业推荐师(官方)
  • Arduino低功耗改造:实现无线温湿度传感器一年续航
  • 2026安阳房屋漏水不用愁!一修修缮免费上门检测,本地专业防水公司常年TOP1!卫生间免砸砖防水,快速解决您的烦恼。权威!靠谱!稳定!售后无忧!!! - 一休咨询
  • 2026南京翡翠回收实测测评:六大平台综合实力排名盘点 - 薛定谔的梨花猫
  • 质量可靠吗?8款AI论文工具综合榜,毕业护航利器!
  • 保姆级教程:用ROS Noetic和YOLOv8n搞定摄像头云台自动追踪(附完整代码)
  • 2026年6月石家庄离婚纠纷律师郝淑巧:深耕婚家二十六载,以专业守护家事安宁,用温情守护家庭尊严 - 十大排行榜推荐
  • 专柜 10 万回收只给 3 万?哈尔滨手表回收机构盘点 + 避坑攻略,少亏就是赚 - 合扬奢侈品交易中心
  • 2026可拆洗羊毛地毯,解锁居家清洁新方式 - 资讯纵览
  • 2026苏州黄金回收六关严测!四大正规入围门店,满分标杆认准合扬 - 合扬奢侈品交易中心
  • 为低识字人群设计多模态交互系统:图标、语音与情境感知的融合实践
  • 路之所止,行之所启
  • 【银川市余生黄金回收全品类金银铂钯贵金属回收】 - 润富黄金回收
  • 珠海亨得利名表维修靠谱吗?劳力士欧米茄卡地亚帝舵浪琴百达翡丽宝珀积家爱彼用户真实亲测 - 亨得利腕表维修中心
  • 行业扫盲:2026最新广州手表回收靠谱门店全城清单 - 奢侈品回收
  • 构建实时告警系统:监控 Agent 异常行为
  • 从能造到造好,国内模具设计制造领域的新一轮供应逻辑 - 深度智识库
  • 2026年最新的 廊坊水处理药剂品牌排行:5个主流品牌实力解析 - 奔跑123
  • 2026年文山装修公司大宅全案TOP4排名:口碑施工设计能力综合测评 - 优家闲谈
  • 从零搭建交互式3D投影桌:硬件选型、软件集成与调试全攻略
  • 基于Arduino的物理勿扰开关:从数字IO到环境设计的嵌入式实践
  • 热式气体质量流量计厂家十大品牌盘点|助你快速选型 - 流量计品牌
  • 别再手动画圆了!用Arcpy脚本工具批量生成矢量圆(附完整Python代码与ArcGIS工具箱配置)
  • PyTorch老项目救星:手把手教你用Conda精准锁定并安装1.13.0等历史版本(附版本对照表)
  • 告别编译报错!手把手教你用VS2022编译64位libmodbus动态库(附完整依赖项配置)
  • 2026宁波奢侈品回收全品类:合扬持证鉴定一站式盘活闲置资产 - 合扬奢侈品交易中心
  • 忆阻器神经形态计算优化:TiO2器件与算法协同设计实战