Page 1 of 1

BLE Proximity detection for a gate opener

Posted: Sun Apr 10, 2022 11:42 pm
by GeilerAffe
Hi all,

Apologies in advance for being abit of a n00b here. My coding experience is from over 30 years ago, so I do understand a little but I have forgotten most of it.

I managed to play around with some code I found elsewhere, it works but with a few hitches. Basically I need this to trigger an output once someone with the BLE device enters the area. I figured out how to deal with the ever changing MAC on the Beacon smart phone apps. I basically changed BLEAddress to BLEServiceUUID This way I can create my own static ID in the Beacon App.

The problem I have is I need the output to trigger once, when the device enters the area. The output should last for 1 second and then not activate again, until the device disappears for a set period of time. Lets say 1 minute. This way the user can enter the gate without it stopping mid opening, because of a secondary trigger.

Alternatively I can see where it would be handy for the output to remain high for the duration the device is in the area, with a delay for the ESP to decide the device is no longer there. Maybe 30 seconds, or something like that. This will account for momentary drops due to being at the edge of the range.

I did notice the output will latch, for the entire period the BLE device is in range, so long as there is no other BLE Device in the area. Also, I noticed the output will remain high if I turn the BLE device off, prior to the ESP detecting it drop below the range. I assume the same would hold true if the BLE Device dropped out completely prior to the ESP seeing the signal strength drop. This could be problematic

Hopefully the above makes sense. I have pasted my code below. Hopefully I did that right :)

Cheers

Heinz
from Vancouver Canada


#include <BLEDevice.h>
#include <BLEUtils.h>
#include <BLEScan.h>
#include <BLEAdvertisedDevice.h>
String knownBLEAddresses[] = {"00006666-0000-1000-8000-00805f9b34fb"};
int RSSI_THRESHOLD = -95;
const int Pin4 = 4;
const int Pin2 = 2;
bool device_found;
int scanTime = 3; //In seconds
BLEScan* pBLEScan;
class MyAdvertisedDeviceCallbacks: public BLEAdvertisedDeviceCallbacks {
void onResult(BLEAdvertisedDevice advertisedDevice) {
for (int i = 0; i < (sizeof(knownBLEAddresses) / sizeof(knownBLEAddresses[0])); i++)
{
//Uncomment to Enable Debug Information
Serial.println("*************Start**************");
Serial.printf("Advertised Device: %s \n", advertisedDevice.toString().c_str());
//Serial.println(sizeof(knownBLEAddresses));
//Serial.println(sizeof(knownBLEAddresses[0]));
//Serial.println(sizeof(knownBLEAddresses)/sizeof(knownBLEAddresses[0]));
Serial.println(advertisedDevice.getAddress().toString().c_str());
Serial.print("mfg data: ");
Serial.println(advertisedDevice.getManufacturerData().c_str());
Serial.print("Name: ");
Serial.println(advertisedDevice.getName().c_str());
Serial.print("UUID: ");
Serial.println(advertisedDevice.getServiceUUID().toString().c_str());
Serial.println(advertisedDevice.getServiceDataUUID().toString().c_str());
Serial.println(knownBLEAddresses.c_str());
Serial.println("*************End**************");
if (strcmp(advertisedDevice.getServiceUUID().toString().c_str(), knownBLEAddresses.c_str()) == 0)
{
device_found = true;
// break;
}
else
device_found = false;
}
Serial.printf("Advertised Device: %s \n", advertisedDevice.toString().c_str());
}
};
void setup() {
Serial.begin(9600); //Enable UART on ESP32
pinMode(Pin2, OUTPUT); //make BUILTIN_LED pin as output
pinMode(Pin4, OUTPUT);
BLEDevice::init("");
pBLEScan = BLEDevice::getScan(); //create new scan
// pBLEScan->setAdvertisedDeviceCallbacks(new MyAdvertisedDeviceCallbacks()); //Init Callback Function
pBLEScan->setAdvertisedDeviceCallbacks(new MyAdvertisedDeviceCallbacks(), false); // <-- true means you want duplicates, unless you dont
pBLEScan->setActiveScan(false); //active scan uses more power, but get results faster
pBLEScan->setInterval(60); // set Scan interval
pBLEScan->setWindow(2); // less or equal setInterval value
}
void loop() {
// put your main code here, to run repeatedly:
BLEScanResults foundDevices = pBLEScan->start(scanTime, false);
for (int i = 0; i < foundDevices.getCount(); i++)
{
BLEAdvertisedDevice device = foundDevices.getDevice(i);
int rssi = device.getRSSI();
Serial.print("RSSI: ");
Serial.println(rssi);
if (rssi > RSSI_THRESHOLD && device_found == true)
digitalWrite(Pin2, HIGH);
else
digitalWrite(Pin2, LOW);

}
pBLEScan->clearResults(); // delete results fromBLEScan buffer to release memory
}