Advertisement
TolentinoCotesta

ESP32 BLE Scan

Oct 8th, 2021 (edited)
842
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 5.40 KB | None | 0 0
  1. #include <Arduino.h>
  2. #include <BLEDevice.h>
  3. #include <BLEUtils.h>
  4. #include <BLEScan.h>
  5. #include <BLEAdvertisedDevice.h>
  6. #include <set>
  7. #include "FS.h"
  8. #include <LittleFS.h>
  9. #define FORMAT_LITTLEFS_IF_FAILED true
  10.  
  11. // Durata minima dell'impulso di uscita
  12. #define MIN_PULSE_TIME 5000
  13.  
  14. // Pulsante per abilitare l'associazione del device
  15. const byte Button = 0;
  16.  
  17. // Uscita attiva quando il device è in prossimità
  18. const byte LED = 2;
  19.  
  20. // Per associare un dispositivo, questo deve essere molto vicino all'ESP32
  21. int linkRSSI = -85;
  22.  
  23. // Quando il dispositivo è abbastanza vicino, esegui azione
  24. int nearRSSI = -90;
  25.  
  26. // Variabile che diventa true quando il dispositivo è abbastanza vicino
  27. bool isNearDevice = false;
  28.  
  29. // Viene usato un set (lista di elementi univoci) per memorizzare i device autorizzati
  30. std::set<std::string> allowedDevices;
  31.  
  32. // Prototipi delle funzioni (dichiarate più sotto)
  33. bool saveAllowedDevice();
  34. bool loadAllowedDevice();
  35.  
  36.  
  37. BLEScan* pBLEScan;
  38. class MyAdvertisedDeviceCallbacks: public BLEAdvertisedDeviceCallbacks {
  39.     void onResult(BLEAdvertisedDevice advertisedDevice) {
  40.  
  41.       if (advertisedDevice.haveServiceUUID()) {
  42.  
  43.         // Salva in una variabile std:struing una chiave univoca ce identifica il device
  44.         std::string uuid = advertisedDevice.getServiceUUID().toString();
  45.         //std::string mac_adr = advertisedDevice.getAddress().toString();
  46.         //Serial.printf("MAC %S - UUID %s (%ddB)\n", mac_adr.c_str(), uuid.c_str(), advertisedDevice.getRSSI());
  47.  
  48.         // Controlla se il device è nella lista di quelli autorizzati
  49.         bool authorized = ( allowedDevices.count(uuid) > 0);
  50.  
  51.         // Aggiungo alla lista dei device ammessi se molto vicino e pulsante premuto
  52.         if (digitalRead(Button) == LOW) {
  53.           Serial.println("Pulsante di abbinamento premuto");
  54.  
  55.           if (advertisedDevice.getRSSI() >= linkRSSI ) {
  56.             // Se è già presente in lista -> ret.second == false
  57.             auto ret = allowedDevices.emplace(uuid);
  58.             if (ret.second) {
  59.               Serial.printf("Dispositivo aggiunto alla lista: %s (%ddB)\n", uuid.c_str(), advertisedDevice.getRSSI());
  60.               saveAllowedDevice();
  61.             }
  62.           }
  63.         }
  64.  
  65.         // Se il dispositivo è autorizzato ed è abbastanza vicino, isNearDevice -> true
  66.         if (advertisedDevice.getRSSI() > nearRSSI && authorized) {
  67.           isNearDevice = true;
  68.           Serial.printf("Dispositivo %s autorizzato (%ddB)\n", uuid.c_str(), advertisedDevice.getRSSI());
  69.         }
  70.       }
  71.     }
  72. };
  73.  
  74. // Task che esegue continuamente lo scan dei device BLE raggiungibili
  75. void bleScanTask(void * taskPar) {
  76.   Serial.print("Task \"BLE Scanning\" avviato sul core: ");
  77.   Serial.println(xPortGetCoreID());
  78.  
  79.   while (true) {
  80.     vTaskDelay(100 / portTICK_PERIOD_MS);
  81.     BLEScanResults foundDevices = pBLEScan->start(1, true); // duration( seconds), is_continue
  82.     pBLEScan->clearResults();                               // delete results from BLEScan buffer
  83.   }
  84.  
  85.   Serial.println("Chiusura del task \"BLE scanning\"");
  86.   vTaskDelete(NULL);
  87. }
  88.  
  89.  
  90. bool loadAllowedDevice() {
  91.   File file = LittleFS.open("/devices.txt");
  92.   if (!file ) {
  93.     Serial.println("Failed to open file devices.txt for reading");
  94.     return false;
  95.   }
  96.  
  97.   Serial.println("- read from file:");
  98.   while (file.available()) {
  99.     std::string line = file.readStringUntil('\n').c_str();
  100.     if(line.size()) {
  101.       allowedDevices.emplace(line);
  102.       Serial.println(line.c_str());
  103.     }
  104.   }
  105.   file.close();
  106.   return true;
  107. }
  108.  
  109. bool saveAllowedDevice() {
  110.   File file = LittleFS.open("/devices.txt", FILE_WRITE);
  111.   if (!file ) {
  112.     Serial.println("Failed to open file devices.txt for writing");
  113.     return false;
  114.   }
  115.   for (std::set<std::string>::iterator it=allowedDevices.begin(); it!=allowedDevices.end(); ++it) {
  116.     std::string device = *it;
  117.     file.println(device.c_str());
  118.   }
  119.   file.close();
  120.   Serial.println("Saved device list to file devices.txt");
  121.   return true;
  122. }
  123.  
  124.  
  125. void setup() {
  126.   Serial.begin(115200);
  127.   Serial.println();
  128.   pinMode(Button, INPUT);
  129.   pinMode(LED, OUTPUT);
  130.   digitalWrite(LED , LOW);
  131.  
  132.   if (!LittleFS.begin(FORMAT_LITTLEFS_IF_FAILED)) {
  133.     Serial.println("LittleFS Mount Failed");
  134.     ESP.restart();
  135.   }
  136.   //loadAllowedDevice();
  137.  
  138.   Serial.println("Scanning...");
  139.   BLEDevice::init("");
  140.   pBLEScan = BLEDevice::getScan();  // Create new scan object
  141.   pBLEScan->setAdvertisedDeviceCallbacks(new MyAdvertisedDeviceCallbacks());
  142.   pBLEScan->setActiveScan(true);    // Active scan uses more power, but get results faster
  143.   pBLEScan->setInterval(100);
  144.   pBLEScan->setWindow(99);          // Less or equal setInterval value
  145.  
  146.   // Siccome l'esecuzione dello scanning è bloccante, facciamola in un task dedicato
  147.   xTaskCreate(
  148.     bleScanTask,     // Function to be called
  149.     "BLE Scan task", // Name of the task (for debugging)
  150.     2048,            // Stack size (bytes)
  151.     NULL,            // Parameter to pass
  152.     1,               // Task priority
  153.     NULL             // Task handle
  154.   );
  155. }
  156.  
  157. void loop() {
  158.  
  159.   // Un dispositivo è passato abbastanza vicino, attivo un segnale
  160.   static uint32_t pulseTime;
  161.   if (isNearDevice) {
  162.     pulseTime = millis();
  163.     digitalWrite(LED , HIGH);
  164.     isNearDevice = false;
  165.   }
  166.  
  167.   // Il segnale è durato abbastanza -> reset
  168.   if (millis() - pulseTime > MIN_PULSE_TIME) {
  169.     digitalWrite(LED , LOW);
  170.   }
  171.  
  172. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement