RError.com

RError.com Logo RError.com Logo

RError.com Navigation

  • 主页

Mobile menu

Close
  • 主页
  • 系统&网络
    • 热门问题
    • 最新问题
    • 标签
  • Ubuntu
    • 热门问题
    • 最新问题
    • 标签
  • 帮助
主页 / 问题 / 1593976
Accepted
Seffel
Seffel
Asked:2024-09-16 17:13:27 +0000 UTC2024-09-16 17:13:27 +0000 UTC 2024-09-16 17:13:27 +0000 UTC

我可以通过蓝牙获取 ESP32 连接设备的数据吗?

  • 772

我需要 ESP32 上的自动“身份验证”。我想通过蓝牙将特定手机连接到固件内的 ESP 来实现它。例如:我进入 ESP32 蓝牙连接的范围内,手机自动连接到该网络,ESP32 看到这一点,接收所连接设备的 MAC 地址和有关该设备的其他不可变数据(如果有),然后生成哈希值数据并将其与内存中存储的数据进行比较,如果哈希值相同,则将标志设置为 True;如果没有设备或连接了其他设备,则标志的值为 False;

bluetooth
  • 2 2 个回答
  • 30 Views

2 个回答

  • Voted
  1. Seffel
    2024-09-17T14:46:27Z2024-09-17T14:46:27Z

    在网上摸索了很长时间,我找到了一个更适合自己的解决方案。文章中描述了其实现:https://microkontroller.ru/esp32-projects/ispolzovanie-bluetooth-low-energy-ble-v-esp32-dl ​​ya-soedineniya -s-fitnes-brasletom/ 发布于 01/30/2022由管理员新

    感谢作者!

    代码:

    #include <BLEDevice.h> //Header file for BLE 
    static BLEUUID serviceUUID("xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxx"); //Service UUID фитнес браслета, полученный с помощью приложения nRF connect 
    static BLEUUID    charUUID("xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxx"); //Characteristic  UUID фитнес браслета, полученный с помощью приложения nRF connect
    String My_BLE_Address = "ff:ff:ff:ff:ff:ff"; //аппаратный    Bluetooth MAC нашего фитнес браслета,  полученный с помощью приложения nRF connect. Будет отличаться для каждого браслета 
    static BLERemoteCharacteristic* pRemoteCharacteristic;
    BLEScan* pBLEScan; //Name the scanning device as pBLEScan
    BLEScanResults foundDevices;
    static BLEAddress *Server_BLE_Address;
    String Scaned_BLE_Address;
    boolean paired = false; //boolean variable to togge light (логическая переменная для включения/выключения света)
     
    bool connectToserver (BLEAddress pAddress){
        
        BLEClient*  pClient  = BLEDevice::createClient();
        Serial.println(" - Created client");
        // Connect to the BLE Server. (соединение с BLE сервером)
        pClient->connect(pAddress);
        Serial.println(" - Connected to fitnessband");
        // Obtain a reference to the service we are after in the remote BLE server.
        BLERemoteService* pRemoteService = pClient->getService(serviceUUID);
        if (pRemoteService != nullptr)
        {
          Serial.println(" - Found our service");
          return true;
        }
        else
        return false;
        // Obtain a reference to the characteristic in the service of the remote BLE server.
        pRemoteCharacteristic = pRemoteService->getCharacteristic(charUUID);
        if (pRemoteCharacteristic != nullptr)
          Serial.println(" - Found our characteristic");
          return true;
    }
    class MyAdvertisedDeviceCallbacks: public BLEAdvertisedDeviceCallbacks 
    {
        void onResult(BLEAdvertisedDevice advertisedDevice) {
          Serial.printf("Scan Result: %s \n", advertisedDevice.toString().c_str());
          Server_BLE_Address = new BLEAddress(advertisedDevice.getAddress());
          
          Scaned_BLE_Address = Server_BLE_Address->toString().c_str();
          
        }
    };
    void setup() {
        Serial.begin(115200); //инициализируем последовательную связь 
        Serial.println("ESP32 BLE Server program"); //печатаем приветственное сообщение
        BLEDevice::init("");
        pBLEScan = BLEDevice::getScan(); //начинаем новое сканирование
        pBLEScan->setAdvertisedDeviceCallbacks(new MyAdvertisedDeviceCallbacks()); //Call the class that is defined above 
        pBLEScan->setActiveScan(true); // активное сканирование потребляет больше мощности, но быстрее получает результат
        pinMode (13,OUTPUT); //задаем режим работы для контакта на вывод данных 
    }
    void loop() {
      foundDevices = pBLEScan->start(5); // сканируем в течение 5-х секунд чтобы найти фитнес браслет 
      while (foundDevices.getCount() >= 1)
      {
        if (Scaned_BLE_Address == My_BLE_Address && paired == false)
        {
          Serial.println("Found Device :-)... connecting to Server as client");
           if (connectToserver(*Server_BLE_Address))
          {
          paired = true;
          Serial.println("********************LED turned ON************************");
          digitalWrite (13,HIGH);
          break;
          }
          else
          {
          Serial.println("Pairing failed");
          break;
          }
        }
        
        if (Scaned_BLE_Address == My_BLE_Address && paired == true)
        {
          Serial.println("Our device went out of range"); // устройство вне диапазона действия
          paired = false;
          Serial.println("********************LED OOOFFFFF************************");
          digitalWrite (13,LOW);
          ESP.restart();
          break;
        }
        else
        {
        Serial.println("We have some other BLe device in range"); //некоторые BLe устройства в зоне нашего действия
        break;
        }
      } 
    }
    

    说明:ESP32模块程序的主要思想是使其成为蓝牙客户端,不断扫描蓝牙设备的电波,当它找到我们的服务器(健身手环)时,它会检查其硬件ID,如果是如果正确,则它将通过向引脚 13 发送适当的信号来打开灯。

    乍一看,一切似乎很简单,但这里的问题是,所有 BLE 服务器的范围约为 10 米,这对于我们的项目来说是比较大的 - 毕竟,在这样的范围内,房间里的灯会在以下情况下打开:我们在另一个房间。

    为了缩小 BLE 服务器的范围,我们将使用配对选项。仅当 BLE 服务器和 BLE 客户端之间的距离不超过 3-4 米时,它们才被视为已连接(“配对”)。这个距离已经非常适合我们的项目了。也就是说,在 ESP32 模块的程序中,我们不仅会扫描空间中是否存在 BLE 服务器,还会连接到它并与其“配对”。只要我们的 BLE 服务器和客户端保持“配对”,交流灯就会保持亮起状态。一旦它们之间的距离超过“配对”半径,灯就会关闭。

    文章最后给出了该程序的完整代码,但这里我们将简单看一下它的主要片段。

    在程序代码中连接必要的库后,我们在程序中指示我们之前使用 nRF connect 应用程序获得的 BLE 地址、服务和特征 UUID。接下来,在设置函数中,我们初始化串行通信并启用 ESP 模块中的 BLE 来扫描电波。扫描完成后,将为每个检测到的设备调用 MyAdvertishedDeviceCallbacks 函数。

    当我们使用固定电源为 ESP32 模块供电时,我们将使用主动扫描空气;当使用电池供电时,我们将关闭它以节省功耗。继电器的触发触点连接到模块的引脚13,因此对于该引脚,我们将工作模式设置为数据输出。在 MyAdvertizedDeviceCallbacks 函数中,我们将显示在串行通信监视器窗口中检测到的 BLE 设备的名称和其他信息。我们需要检测到的设备的硬件 ID - 我们会将其与预定值(即与我们需要的值)进行比较。因此,我们将使用 Server_BLE_Address 变量来获取设备地址,然后将 BLEAddress 类型转换为字符串。在循环函数内,我们将扫描空气 3 秒,并将扫描结果放置在foundDevices 对象中,该对象是 BLEScanResults 类的对象。如果我们在扫描过程中检测到一台或多台设备,我们将检查这些设备的 BLE 地址是否与我们需要的地址匹配。如果地址匹配,但设备之前尚未“配对”,我们将尝试使用 connectToserver 函数将它们“配对”。我们还将在串行通信监视窗口中显示一些信息以供调试之用。在 connectToserver 函数中,我们将使用 UUID 来连接/“配对”我们的 BLE 服务器和客户端。我们的客户端是ESP32模块,因此我们使用createClient()函数在程序中创建它,然后连接到BLE服务器地址。接下来,我们使用 UUID 值搜索服务和特征并尝试连接。当连接成功建立时,该函数将返回true,如果连接未建立,则返回false。请注意,无需知道服务和特征 UUID 即可与服务器“配对”;我们在此将其用于教育目的。如果连接成功建立,那么我们将向引脚13施加高电平,并使用break命令将控制权转移到循环函数之外。逻辑变量paired将被设置为true。设备“配对”成功并将引脚 13 设置为高电平后,我们需要检查设备是否在我们的范围内。由于我们的设备已经“配对”,扫描 BLE 设备将无法再看到该设备。只有当佩戴手环的用户离开我们的操作区域时,我们才能通过扫描找到它。因此,我们需要检查这一事实,如果我们发现 BLE 服务器超出了 ESP32 模块的范围,我们将引脚 13 设置为低电平并将配对变量设置为 false。

    • 0
  2. Best Answer
    Seffel
    2024-09-18T05:39:12Z2024-09-18T05:39:12Z

    重新编写上面的代码后,可以大大简化并加快速度。我附上带有评论的编辑版本:

    #include <BLEDevice.h>
    
    #define out_pin 22 // Пин светодиода на плате
    #define time_sleep 3 // Время сканирования устройств
    #define level_RSSI -75 // Уровень сигнала при достижении которого плата будет считать что браслет вне зоны доступа
    
    String My_BLE_Address = "ff:ff:ff:ff:ff:ff"; //Mac-адрес фитнес браслета
    
    BLEScan* pBLEScan;
    BLEScanResults *foundDevices;
    static BLEAddress *Server_BLE_Address;
    String Scaned_BLE_Address;
    String Scaned_BLE_RSSI;
    
    boolean paired = false;
    
    class MyAdvertisedDeviceCallbacks: public BLEAdvertisedDeviceCallbacks 
    {
        void onResult(BLEAdvertisedDevice advertisedDevice) {
          //Serial.printf("Scan Result: %s \n", advertisedDevice.toString().c_str()); // Вывод списка обнаруженных устройств со сведениями
          Server_BLE_Address = new BLEAddress(advertisedDevice.getAddress());
          Scaned_BLE_Address = Server_BLE_Address->toString().c_str();
          Scaned_BLE_RSSI    = advertisedDevice.getRSSI();
          if (Scaned_BLE_Address == My_BLE_Address && Scaned_BLE_RSSI.toInt() > level_RSSI) { 
            //Serial.println(Scaned_BLE_RSSI); // Вывод текущего уровня сигнала если он не превышает лимит
            paired = true; 
          }
        }
    };
    void setup() {
        Serial.begin(115200);
        BLEDevice::init("SonZMoon");
        pBLEScan = BLEDevice::getScan();
        pBLEScan->setAdvertisedDeviceCallbacks(new MyAdvertisedDeviceCallbacks());
        pBLEScan->setActiveScan(true);
        pinMode (out_pin, OUTPUT);
        digitalWrite (out_pin, HIGH);
    }
    void loop() {
      paired = false;
      foundDevices = pBLEScan->start(time_sleep);
      if (paired == true) {
        digitalWrite (out_pin, LOW);
      } else {
        digitalWrite (out_pin, HIGH);
      }
    }
    
    • 0

