View difference between Paste ID: VDn5TJb8 and n0dFVYnc
SHOW: | | - or go back to the newest paste.
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-
      if (advertisedDevice.haveServiceUUID()) {
34+
bool loadAllowedDevice();
35
36
37-
        std::string uuid = advertisedDevice.getServiceUUID().toString();
37+
38
class MyAdvertisedDeviceCallbacks: public BLEAdvertisedDeviceCallbacks {
39
    void onResult(BLEAdvertisedDevice advertisedDevice) {
40
41
      std::string uuid = advertisedDevice.getAddress().toString();
42
      
43
      if (uuid.size()) {
44
45
        // Salva in una variabile std:struing una chiave univoca ce identifica il device
46
        //std::string uuid = advertisedDevice.getServiceUUID().toString();
47
        //std::string mac_adr = advertisedDevice.getAddress().toString();
48
        //Serial.printf("MAC %S - UUID %s (%ddB)\n", mac_adr.c_str(), uuid.c_str(), advertisedDevice.getRSSI());
49
        
50
        // Controlla se il device è nella lista di quelli autorizzati
51
        bool authorized = ( allowedDevices.count(uuid) > 0);
52
53
        // Aggiungo alla lista dei device ammessi se molto vicino e pulsante premuto
54
        if (digitalRead(Button) == LOW) {
55
          Serial.println("Pulsante di abbinamento premuto");
56
57
          if (advertisedDevice.getRSSI() >= linkRSSI ) {
58
            // Se è già presente in lista -> ret.second == false
59
            auto ret = allowedDevices.emplace(uuid);
60
            if (ret.second) {
61
              Serial.printf("Dispositivo aggiunto alla lista: %s (%ddB)\n", uuid.c_str(), advertisedDevice.getRSSI());
62
              saveAllowedDevice();
63
            }
64
          }
65
        }
66
67
        // Se il dispositivo è autorizzato ed è abbastanza vicino, isNearDevice -> true
68
        if (advertisedDevice.getRSSI() > nearRSSI && authorized) {
69
          isNearDevice = true;
70
          Serial.printf("Dispositivo %s autorizzato (%ddB)\n", uuid.c_str(), advertisedDevice.getRSSI());
71
        }
72
      }
73
    }
74
};
75
76
// Task che esegue continuamente lo scan dei device BLE raggiungibili
77
void bleScanTask(void * taskPar) {
78
  Serial.print("Task \"BLE Scanning\" avviato sul core: ");
79
  Serial.println(xPortGetCoreID());
80
81
  while (true) {
82
    vTaskDelay(100 / portTICK_PERIOD_MS);
83
    BLEScanResults foundDevices = pBLEScan->start(1, true); // duration( seconds), is_continue
84
    pBLEScan->clearResults();                               // delete results from BLEScan buffer
85
  }
86
87
  Serial.println("Chiusura del task \"BLE scanning\"");
88
  vTaskDelete(NULL);
89
}
90
91
92
bool loadAllowedDevice() {
93
  File file = LittleFS.open("/devices.txt");
94
  if (!file ) {
95
    Serial.println("Failed to open file devices.txt for reading");
96
    return false;
97
  }
98
99
  Serial.println("- read from file:");
100
  while (file.available()) {
101
    std::string line = file.readStringUntil('\n').c_str();
102
    if(line.size()) {
103
      allowedDevices.emplace(line);
104
      Serial.println(line.c_str());
105
    }
106
  }
107
  file.close();
108
  return true;
109
}
110
111
bool saveAllowedDevice() {
112
  File file = LittleFS.open("/devices.txt", FILE_WRITE);
113
  if (!file ) {
114
    Serial.println("Failed to open file devices.txt for writing");
115
    return false;
116
  }
117
  for (std::set<std::string>::iterator it=allowedDevices.begin(); it!=allowedDevices.end(); ++it) {
118
    std::string device = *it;
119
    file.println(device.c_str());
120
  }
121
  file.close();
122
  Serial.println("Saved device list to file devices.txt");
123
  return true;
124
}
125
126
127
void setup() {
128
  Serial.begin(115200);
129
  Serial.println();
130
  pinMode(Button, INPUT);
131
  pinMode(LED, OUTPUT);
132
  digitalWrite(LED , LOW);
133
134
  if (!LittleFS.begin(FORMAT_LITTLEFS_IF_FAILED)) {
135
    Serial.println("LittleFS Mount Failed");
136
    ESP.restart();
137
  }
138
  //loadAllowedDevice();
139
140
  Serial.println("Scanning...");
141
  BLEDevice::init("");
142
  pBLEScan = BLEDevice::getScan();  // Create new scan object
143
  pBLEScan->setAdvertisedDeviceCallbacks(new MyAdvertisedDeviceCallbacks());
144
  pBLEScan->setActiveScan(true);    // Active scan uses more power, but get results faster
145
  pBLEScan->setInterval(100);
146
  pBLEScan->setWindow(99);          // Less or equal setInterval value
147
148
  // Siccome l'esecuzione dello scanning è bloccante, facciamola in un task dedicato
149
  xTaskCreate(
150
    bleScanTask,     // Function to be called
151
    "BLE Scan task", // Name of the task (for debugging)
152
    2048,            // Stack size (bytes)
153
    NULL,            // Parameter to pass
154
    1,               // Task priority
155
    NULL             // Task handle
156
  );
157
}
158
159
void loop() {
160
161
  // Un dispositivo è passato abbastanza vicino, attivo un segnale
162
  static uint32_t pulseTime;
163
  if (isNearDevice) {
164
    pulseTime = millis();
165
    digitalWrite(LED , HIGH);
166
    isNearDevice = false;
167
  }
168
169
  // Il segnale è durato abbastanza -> reset
170
  if (millis() - pulseTime > MIN_PULSE_TIME) {
171
    digitalWrite(LED , LOW);
172
  }
173
174
}