Reputation: 1
How can I get a relay to turn on when an iBeacon approaches an esp32 via bluetooth? via arduino I have to assign a pin for the relay so that it turns on every time the iBeacon comes close all this via bluetooth this code detects the arduino The following code helps me to establish connection of the esp32 with the iBeacon but now I don't know how to continue to be able to make the relay activate every time the Ibeacon approaches and when I know when it moves away the relay turns off all this through Bluetooth and by arduino Ide note: I already have the esp32 libraries #include <Arduino.h>
#include <BLEDevice.h>
#include <BLEUtils.h>
#include <BLEScan.h>
#include <BLEAdvertisedDevice.h>
#include <BLEEddystoneURL.h>
#include <BLEEddystoneTLM.h>
#include <BLEBeacon.h>
#define ENDIAN_CHANGE_U16(x) ((((x)&0xFF00) >> 8) + (((x)&0xFF) << 8))
int scanTime = 5; //In seconds
BLEScan *pBLEScan;
class MyAdvertisedDeviceCallbacks : public BLEAdvertisedDeviceCallbacks
{
void onResult(BLEAdvertisedDevice advertisedDevice)
{
if (advertisedDevice.haveName())
{
Serial.print("Device name: ");
Serial.println(advertisedDevice.getName().c_str());
Serial.println("");
}
if (advertisedDevice.haveServiceUUID())
{
BLEUUID devUUID = advertisedDevice.getServiceUUID();
Serial.print("Found ServiceUUID: ");
Serial.println(devUUID.toString().c_str());
Serial.println("");
}
else
{
if (advertisedDevice.haveManufacturerData() == true)
{
std::string strManufacturerData = advertisedDevice.getManufacturerData();
uint8_t cManufacturerData[100];
strManufacturerData.copy((char *)cManufacturerData, strManufacturerData.length(), 0);
if (strManufacturerData.length() == 25 && cManufacturerData[0] == 0x4C && cManufacturerData[1] == 0x00)
{
Serial.println("Found an iBeacon!");
BLEBeacon oBeacon = BLEBeacon();
oBeacon.setData(strManufacturerData);
Serial.printf("iBeacon Frame\n");
Serial.printf("ID: %04X Major: %d Minor: %d UUID: %s Power: %d\n", oBeacon.getManufacturerId(), ENDIAN_CHANGE_U16(oBeacon.getMajor()), ENDIAN_CHANGE_U16(oBeacon.getMinor()), oBeacon.getProximityUUID().toString().c_str(), oBeacon.getSignalPower());
}
}
}
uint8_t *payLoad = advertisedDevice.getPayload();
BLEUUID checkUrlUUID = (uint16_t)0xfeaa;
if (advertisedDevice.getServiceUUID().equals(checkUrlUUID))
{
if (payLoad[11] == 0x10)
{
Serial.println("Found an EddystoneURL beacon!");
BLEEddystoneURL foundEddyURL = BLEEddystoneURL();
std::string eddyContent((char *)&payLoad[11]); // incomplete EddystoneURL struct!
foundEddyURL.setData(eddyContent);
std::string bareURL = foundEddyURL.getURL();
if (bareURL[0] == 0x00)
{
size_t payLoadLen = advertisedDevice.getPayloadLength();
Serial.println("DATA-->");
for (int idx = 0; idx < payLoadLen; idx++)
{
Serial.printf("0x%08X ", payLoad[idx]);
}
Serial.println("\nInvalid Data");
return;
}
Serial.printf("Found URL: %s\n", foundEddyURL.getURL().c_str());
Serial.printf("Decoded URL: %s\n", foundEddyURL.getDecodedURL().c_str());
Serial.printf("TX power %d\n", foundEddyURL.getPower());
Serial.println("\n");
}
else if (payLoad[11] == 0x20)
{
Serial.println("Found an EddystoneTLM beacon!");
BLEEddystoneTLM foundEddyURL = BLEEddystoneTLM();
std::string eddyContent((char *)&payLoad[11]); // incomplete EddystoneURL struct!
eddyContent = "01234567890123";
for (int idx = 0; idx < 14; idx++)
{
eddyContent[idx] = payLoad[idx + 11];
}
foundEddyURL.setData(eddyContent);
Serial.printf("Reported battery voltage: %dmV\n", foundEddyURL.getVolt());
Serial.printf("Reported temperature from TLM class: %.2fC\n", (double)foundEddyURL.getTemp());
int temp = (int)payLoad[16] + (int)(payLoad[15] << 8);
float calcTemp = temp / 256.0f;
Serial.printf("Reported temperature from data: %.2fC\n", calcTemp);
Serial.printf("Reported advertise count: %d\n", foundEddyURL.getCount());
Serial.printf("Reported time since last reboot: %ds\n", foundEddyURL.getTime());
Serial.println("\n");
Serial.print(foundEddyURL.toString().c_str());
Serial.println("\n");
}
}
}
};
void setup()
{
Serial.begin(115200);
Serial.println("Scanning...");
BLEDevice::init("");
pBLEScan = BLEDevice::getScan(); //create new scan
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
}
void loop()
{
// put your main code here, to run repeatedly:
BLEScanResults foundDevices = pBLEScan->start(scanTime, false);
Serial.print("Devices found: ");
Serial.println(foundDevices.getCount());
Serial.println("Scan done!");
pBLEScan->clearResults(); // delete results fromBLEScan buffer to release memory
delay(2000);
}
Upvotes: 0
Views: 860
Reputation: 1
You can do it like this:
#include <BLEUtils.h>
#include <BLEScan.h>
#include <BLEAdvertisedDevice.h>
#include <BLEAddress.h>
#include <Ticker.h>
String Adresse = "00:15:83:40:7c:bc"; // Bluetooth MAC to watch for
const int RelaisPin = 22; // pin of relay to swiwtch
int Verzoegerung = 15; // delay after which the relay will be switched when BLE device is out of range
int VerzoegerungZaeler = 0;
Ticker Tic;
static BLEAddress *pServerAddress;
BLEScan* pBLEScan ;
int scanTime = 30; //In seconds
class MyAdvertisedDeviceCallbacks: public BLEAdvertisedDeviceCallbacks
{
void onResult(BLEAdvertisedDevice advertisedDevice) // when BLE device is found
{
Serial.print(advertisedDevice.getAddress().toString().c_str()); // show MAC of BLE
if (advertisedDevice.getAddress().equals(*pServerAddress)) // compare MAC
{
Serial.print(" Ueberwachte Adresse"); // monitored MAC found
digitalWrite (RelaisPin, 0); // switch relay
VerzoegerungZaeler = 0; // reset delay
advertisedDevice.getScan()->stop(); // stop scanning
} // Found our server
Serial.println("");
}
};
void SekundenTic() // once per second
{
VerzoegerungZaeler++; // time counter
if (VerzoegerungZaeler >= Verzoegerung) digitalWrite (RelaisPin, 1); // switch off after delay
}
void setup()
{
pinMode (RelaisPin, OUTPUT);
digitalWrite (RelaisPin, 1);
Serial.begin(115200);
Serial.println("");
Serial.println("Starte BLE Scanner");
pServerAddress = new BLEAddress(Adresse.c_str());
BLEDevice::init("");
pBLEScan = BLEDevice::getScan(); // create new scan
pBLEScan->setAdvertisedDeviceCallbacks(new MyAdvertisedDeviceCallbacks());
pBLEScan->setActiveScan(true); // active scan uses more power, but get results faster
Tic.attach( 1,SekundenTic);
}
void loop()
{
pBLEScan->start(scanTime);
delay(2000); // scan every 2s for devices
}
Upvotes: 0