forked from espressif/arduino-esp32
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathBeacon_Scanner.ino
120 lines (107 loc) · 4.49 KB
/
Beacon_Scanner.ino
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
/*
Based on Neil Kolban example for IDF: https://github.com/nkolban/esp32-snippets/blob/master/cpp_utils/tests/BLE%20Tests/SampleScan.cpp
Ported to Arduino ESP32 by Evandro Copercini
Changed to a beacon scanner to report iBeacon, EddystoneURL and EddystoneTLM beacons by beegee-tokyo
Upgraded Eddystone part by Tomas Pilny on Feb 20, 2023
*/
#include <Arduino.h>
#include <BLEDevice.h>
#include <BLEUtils.h>
#include <BLEScan.h>
#include <BLEAdvertisedDevice.h>
#include <BLEEddystoneURL.h>
#include <BLEEddystoneTLM.h>
#include <BLEBeacon.h>
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("");
}
if (advertisedDevice.haveManufacturerData() == true)
{
String strManufacturerData = advertisedDevice.getManufacturerData();
uint8_t cManufacturerData[100];
memcpy(cManufacturerData, strManufacturerData.c_str(), strManufacturerData.length());
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());
}
else
{
Serial.println("Found another manufacturers beacon!");
Serial.printf("strManufacturerData: %d ", strManufacturerData.length());
for (int i = 0; i < strManufacturerData.length(); i++)
{
Serial.printf("[%X]", cManufacturerData[i]);
}
Serial.printf("\n");
}
}
if (advertisedDevice.getFrameType() == BLE_EDDYSTONE_URL_FRAME)
{
Serial.println("Found an EddystoneURL beacon!");
BLEEddystoneURL EddystoneURL = BLEEddystoneURL(&advertisedDevice);
Serial.printf("URL bytes: 0x");
String url = EddystoneURL.getURL();
for(auto byte : url){
Serial.printf("%02X", byte);
}
Serial.printf("\n");
Serial.printf("Decoded URL: %s\n", EddystoneURL.getDecodedURL().c_str());
Serial.printf("EddystoneURL.getDecodedURL(): %s\n", EddystoneURL.getDecodedURL().c_str());
Serial.printf("TX power %d (Raw 0x%02X)\n", EddystoneURL.getPower(), EddystoneURL.getPower());
Serial.println("\n");
}
if (advertisedDevice.getFrameType() == BLE_EDDYSTONE_TLM_FRAME)
{
Serial.println("Found an EddystoneTLM beacon!");
BLEEddystoneTLM EddystoneTLM(&advertisedDevice);
Serial.printf("Reported battery voltage: %dmV\n", EddystoneTLM.getVolt());
Serial.printf("Reported temperature: %.2f°C (raw data=0x%04X)\n", EddystoneTLM.getTemp(), EddystoneTLM.getRawTemp());
Serial.printf("Reported advertise count: %lu\n", EddystoneTLM.getCount());
Serial.printf("Reported time since last reboot: %lus\n", EddystoneTLM.getTime());
Serial.println("\n");
Serial.print(EddystoneTLM.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);
}