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 | } |