Skip to content

Commit ae0909b

Browse files
committed
Update examples
1 parent 740a1e7 commit ae0909b

File tree

26 files changed

+857
-2170
lines changed

26 files changed

+857
-2170
lines changed

examples/BLE_Beacon_Scanner/BLE_Beacon_Scanner.ino

Lines changed: 73 additions & 129 deletions
Original file line numberDiff line numberDiff line change
@@ -3,151 +3,95 @@
33
Ported to Arduino ESP32 by Evandro Copercini
44
*/
55

6-
/** NimBLE differences highlighted in comment blocks **/
7-
8-
/*******original********
9-
#include <BLEDevice.h>
10-
#include <BLEUtils.h>
11-
#include <BLEScan.h>
12-
#include <BLEAdvertisedDevice.h>
13-
#include "BLEEddystoneURL.h"
14-
#include "BLEEddystoneTLM.h"
15-
#include "BLEBeacon.h"
16-
***********************/
17-
186
#include <Arduino.h>
19-
207
#include <NimBLEDevice.h>
218
#include <NimBLEAdvertisedDevice.h>
22-
#include "NimBLEEddystoneURL.h"
239
#include "NimBLEEddystoneTLM.h"
2410
#include "NimBLEBeacon.h"
2511

26-
#define ENDIAN_CHANGE_U16(x) ((((x)&0xFF00) >> 8) + (((x)&0xFF) << 8))
27-
28-
int scanTime = 5 * 1000; //In milliseconds
29-
BLEScan *pBLEScan;
12+
#define ENDIAN_CHANGE_U16(x) ((((x) & 0xFF00) >> 8) + (((x) & 0xFF) << 8))
3013

