What is Bluetooth Low Energy (BLE)?
BLE stands for Bluetooth Low Energy, and it came to our everyday lives in 2011, because at that time of the year every major manufacturer started embedding BLE technology on their devices. BLE is a low power wireless communication technology that was developed for battery power applications which can be used to communicate among devices over a short distance. Some of the devices you use every day have Bluetooth built into it like your smartphone, your smartwatch, wireless earbuds, wireless speakers, smart home devices, and more embedded Bluetooth to communicate or to get location data.
How the BLE Proximity Sensor Works?
BLE servers regularly broadcast advertisement signals so the clients can search for it and connect to it. This advertisement signal contains a unique BLE MAC (Media Access Control) address, which is very similar to a MAC address used in Wi-Fi because our ESP32 module has Bluetooth built-in, we could easily detect this broadcasted signal and compare it to a lookup table, to detect the presence of a known device. Once the device is verified, we can turn on a light locally or we can use Adafruit IO to trigger a notification on our android application.
Materials Required
- ESP32 Board
- Mobile Phone
- Any BLE Enabled device, be it a smartwatch or fitband or bluetooth speaker. Here we take a fitband to demonstrate.
Code
#include <BLEDevice.h>
#include <BLEUtils.h>
#include <BLEScan.h>
#include <BLEAdvertisedDevice.h>
String knownBLEAddresses[] = {"6E:bc:55:18:cf:7b", "53:3c:cb:56:36:02", "40:99:4b:75:7d:2f", "5c:5b:68:6f:34:96"};
int RSSI_THRESHOLD = -55;
bool device_found;
int scanTime = 5; //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.println(sizeof(knownBLEAddresses));
//Serial.println(sizeof(knownBLEAddresses[0]));
//Serial.println(sizeof(knownBLEAddresses)/sizeof(knownBLEAddresses[0]));
//Serial.println(advertisedDevice.getAddress().toString().c_str());
//Serial.println(knownBLEAddresses[i].c_str());
//Serial.println("*************End**************");
if (strcmp(advertisedDevice.getAddress().toString().c_str(), knownBLEAddresses[i].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(115200); //Enable UART on ESP32
Serial.println("Scanning..."); // Print Scanning
pinMode(LED_BUILTIN, OUTPUT); //make BUILTIN_LED pin as output
BLEDevice::init("");
pBLEScan = BLEDevice::getScan(); //create new scan
pBLEScan->setAdvertisedDeviceCallbacks(new MyAdvertisedDeviceCallbacks()); //Init Callback Function
pBLEScan->setActiveScan(true); //active scan uses more power, but get results faster
pBLEScan->setInterval(100); // set Scan interval
pBLEScan->setWindow(99); // 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(LED_BUILTIN, HIGH);
else
digitalWrite(LED_BUILTIN, LOW);
}
pBLEScan->clearResults(); // delete results fromBLEScan buffer to release memory
}
Follow up Projects
Using BLE try setting up communication network between the Phone and ESP32.
References
You can find more details of the project and the description of the components here