进入家中后立即自动打开灯,离开时再次将其关闭,真是太酷了!是的,一个简单的应用程序可以为您完成此任务。在此项目中,我们将ESP32用作BLE客户端,将健身手环用作BLE服务器,因此,只要佩戴健身手环的人进入ESP32蓝牙范围,ESP32都会检测到它并打开Light。任何具有BLE服务器功能的蓝牙设备都可以用作触发设备,以使用ESP32控制任何家用电器。
我们已经探索了ESP32模块的BLE(蓝牙低功耗)功能,对此我感到非常兴奋。概括地说,该模块同时具有经典的蓝牙和低功耗蓝牙(BLE),经典的蓝牙可用于传输歌曲或文件,而BLE选项可用于电池优化的应用,例如蓝牙信标,健身带,感应器等。 ,也可以将它用作串行蓝牙,例如HC-05或HC-06模块,用于简单的微控制器项目。
如您所知,ESP32 BLE可以在两种不同的模式下运行。一种是服务器模式,我们已经通过利用GATT服务来模拟电池电量指示器服务来进行讨论。在该练习中,ESP32充当服务器,而我们的手机充当客户端。现在,让我们将ESP32作为客户端进行操作,并尝试将其连接到其他BLE服务器(例如我的健身带)。
包括我的健身带在内的所有BLE服务器均处于恒定播发模式,这是在客户端扫描时始终可以发现它们。通过利用此功能,我们可以将这些健身带用作接近开关,这意味着这些健身带始终与用户的手绑在一起,并且通过扫描该健身带,我们可以检测到该人是否在范围内。这正是我们在本文中要做的。我们将对ESP32进行编程以使其作为BLE客户端并不断扫描BLE设备;如果找到适合的频段,我们将尝试连接到该频段,如果连接成功,则可以通过切换ESP32上的GPIO引脚之一来触发灯泡。该方法可靠,因为每个BLE服务器(健身带)将具有唯一的硬件ID,因此不会有两个BLE服务器设备相同。有趣吧?!现在,让我们开始建造
先决条件
在本文中,我假设您已经熟悉如何将ESP32开发板与Arduino IDE结合使用,如果您还不熟悉ESP32入门指南的话。
为了便于理解,我们将整个 ESP32蓝牙分为三个部分。因此,建议在开始本教程之前先阅读前两个教程。
- ESP32上的串行蓝牙从手机切换LED
- BLE服务器使用GATT服务将电池电量数据发送到手机
- BLE客户端扫描BLE设备并充当信标。
我们已经介绍了前两个教程,在这里我们将继续介绍最后一个教程,以将ESP32解释为BLE客户端。
所需材料
- ESP32开发板
- 交流负载(灯)
- 继电器模块
硬件
ESP32 BLE Client项目的硬件非常简单,因为大多数魔术都发生在代码内部。发现或丢失蓝牙信号后,ESP32必须拨动交流灯(负载)。要切换此负载,我们将使用继电器,并且由于ESP32的GPIO引脚仅兼容3.3V,因此我们需要一个可以用3.3V驱动的继电器模块。只要检查继电器模块中使用的是BC548,您可以按照以下电路图来构建自己的电路。
警告:该电路处理直流220V交流主电源电压。小心带电电线,并确保不要造成短路。你被警告了。
在BC547或2N2222上使用BC548的原因是它们的基极-发射极电压低,仅需3.3V即可触发。这里使用的继电器是5V继电器,因此我们通过Vin引脚为它供电,该引脚通过电源线获得5V电压。接地引脚连接到电路的接地。所述电阻R1 1K被用作基极电流限制器的电阻。相线连接到继电器的NO引脚,继电器的公共端连接到负载,负载的另一端连接到中性线。您可以调换相位和中性的位置,但请注意不要直接做空。电流应始终流经负载(灯泡)。我使用了继电器模块来简化操作,这里的负载是一个聚焦LED灯。我的设置如下所示
如果您现在想跳过硬件,可以使用GPIO 2引脚而不是GPIO 13引脚来切换ESP32上的板载LED。建议初学者使用此方法。
获取服务器的蓝牙地址(健身带地址)
如前所述,我们将对ESP32进行编程以使其作为客户端(类似于电话)并连接到服务器(这是我的健身带)(联想HW-01)。为了使客户端连接到服务器,它必须知道服务器的蓝牙地址。每个蓝牙服务器(如我的健身带)都具有其自己的永久蓝牙地址。您可以将其与笔记本电脑或手机的MAC地址相关联。
为了从服务器获得该地址,我们使用了来自北欧半导体的名为nRF connect的应用程序,该应用程序已在我们之前的教程中使用。IOS和Android用户均可免费使用。只需下载,启动应用程序并扫描附近的蓝牙设备。该应用程序将列出找到的所有BLE设备。我的名字叫HW-01,只需在它的名字下面看,就可以找到服务器的硬件地址,如下所示。
因此,我的适用范围的ESP32 BLE硬件地址为C7:F0:69:F0:68:81,您将使用同一格式的一组不同的数字。只需记下它,因为在编写ESP32时我们将需要它。
获取服务器的服务和特征UUID
好的,现在我们已经使用BLE地址标识了我们的服务器,但是为了与之通信,我们需要使用服务和特性语言,如果您已阅读上一教程,您将理解。在本教程中,我将使用服务器的写入特征(适应范围)与它配对。因此,为了与设备配对,我们需要可以通过同一应用程序再次获得的服务广告特征UUID。
只需单击应用程序上的连接按钮并搜索一些写入特征,该应用程序将在其中显示服务UUID和特征UUID。我的如下图所示
在这里,我的服务UUID和特征UUID是相同的,但不必相同。记下服务器的UUID。我的被记录为
服务UUID: 0000fee7-0000-1000-8000-00805f9b34fb 特征UUID:0000fee7-0000-1000-8000-00805f9b34fb
使用写特征不是强制性的。您可以使用应用程序中显示的服务器的任何有效服务和特征性UUID。
对ESP32进行编程以充当接近开关应用程序的客户端
该程序的想法是让ESP32充当客户端,在找到我们的服务器(健身频段)时继续扫描蓝牙设备,它会验证硬件ID,并将通过GPIO引脚13切换指示灯。好吧! !,但是有一个问题。所有BLE服务器的射程均为10米,这有点太大了。因此,如果我们试图使接近开关打开开门灯,则该范围非常高。
为了减小BLE服务器的范围,我们可以使用配对选项。仅当BLE服务器和客户端都在3-4米的距离内时,它们才会保持配对。这对于我们的应用程序来说是完美的。因此,我们制作ESP32不仅可以发现BLE服务器,还可以连接到它并确定它是否保持配对状态。 只要配对,交流电灯将保持打开状态,当超出配对范围时,交流电灯将丢失,并且交流电灯将关闭。本页尾给出了完整的ESP32 BLE示例程序。在下面,我将代码分成小片段并尝试对其进行解释。
包含头文件后,我们将通过nRF连接应用程序获得的BLE地址,服务和特征性UUID告知ESP32,如上标题所述。代码如下
静态BLEUUID serviceUUID (“ 0000fee7-0000-1000-8000-00805f9b34fb”);//通过nRF获取的健身带的服务UUID连接应用程序 静态BLEUUID charUUID(“ 0000fee7-0000-1000-8000-00805f9b34fb”); //通过nRF连接应用程序String My_BLE_Address =“ c7:f0:69:f0:68:81”获得的Fitnessband的特征性UUID ;//我的Fitnessband的硬件蓝牙MAC,对于通过nRF connect应用程序获得的每个频带都会有所不同
接下来,在程序中,我们有 connectToserver 和 MyAdvertisedDeviceCallback ,我们将在稍后返回。然后在 设置 功能中,我们初始化串行监视器,并使ESP上的BLE扫描设备。对发现的每个BLE设备完成扫描后,将调用函数 MyAdvertisedDeviceCallbacks 。
由于我们使用市电为ESP32供电,因此我们也启用了主动扫描功能,在电池应用中将其关闭以减少电流消耗。继电器触发引脚在我们的硬件中连接到GPIO 13,因此我们也将GPIO引脚13声明为输出。
void setup(){ Serial.begin(115200); //启动串口监控器 Serial.println(“ ESP32 BLE Server program”); //简介消息 BLEDevice:: init(“”); pBLEScan = BLEDevice:: getScan(); //创建新的扫描 pBLEScan-> setAdvertisedDeviceCallbacks(new MyAdvertisedDeviceCallbacks()); //调用在 pBLEScan-> setActiveScan(true)上 定义的类; //主动扫描会消耗 更多功率,但会更快获得结果pinMode(13,OUTPUT); //将内置的LED引脚声明为输出}
在 MyAdvertisedDeviceCallbacks 函数内部,我们打印行,其中将列出发现的BLE设备的名称和其他信息。我们需要发现的BLE设备的硬件ID,以便可以将其与所需的设备进行比较。因此,我们使用变量 Server_BLE_Address 来获取设备的地址,然后还将其从BLEAddress类型转换为字符串。
类MyAdvertisedDeviceCallbacks:公共BLEAdvertisedDeviceCallbacks { 空隙onResult(BLEAdvertisedDevice advertisedDevice){ Serial.printf:;( “扫描结果%S \ n”个,advertisedDevice.toString()c_str()。) Server_BLE_Address =新的BLEAddress(advertisedDevice.getAddress()); Scaned_BLE_Address = Server_BLE_Address-> toString()。c_str(); } };
在 循环 函数内部,我们扫描3秒钟,并将结果放入BLEScanResults中的对象foundDevices中。如果通过扫描找到一台或多台设备,我们将开始检查发现的BLE地址是否与我们在程序中输入的地址匹配。如果匹配为正,并且设备未提前配对,我们尝试使用connectToserver函数对其进行配对。我们也很少使用Serial语句来理解目的。
while(foundDevices.getCount()> = 1) { 如果(Scaned_BLE_Address == My_BLE_Address && paired == false) { Serial.println(“ Found Device:-)…以客户端身份连接到服务器”); 如果(connectToserver(* Server_BLE_Address)) {
在 connectToserver 函数内部,我们利用UUID与BLE服务器配对(适应带)。为了与服务器连接,ESP32必须充当客户端,因此我们使用 createClient() 函数创建一个客户端,然后连接到BLE服务器的地址。然后,我们使用UUID值搜索服务和特征,然后尝试连接到该服务和特征。连接成功后,该函数返回true,否则返回false。请注意,将服务和特征性UUID与服务器配对不是强制性的,仅出于您的理解而进行。
bool connectToserver(BLEAddress pAddress){ BLEClient * pClient = BLEDevice:: createClient(); Serial.println(“-创建的客户端”); //连接到BLE服务器。 pClient-> connect(pAddress); Serial.println(“-已连接到Fitnessband”); //获取对我们在远程BLE服务器中追求的服务的引用。 BLERemoteService * pRemoteService = pClient-> getService(serviceUUID); 如果(pRemoteService!= nullptr) { Serial.println(“-找到我们的服务”); 返回true; } 否则 将返回false; //获取对远程BLE服务器服务中的特征的引用。 pRemoteCharacteristic = pRemoteService->getCharacteristic(charUUID); if(pRemoteCharacteristic!= nullptr) Serial.println(“-找到我们的特征”); 返回true; }
如果连接成功,则将GPIO引脚13设为高电平,并使用break语句将控制发送到循环外部。成对的布尔变量也设置为true。
如果(connectToserver(* Server_BLE_Address)) { 成对= true; Serial.println(“ ******************** LED点亮********************** **“); digitalWrite(13,HIGH); 打破; }
配对成功且GPIO引脚打开后,我们必须检查设备是否仍在范围内。由于现在设备已配对,因此BLE扫描服务将不再能够看到它。仅当用户离开该区域时,我们才会再次找到它。因此,我们只需要扫描掉BLE服务器,如果发现我们必须将GPIO引脚设置为低电平,如下所示
if(Scaned_BLE_Address == My_BLE_Address && paired == true) { 序列号。println (“我们的设备超出范围”); 成对=假; 序列号。println (“ ******************** LED OOOFFFFF ************************” ); digitalWrite(13,LOW); ESP.restart(); 打破; }
工作与测试
准备好程序和硬件设置后,只需将代码上传到ESP32并按如下所示安排整个设置。
健身腕带(服务器)与ESP32配对后,您应该注意到灯泡已打开。您也可以通过注意健身腕带上的连接蓝牙符号来检查此情况。配对后,请尝试离开ESP32,当您越过3-4米时,您会注意到手表上的蓝牙符号消失并且连接断开。现在,如果您看一下灯泡,它将关闭。当您走进去时,设备会再次配对,并且指示灯会亮起。您可以在下面的视频中找到该项目的完整工作。
希望您喜欢这个项目并在此途中学到了一些新东西。如果您在使用它时遇到任何问题,请随时在论坛或下面的评论部分中发布问题