31-
class MyAdvertisedDeviceCallbacks : public BLEAdvertisedDeviceCallbacks
32-
{
33-
/*** Only a reference to the advertised device is passed now
34-
void onResult(BLEAdvertisedDevice advertisedDevice) { **/
35-
void onResult(BLEAdvertisedDevice *advertisedDevice)
36-
{
37-
if (advertisedDevice->haveName())
38-
{
39-
Serial.print("Device name: ");
40-
Serial.println(advertisedDevice->getName().c_str());
41-
Serial.println("");
42-
}
14+
int scanTime = 5 * 1000; // In milliseconds
15+
NimBLEScan* pBLEScan;
4316

44-
if (advertisedDevice->haveServiceUUID())
45-
{
46-
BLEUUID devUUID = advertisedDevice->getServiceUUID();
47-
Serial.print("Found ServiceUUID: ");
48-
Serial.println(devUUID.toString().c_str());
49-
Serial.println("");
50-
}
51-
else
52-
{
53-
if (advertisedDevice->haveManufacturerData() == true)
54-
{
55-
std::string strManufacturerData = advertisedDevice->getManufacturerData();
56-
57-
uint8_t cManufacturerData[100];
58-
strManufacturerData.copy((char *)cManufacturerData, strManufacturerData.length(), 0);
59-
60-
if (strManufacturerData.length() == 25 && cManufacturerData[0] == 0x4C && cManufacturerData[1] == 0x00)
61-
{
62-
Serial.println("Found an iBeacon!");
63-
BLEBeacon oBeacon = BLEBeacon();
64-
oBeacon.setData(strManufacturerData);
65-
Serial.printf("iBeacon Frame\n");
66-
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());
67-
}
68-
else
69-
{
70-
Serial.println("Found another manufacturers beacon!");
71-
Serial.printf("strManufacturerData: %d ", strManufacturerData.length());
72-
for (int i = 0; i < strManufacturerData.length(); i++)
73-
{
74-
Serial.printf("[%X]", cManufacturerData[i]);
75-
}
76-
Serial.printf("\n");
77-
}
17+
class ScanCallbacks : public NimBLEScanCallbacks {
18+
void onResult(const NimBLEAdvertisedDevice* advertisedDevice) override {
19+
if (advertisedDevice->haveName()) {
20+
Serial.print("Device name: ");
21+
Serial.println(advertisedDevice->getName().c_str());
22+
Serial.println("");
7823
}
79-
return;
80-
}
8124

82-
BLEUUID eddyUUID = (uint16_t)0xfeaa;
83-
84-
if (advertisedDevice->getServiceUUID().equals(eddyUUID))
85-
{
86-
std::string serviceData = advertisedDevice->getServiceData(eddyUUID);
87-
if (serviceData[0] == 0x10)
88-
{
89-
Serial.println("Found an EddystoneURL beacon!");
90-
BLEEddystoneURL foundEddyURL = BLEEddystoneURL();
91-
92-
foundEddyURL.setData(serviceData);
93-
std::string bareURL = foundEddyURL.getURL();
94-
if (bareURL[0] == 0x00)
95-
{
96-
Serial.println("DATA-->");
97-
for (int idx = 0; idx < serviceData.length(); idx++)
98-
{
99-
Serial.printf("0x%08X ", serviceData[idx]);
25+
if (advertisedDevice->haveServiceUUID()) {
26+
NimBLEUUID devUUID = advertisedDevice->getServiceUUID();
27+
Serial.print("Found ServiceUUID: ");
28+
Serial.println(devUUID.toString().c_str());
29+
Serial.println("");
30+
} else if (advertisedDevice->haveManufacturerData() == true) {
31+
std::string strManufacturerData = advertisedDevice->getManufacturerData();
32+
if (strManufacturerData.length() == 25 && strManufacturerData[0] == 0x4C && strManufacturerData[1] == 0x00) {
33+
Serial.println("Found an iBeacon!");
34+
NimBLEBeacon oBeacon = NimBLEBeacon();
35+
oBeacon.setData(reinterpret_cast<const uint8_t*>(strManufacturerData.data()), strManufacturerData.length());
36+
Serial.printf("iBeacon Frame\n");
37+
Serial.printf("ID: %04X Major: %d Minor: %d UUID: %s Power: %d\n",
38+
oBeacon.getManufacturerId(),
39+
ENDIAN_CHANGE_U16(oBeacon.getMajor()),
40+
ENDIAN_CHANGE_U16(oBeacon.getMinor()),
41+
oBeacon.getProximityUUID().toString().c_str(),
42+
oBeacon.getSignalPower());
43+
} else {
44+
Serial.println("Found another manufacturers beacon!");
45+
Serial.printf("strManufacturerData: %d ", strManufacturerData.length());
46+
for (int i = 0; i < strManufacturerData.length(); i++) {
47+
Serial.printf("[%X]", strManufacturerData[i]);
48+
}
49+
Serial.printf("\n");
10050
}
101-
Serial.println("\nInvalid Data");
10251
return;
103-
}
104-
105-
Serial.printf("Found URL: %s\n", foundEddyURL.getURL().c_str());
106-
Serial.printf("Decoded URL: %s\n", foundEddyURL.getDecodedURL().c_str());
107-
Serial.printf("TX power %d\n", foundEddyURL.getPower());
108-
Serial.println("\n");
10952
}
110-
else if (serviceData[0] == 0x20)
111-
{
112-
Serial.println("Found an EddystoneTLM beacon!");
113-
BLEEddystoneTLM foundEddyURL = BLEEddystoneTLM();
114-
foundEddyURL.setData(serviceData);
11553

116-
Serial.printf("Reported battery voltage: %dmV\n", foundEddyURL.getVolt());
117-
Serial.printf("Reported temperature from TLM class: %.2fC\n", (double)foundEddyURL.getTemp());
118-
int temp = (int)serviceData[5] + (int)(serviceData[4] << 8);
119-
float calcTemp = temp / 256.0f;
120-
Serial.printf("Reported temperature from data: %.2fC\n", calcTemp);
121-
Serial.printf("Reported advertise count: %d\n", foundEddyURL.getCount());
122-
Serial.printf("Reported time since last reboot: %ds\n", foundEddyURL.getTime());
123-
Serial.println("\n");
124-
Serial.print(foundEddyURL.toString().c_str());
125-
Serial.println("\n");
54+
NimBLEUUID eddyUUID = (uint16_t)0xfeaa;
55+
56+
if (advertisedDevice->getServiceUUID().equals(eddyUUID)) {
57+
std::string serviceData = advertisedDevice->getServiceData(eddyUUID);
58+
if (serviceData[0] == 0x20) {
59+
Serial.println("Found an EddystoneTLM beacon!");
60+
NimBLEEddystoneTLM foundEddyTLM = NimBLEEddystoneTLM();
61+
foundEddyTLM.setData(reinterpret_cast<const uint8_t*>(serviceData.data()), serviceData.length());
62+
63+
Serial.printf("Reported battery voltage: %dmV\n", foundEddyTLM.getVolt());
64+
Serial.printf("Reported temperature from TLM class: %.2fC\n", (double)foundEddyTLM.getTemp());
65+
int temp = (int)serviceData[5] + (int)(serviceData[4] << 8);
66+
float calcTemp = temp / 256.0f;
67+
Serial.printf("Reported temperature from data: %.2fC\n", calcTemp);
68+
Serial.printf("Reported advertise count: %d\n", foundEddyTLM.getCount());
69+
Serial.printf("Reported time since last reboot: %ds\n", foundEddyTLM.getTime());
70+
Serial.println("\n");
71+
Serial.print(foundEddyTLM.toString().c_str());
72+
Serial.println("\n");
73+
}
12674
}
127-
}
12875
}
129-
};
130-
131-
void setup()
132-
{
133-
Serial.begin(115200);
134-
Serial.println("Scanning...");
135-
136-
BLEDevice::init("");
137-
pBLEScan = BLEDevice::getScan(); //create new scan
138-
pBLEScan->setScanCallbacks(new MyAdvertisedDeviceCallbacks());
139-
pBLEScan->setActiveScan(true); //active scan uses more power, but get results faster
140-
pBLEScan->setInterval(100);
141-
pBLEScan->setWindow(99); // less or equal setInterval value
76+
} scanCallbacks;
77+
78+
void setup() {
79+
Serial.begin(115200);
80+
Serial.println("Scanning...");
81+
82+
NimBLEDevice::init("Beacon-scanner");
83+
pBLEScan = BLEDevice::getScan();
84+
pBLEScan->setScanCallbacks(&scanCallbacks);
85+
pBLEScan->setActiveScan(true);
86+
pBLEScan->setInterval(100);
87+
pBLEScan->setWindow(100);
14288
}
14389

144-
void loop()
145-
{
146-
// put your main code here, to run repeatedly:
147-
BLEScanResults foundDevices = pBLEScan->getResults(scanTime, false);
148-
Serial.print("Devices found: ");
149-
Serial.println(foundDevices.getCount());
150-
Serial.println("Scan done!");
151-
pBLEScan->clearResults(); // delete results fromBLEScan buffer to release memory
152-
delay(2000);
90+
void loop() {
91+
NimBLEScanResults foundDevices = pBLEScan->getResults(scanTime, false);
92+
Serial.print("Devices found: ");
93+
Serial.println(foundDevices.getCount());
94+
Serial.println("Scan done!");
95+
pBLEScan->clearResults(); // delete results scan buffer to release memory
96+
delay(2000);
15397
}

examples/BLE_Beacon_Scanner/BLE_Beacon_Scanner.md

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,5 @@ Initiates a BLE device scan.
44
Checks if the discovered devices are
55
- an iBeacon
66
- an Eddystone TLM beacon
7-
- an Eddystone URL beacon
87

98
and sends the decoded beacon information over Serial log
Lines changed: 55 additions & 85 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
/*
2-
EddystoneTLM beacon for NimBLE by BeeGee based on https://github.com/pcbreflux/espressif/blob/master/esp32/arduino/sketchbook/ESP32_Eddystone_TLM_deepsleep/ESP32_Eddystone_TLM_deepsleep.ino
2+
EddystoneTLM beacon by BeeGee based on
3+
https://github.com/pcbreflux/espressif/blob/master/esp32/arduino/sketchbook/ESP32_Eddystone_TLM_deepsleep/ESP32_Eddystone_TLM_deepsleep.ino
34
EddystoneTLM frame specification https://github.com/google/eddystone/blob/master/eddystone-tlm/tlm-plain.md
45
*/
56

@@ -13,102 +14,71 @@
1314
5. Stop advertising.
1415
6. deep sleep
1516
17+
To read data advertised by this beacon use second ESP with example sketch BLE_Beacon_Scanner
1618
*/
1719

18-
#include "NimBLEDevice.h"
19-
#include "NimBLEBeacon.h"
20-
#include "NimBLEAdvertising.h"
21-
#include "NimBLEEddystoneURL.h"
20+
#include <Arduino.h>
21+
#include <NimBLEDevice.h>
22+
#include <NimBLEEddystoneTLM.h>
23+
#include <sys/time.h>
24+
#include <esp_sleep.h>
2225

23-
#include "sys/time.h"
24-
#include "esp_sleep.h"
26+
#define GPIO_DEEP_SLEEP_DURATION 10 // sleep x seconds and then wake up
27+
#define BEACON_POWER 3 // 3dbm
2528

26-
#define GPIO_DEEP_SLEEP_DURATION 10 // sleep x seconds and then wake up
27-
28-
// UUID 1 128-Bit (may use linux tool uuidgen or random numbers via https://www.uuidgenerator.net/)
29-
#define BEACON_UUID "8ec76ea3-6668-48da-9866-75be8bc86f4d"
30-
31-
RTC_DATA_ATTR static time_t last; // remember last boot in RTC Memory
29+
RTC_DATA_ATTR static time_t last; // remember last boot in RTC Memory
3230
RTC_DATA_ATTR static uint32_t bootcount; // remember number of boots in RTC Memory
31+
NimBLEAdvertising* pAdvertising;
32+
struct timeval nowTimeStruct;
3333

34-
BLEAdvertising *pAdvertising;
35-
struct timeval nowTimeStruct;
36-
37-
time_t lastTenth;
34+
#define BEACON_UUID \
35+
"8ec76ea3-6668-48da-9866-75be8bc86f4d" // UUID 1 128-Bit (may use linux tool uuidgen or random numbers via https://www.uuidgenerator.net/)
3836

3937
// Check
4038
// https://github.com/google/eddystone/blob/master/eddystone-tlm/tlm-plain.md
4139
// and http://www.hugi.scene.org/online/coding/hugi%2015%20-%20cmtadfix.htm
4240
// for the temperature value. It is a 8.8 fixed-point notation
43-
void setBeacon()
44-
{
45-
char beacon_data[25];
46-
uint16_t beconUUID = 0xFEAA;
47-
uint16_t volt = random(2800, 3700); // 3300mV = 3.3V
48-
float tempFloat = random(2000, 3100) / 100.0f;
49-
Serial.printf("Random temperature is %.2fC\n", tempFloat);
50-
int temp = (int)(tempFloat * 256); //(uint16_t)((float)23.00);
51-
Serial.printf("Converted to 8.8 format %0X%0X\n", (temp >> 8), (temp & 0xFF));
52-
53-
BLEAdvertisementData oAdvertisementData = BLEAdvertisementData();
54-
BLEAdvertisementData oScanResponseData = BLEAdvertisementData();
55-
56-
oScanResponseData.setFlags(0x06); // GENERAL_DISC_MODE 0x02 | BR_EDR_NOT_SUPPORTED 0x04
57-
oScanResponseData.setCompleteServices(BLEUUID(beconUUID));
58-
59-
beacon_data[0] = 0x20; // Eddystone Frame Type (Unencrypted Eddystone-TLM)
60-
beacon_data[1] = 0x00; // TLM version
61-
beacon_data[2] = (volt >> 8); // Battery voltage, 1 mV/bit i.e. 0xCE4 = 3300mV = 3.3V
62-
beacon_data[3] = (volt & 0xFF); //
63-
beacon_data[4] = (temp >> 8); // Beacon temperature
64-
beacon_data[5] = (temp & 0xFF); //
65-
beacon_data[6] = ((bootcount & 0xFF000000) >> 24); // Advertising PDU count
66-
beacon_data[7] = ((bootcount & 0xFF0000) >> 16); //
67-
beacon_data[8] = ((bootcount & 0xFF00) >> 8); //
68-
beacon_data[9] = (bootcount & 0xFF); //
69-
beacon_data[10] = ((lastTenth & 0xFF000000) >> 24); // Time since power-on or reboot as 0.1 second resolution counter
70-
beacon_data[11] = ((lastTenth & 0xFF0000) >> 16); //
71-
beacon_data[12] = ((lastTenth & 0xFF00) >> 8); //
72-
beacon_data[13] = (lastTenth & 0xFF); //
73-
74-
oScanResponseData.setServiceData(BLEUUID(beconUUID), std::string(beacon_data, 14));
75-
oAdvertisementData.setName("TLMBeacon");
76-
pAdvertising->setAdvertisementData(oAdvertisementData);
77-
pAdvertising->setScanResponseData(oScanResponseData);
41+
void setBeacon() {
42+
NimBLEEddystoneTLM eddystoneTLM;
43+
eddystoneTLM.setVolt((uint16_t)random(2800, 3700)); // 3300mV = 3.3V
44+
eddystoneTLM.setTemp(random(-3000, 3000)); // 3000 = 30.00 ˚C
45+
Serial.printf("Random Battery voltage is %d mV = 0x%04X\n", eddystoneTLM.getVolt(), eddystoneTLM.getVolt());
46+
Serial.printf("Random Temperature is: %d.%d 0x%04X\n",
47+
eddystoneTLM.getTemp() / 256,
48+
eddystoneTLM.getTemp() % 256 * 100 / 256);
49+
50+
NimBLEAdvertisementData oAdvertisementData = BLEAdvertisementData();
51+
NimBLEAdvertisementData oScanResponseData = BLEAdvertisementData();
52+
oScanResponseData.setServiceData(NimBLEUUID("FEAA"),
53+
reinterpret_cast<const uint8_t*>(&eddystoneTLM.getData()),
54+
sizeof(NimBLEEddystoneTLM::BeaconData));
55+
56+
oAdvertisementData.setName("ESP32 TLM Beacon");
57+
pAdvertising->setAdvertisementData(oAdvertisementData);
58+
pAdvertising->setScanResponseData(oScanResponseData);
7859
}
7960

80-
void setup()
81-
{
82-
83-
Serial.begin(115200);
84-
gettimeofday(&nowTimeStruct, NULL);
85-
86-
Serial.printf("start ESP32 %d\n", bootcount++);
87-
88-
Serial.printf("deep sleep (%lds since last reset, %lds since last boot)\n", nowTimeStruct.tv_sec, nowTimeStruct.tv_sec - last);
89-
90-
last = nowTimeStruct.tv_sec;
91-
lastTenth = nowTimeStruct.tv_sec * 10; // Time since last reset as 0.1 second resolution counter
92-
93-
// Create the BLE Device
94-
BLEDevice::init("TLMBeacon");
95-
96-
BLEDevice::setPower(ESP_PWR_LVL_N12);
97-
98-
pAdvertising = BLEDevice::getAdvertising();
99-
pAdvertising->enableScanResponse(true);
100-
101-
setBeacon();
102-
// Start advertising
103-
pAdvertising->start();
104-
Serial.println("Advertizing started for 10s ...");
105-
delay(10000);
106-
pAdvertising->stop();
107-
Serial.printf("enter deep sleep for 10s\n");
108-
esp_deep_sleep(1000000LL * GPIO_DEEP_SLEEP_DURATION);
109-
Serial.printf("in deep sleep\n");
61+
void setup() {
62+
Serial.begin(115200);
63+
gettimeofday(&nowTimeStruct, NULL);
64+
65+
Serial.printf("Starting ESP32. Bootcount = %lu\n", bootcount++);
66+
Serial.printf("Deep sleep (%llds since last reset, %llds since last boot)\n",
67+
nowTimeStruct.tv_sec,
68+
nowTimeStruct.tv_sec - last);
69+
last = nowTimeStruct.tv_sec;
70+
71+
NimBLEDevice::init("TLMBeacon");
72+
NimBLEDevice::setPower(BEACON_POWER);
73+
74+
pAdvertising = NimBLEDevice::getAdvertising();
75+
setBeacon();
76+
pAdvertising->start();
77+
Serial.println("Advertising started for 10s ...");
78+
delay(10000);
79+
pAdvertising->stop();
80+
Serial.printf("Enter deep sleep for 10s\n");
81+
esp_deep_sleep(1000000LL * GPIO_DEEP_SLEEP_DURATION);
11082
}
11183

112-
void loop()
113-
{
114-
}
84+
void loop() {}

0 commit comments

Comments
 (0)