Skip to content

Instantly share code, notes, and snippets.

@cotestatnt
Created September 24, 2021 16:01
Show Gist options
  • Save cotestatnt/f413e1ec2f3cfb6b1913b210ccbdbbd9 to your computer and use it in GitHub Desktop.
Save cotestatnt/f413e1ec2f3cfb6b1913b210ccbdbbd9 to your computer and use it in GitHub Desktop.
#include <Arduino.h>
#include <BLEDevice.h>
#include <BLEUtils.h>
#include <BLEScan.h>
#include <BLEAdvertisedDevice.h>
// Pulsante per abilitare l'associazione del device
const byte Button = 4;
// Per associare un dispositivo, questo deve essere molto vicino all'ESP32
int linkRSSI = -69;
// Quando il dispositivo è abbastanza vicino, esegui azione
int nearRSSI = -90;
// Variabile che diventa true quando il dispositivo è abbastanza vicino
bool isNearDevice = false;
// Questa stringa andrà a memorizzare l'uuid dei device autorizzati
// E' necessario usare std:string perché le funzioni restituiscono questo tipo di dati
std::string allowedDevice;
// Durata minima dell'impulso di uscita
#define MIN_PULSE_TIME 2000
BLEScan* pBLEScan;
class MyAdvertisedDeviceCallbacks: public BLEAdvertisedDeviceCallbacks {
void onResult(BLEAdvertisedDevice advertisedDevice) {
if (advertisedDevice.haveServiceUUID()){
std::string uuid = advertisedDevice.getServiceUUID().toString();
std::string mac_adr = advertisedDevice.getAddress().toString();
//Serial.printf("MAC %S - UUID %s\n", mac_adr.c_str(), uuid.c_str());
// Cerca l'uuid nella std::string allowedDevice
std::size_t found = allowedDevice.find(uuid);
bool authorized = (found != std::string::npos);
// Aggiungo alla lista dei device ammessi se molto vicino e pulsante premuto
if(advertisedDevice.getRSSI() >= linkRSSI && digitalRead(Button) == LOW){
// Se è già presente in lista -> authorized == true
if( !authorized) {
Serial.printf("Add to list allowed device: %s (%ddB)\n", uuid.c_str(), advertisedDevice.getRSSI());
allowedDevice += uuid;
allowedDevice += "\n";
}
}
// Se il dispositivo è autorizzato ed è abbastanza vicino, isNearDevice -> true
if(advertisedDevice.getRSSI() > nearRSSI && authorized){
isNearDevice = true;
Serial.printf("Near authorized device found: %s\n", uuid.c_str());
}
}
}
};
// Task che esegue continuamente lo scan dei device BLE raggiungibili
void bleScanTask(void * taskPar){
Serial.print("Task is running on: ");
Serial.println(xPortGetCoreID());
while(true) {
vTaskDelay(100 / portTICK_PERIOD_MS);
BLEScanResults foundDevices = pBLEScan->start(1, true); // duration( seconds), is_continue
pBLEScan->clearResults(); // delete results from BLEScan buffer
}
Serial.println("Terminating BLE scanning task");
vTaskDelete(NULL);
}
void setup() {
pinMode(Button, INPUT_PULLUP);
pinMode(LED_BUILTIN, OUTPUT);
digitalWrite(LED_BUILTIN, LOW);
Serial.begin(115200);
Serial.println("Scanning...");
BLEDevice::init("");
pBLEScan = BLEDevice::getScan(); // Create new scan object
pBLEScan->setAdvertisedDeviceCallbacks(new MyAdvertisedDeviceCallbacks());
pBLEScan->setActiveScan(true); // Active scan uses more power, but get results faster
pBLEScan->setInterval(100);
pBLEScan->setWindow(99); // Less or equal setInterval value
// Siccome l'esecuzione dello scanning è bloccante, facciamola in un task dedicato
xTaskCreate(
bleScanTask, // Function to be called
"BLE Scan task", // Name of the task (for debugging)
2048, // Stack size (bytes)
NULL, // Parameter to pass
1, // Task priority
NULL // Task handle
);
}
void loop() {
// Un dispositivo è passato abbastanza vicino, attivo un segnale
static uint32_t pulseTime;
if(isNearDevice) {
pulseTime = millis();
digitalWrite(BUILTIN_LED, HIGH);
isNearDevice = false;
}
// Il segnale è durato abbastanza -> reset
if(millis() - pulseTime > MIN_PULSE_TIME) {
digitalWrite(BUILTIN_LED, LOW);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment