ripred

ESP32_Client.ino

Aug 13th, 2025 (edited)
358
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 6.09 KB | Source Code | 0 0
  1. /**
  2.  * A BLE client example that is rich in capabilities.
  3.  * There is a lot new capabilities implemented.
  4.  * author unknown
  5.  * updated by chegewara
  6.  *
  7.  * Patched: remove unsafe notify registration, fix return value, add safety checks.
  8.  */
  9. #include <string>
  10. #include "BLEDevice.h"
  11. #include "BLEScan.h"
  12.  
  13. // The remote service we wish to connect to.
  14. static BLEUUID serviceUUID("38d98c26-26ed-430d-83ee-04848df9c4e3");
  15.  
  16. // The characteristic of the remote service we are interested in.
  17. static BLEUUID charUUID("0f9162bf-09eb-42c0-853d-19ea0847a71d");
  18.  
  19. static boolean doConnect = false;
  20. static boolean connected = false;
  21. static boolean doScan = false;
  22. static BLERemoteCharacteristic* pRemoteCharacteristic = nullptr;
  23. static BLEAdvertisedDevice* myDevice = nullptr;
  24.  
  25. // Kept for future use if you add NOTIFY on the server.
  26. static void notifyCallback(
  27.         BLERemoteCharacteristic* pBLERemoteCharacteristic,
  28.         uint8_t* pData,
  29.         size_t length,
  30.         bool /*isNotify*/) {
  31.     Serial.print("Notify callback for characteristic ");
  32.     Serial.print(pBLERemoteCharacteristic->getUUID().toString().c_str());
  33.     Serial.print(" of data length ");
  34.     Serial.println(length);
  35.     Serial.print("data: ");
  36.     // Print length-safe (don't assume pData is NUL-terminated)
  37.     for (size_t i = 0; i < length; ++i) {
  38.         Serial.print((char)pData[i]);
  39.     }
  40.     Serial.println();
  41. }
  42.  
  43. class MyClientCallback : public BLEClientCallbacks {
  44.     void onConnect(BLEClient* /*pclient*/) override {
  45.     }
  46.     void onDisconnect(BLEClient* /*pclient*/) override {
  47.         connected = false;
  48.         Serial.println("onDisconnect");
  49.     }
  50. };
  51.  
  52. bool connectToServer() {
  53.     Serial.print("Forming a connection to ");
  54.     Serial.println(myDevice->getAddress().toString().c_str());
  55.  
  56.     BLEClient* pClient = BLEDevice::createClient();
  57.     Serial.println(" - Created client");
  58.     pClient->setClientCallbacks(new MyClientCallback());
  59.  
  60.     // Connect to the remote BLE Server.
  61.     pClient->connect(myDevice); // using BLEAdvertisedDevice preserves address type
  62.     Serial.println(" - Connected to server");
  63.  
  64.     // Obtain a reference to the service we are after in the remote BLE server.
  65.     BLERemoteService* pRemoteService = pClient->getService(serviceUUID);
  66.     if (pRemoteService == nullptr) {
  67.         Serial.print("Failed to find our service UUID: ");
  68.         Serial.println(serviceUUID.toString().c_str());
  69.         pClient->disconnect();
  70.         return false;
  71.     }
  72.     Serial.println(" - Found our service");
  73.  
  74.     // Obtain a reference to the characteristic in the service of the remote BLE server.
  75.     pRemoteCharacteristic = pRemoteService->getCharacteristic(charUUID);
  76.     if (pRemoteCharacteristic == nullptr) {
  77.         Serial.print("Failed to find our characteristic UUID: ");
  78.         Serial.println(charUUID.toString().c_str());
  79.         pClient->disconnect();
  80.         return false;
  81.     }
  82.     Serial.println(" - Found our characteristic");
  83.  
  84.     // Read the value of the characteristic.
  85.     if (pRemoteCharacteristic->canRead()) {
  86.         std::string value = pRemoteCharacteristic->readValue();
  87.         Serial.print("The characteristic value was: ");
  88.         Serial.println(value.c_str());
  89.     }
  90.  
  91.     // IMPORTANT:
  92.     // Do NOT register for notifications unless the server characteristic
  93.     // has PROPERTY_NOTIFY and exposes a CCCD (0x2902). Your server does not.
  94.     // if (pRemoteCharacteristic->canNotify()) {
  95.     //     auto* cccd = pRemoteCharacteristic->getDescriptor(BLEUUID((uint16_t)0x2902));
  96.     //     if (cccd) pRemoteCharacteristic->registerForNotify(notifyCallback);
  97.     // }
  98.  
  99.     connected = true;
  100.     return true; // FIX: correctly report success
  101. }
  102.  
  103. // Scan for BLE servers and find the first one that advertises the service we are looking for.
  104. class MyAdvertisedDeviceCallbacks : public BLEAdvertisedDeviceCallbacks {
  105.     void onResult(BLEAdvertisedDevice advertisedDevice) override {
  106.         Serial.print("BLE Advertised Device found: ");
  107.         Serial.println(advertisedDevice.toString().c_str());
  108.  
  109.         // We have found a device, let us now see if it contains the service we are looking for.
  110.         if (advertisedDevice.haveServiceUUID() && advertisedDevice.isAdvertisingService(serviceUUID)) {
  111.             BLEDevice::getScan()->stop();
  112.             myDevice = new BLEAdvertisedDevice(advertisedDevice);
  113.             doConnect = true;
  114.             doScan = true; // allow re-scan after disconnect (optional)
  115.         }
  116.     }
  117. };
  118.  
  119. void setup() {
  120.     Serial.begin(115200);
  121.     Serial.println("Starting Arduino BLE Client application...");
  122.     BLEDevice::init("");
  123.  
  124.     // Retrieve a Scanner and set the callback we want to use to be informed when we
  125.     // have detected a new device. Specify that we want active scanning and start the
  126.     // scan to run for 5 seconds.
  127.     BLEScan* pBLEScan = BLEDevice::getScan();
  128.     pBLEScan->setAdvertisedDeviceCallbacks(new MyAdvertisedDeviceCallbacks());
  129.     pBLEScan->setInterval(1349);
  130.     pBLEScan->setWindow(449);
  131.     pBLEScan->setActiveScan(true);
  132.     pBLEScan->start(5, false);
  133. }
  134.  
  135. // Arduino main loop
  136. void loop() {
  137.     // If the flag "doConnect" is true then we have scanned for and found the desired BLE Server.
  138.     if (doConnect) {
  139.         if (connectToServer()) {
  140.             Serial.println("We are now connected to the BLE Server.");
  141.         } else {
  142.             Serial.println("We have failed to connect to the server; there is nothing more we will do.");
  143.         }
  144.         doConnect = false;
  145.     }
  146.  
  147.     // If connected, write to the characteristic each second.
  148.     if (connected && pRemoteCharacteristic != nullptr) {
  149.         if (pRemoteCharacteristic->canWrite()) {
  150.             String newValue = "Time since boot: " + String(millis() / 1000);
  151.             Serial.println("Setting new characteristic value to \"" + newValue + "\"");
  152.             pRemoteCharacteristic->writeValue(newValue.c_str(), newValue.length());
  153.         }
  154.     } else if (doScan) {
  155.         // Restart scan after disconnect (example behavior).
  156.         BLEDevice::getScan()->start(0); // non-blocking continuous scan
  157.     }
  158.  
  159.     delay(1000);
  160. }
  161.  
Tags: ESP32 beacon
Advertisement
Add Comment
Please, Sign In to add comment