相关问题

  • 使用台式电脑作为BT音频设备

  • Linux Mint 无法与蓝牙耳机配对

Sidebar

Stats

  • 问题 10021
  • Answers 30001
  • 最佳答案 8000
  • 用户 6900
  • 常问
  • 回答
  • Marko Smith

    我看不懂措辞

    • 1 个回答
  • Marko Smith

    请求的模块“del”不提供名为“default”的导出

    • 3 个回答
  • Marko Smith

    "!+tab" 在 HTML 的 vs 代码中不起作用

    • 5 个回答
  • Marko Smith

    我正在尝试解决“猜词”的问题。Python

    • 2 个回答
  • Marko Smith

    可以使用哪些命令将当前指针移动到指定的提交而不更改工作目录中的文件?

    • 1 个回答
  • Marko Smith

    Python解析野莓

    • 1 个回答
  • Marko Smith

    问题:“警告:检查最新版本的 pip 时出错。”

    • 2 个回答
  • Marko Smith

    帮助编写一个用值填充变量的循环。解决这个问题

    • 2 个回答
  • Marko Smith

    尽管依赖数组为空,但在渲染上调用了 2 次 useEffect

    • 2 个回答
  • Marko Smith

    数据不通过 Telegram.WebApp.sendData 发送

    • 1 个回答
  • Martin Hope
    Alexandr_TT 2020年新年大赛! 2020-12-20 18:20:21 +0000 UTC
  • Martin Hope
    Alexandr_TT 圣诞树动画 2020-12-23 00:38:08 +0000 UTC
  • Martin Hope
    Air 究竟是什么标识了网站访问者? 2020-11-03 15:49:20 +0000 UTC
  • Martin Hope
    Qwertiy 号码显示 9223372036854775807 2020-07-11 18:16:49 +0000 UTC
  • Martin Hope
    user216109 如何为黑客设下陷阱,或充分击退攻击? 2020-05-10 02:22:52 +0000 UTC
  • Martin Hope
    Qwertiy 并变成3个无穷大 2020-11-06 07:15:57 +0000 UTC
  • Martin Hope
    koks_rs 什么是样板代码? 2020-10-27 15:43:19 +0000 UTC
  • Martin Hope
    Sirop4ik 向 git 提交发布的正确方法是什么? 2020-10-05 00:02:00 +0000 UTC
  • Martin Hope
    faoxis 为什么在这么多示例中函数都称为 foo? 2020-08-15 04:42:49 +0000 UTC
  • Martin Hope
    Pavel Mayorov 如何从事件或回调函数中返回值?或者至少等他们完成。 2020-08-11 16:49:28 +0000 UTC

热门标签

javascript python java php c# c++ html android jquery mysql

Explore

  • 主页
  • 问题
    • 热门问题
    • 最新问题
  • 标签
  • 帮助

Footer

RError.com

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

帮助

© 2023 RError.com All Rights Reserve   沪ICP备12040472号-5