Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit b8ea455

Browse filesBrowse files
PilnyTomasSuGlider
andauthored
Fix for negative temp in Eddystone TLM; solving espressif#7618 (espressif#7791)
* Changed data type of temperature * Changed data type in EddystoneTLM class and example * Revert "Changed data type in EddystoneTLM class and example" This reverts commit 1f3a941. * Draft of Eddystone TLM example * Adds MACROs to convert beacon temperature 2 Macros EDDYSTONE_TEMP_U16_TO_FLOAT(tempU16) - takes the TLM BigEndian 8.8 fixed point representation and returns its float value EDDYSTONE_TEMP_FLOAT_TO_U16(tempFloat) - takes a float (temperature) and returns its BigEndian 8.8 fixed point representation * Fixed temp * Changed to conform with PR comments * Fixed comment on closing bracket * Prints negative TEMP big endian as just 2 bytes * Extacts correct Eddyston Service Data * Fixes BLEEddystoneTLM::toString() negative temp * Fixes URL field length * Fixes Eddystone URL decoding * Fixes MSB for iBeacon UUID iBeacons use big endian BLE fields. * Fix to detect iBeacon that also has Service UUID This fix makes the BLE_iBeacon.ino to work correctly with the BLE_Beacon_Scanner.ino example --------- Co-authored-by: Rodrigo Garcia <rodrigo.garcia@espressif.com>
1 parent 23f653a commit b8ea455
Copy full SHA for b8ea455

File tree

Expand file treeCollapse file tree

6 files changed

+114
-99
lines changed
Filter options
Expand file treeCollapse file tree

6 files changed

+114
-99
lines changed

‎libraries/BLE/examples/BLE_Beacon_Scanner/BLE_Beacon_Scanner.ino

Copy file name to clipboardExpand all lines: libraries/BLE/examples/BLE_Beacon_Scanner/BLE_Beacon_Scanner.ino
+50-55Lines changed: 50 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,6 @@
1414
#include <BLEEddystoneTLM.h>
1515
#include <BLEBeacon.h>
1616

17-
#define ENDIAN_CHANGE_U16(x) ((((x)&0xFF00) >> 8) + (((x)&0xFF) << 8))
18-
1917
int scanTime = 5; //In seconds
2018
BLEScan *pBLEScan;
2119

@@ -37,58 +35,66 @@ class MyAdvertisedDeviceCallbacks : public BLEAdvertisedDeviceCallbacks
3735
Serial.println(devUUID.toString().c_str());
3836
Serial.println("");
3937
}
40-
else
38+
39+
if (advertisedDevice.haveManufacturerData() == true)
4140
{
42-
if (advertisedDevice.haveManufacturerData() == true)
43-
{
44-
std::string strManufacturerData = advertisedDevice.getManufacturerData();
41+
std::string strManufacturerData = advertisedDevice.getManufacturerData();
4542

46-
uint8_t cManufacturerData[100];
47-
strManufacturerData.copy((char *)cManufacturerData, strManufacturerData.length(), 0);
43+
uint8_t cManufacturerData[100];
44+
strManufacturerData.copy((char *)cManufacturerData, strManufacturerData.length(), 0);
4845

49-
if (strManufacturerData.length() == 25 && cManufacturerData[0] == 0x4C && cManufacturerData[1] == 0x00)
50-
{
51-
Serial.println("Found an iBeacon!");
52-
BLEBeacon oBeacon = BLEBeacon();
53-
oBeacon.setData(strManufacturerData);
54-
Serial.printf("iBeacon Frame\n");
55-
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());
56-
}
57-
else
46+
if (strManufacturerData.length() == 25 && cManufacturerData[0] == 0x4C && cManufacturerData[1] == 0x00)
47+
{
48+
Serial.println("Found an iBeacon!");
49+
BLEBeacon oBeacon = BLEBeacon();
50+
oBeacon.setData(strManufacturerData);
51+
Serial.printf("iBeacon Frame\n");
52+
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());
53+
}
54+
else
55+
{
56+
Serial.println("Found another manufacturers beacon!");
57+
Serial.printf("strManufacturerData: %d ", strManufacturerData.length());
58+
for (int i = 0; i < strManufacturerData.length(); i++)
5859
{
59-
Serial.println("Found another manufacturers beacon!");
60-
Serial.printf("strManufacturerData: %d ", strManufacturerData.length());
61-
for (int i = 0; i < strManufacturerData.length(); i++)
62-
{
63-
Serial.printf("[%X]", cManufacturerData[i]);
64-
}
65-
Serial.printf("\n");
60+
Serial.printf("[%X]", cManufacturerData[i]);
6661
}
62+
Serial.printf("\n");
6763
}
68-
return;
6964
}
7065

7166
uint8_t *payLoad = advertisedDevice.getPayload();
67+
// search for Eddystone Service Data in the advertising payload
68+
// *payload shall point to eddystone data or to its end when not found
69+
const uint8_t serviceDataEddystone[3] = {0x16, 0xAA, 0xFE}; // it has Eddystone BLE UUID
70+
const size_t payLoadLen = advertisedDevice.getPayloadLength();
71+
uint8_t *payLoadEnd = payLoad + payLoadLen - 1; // address of the end of payLoad space
72+
while (payLoad < payLoadEnd) {
73+
if (payLoad[1] == serviceDataEddystone[0] && payLoad[2] == serviceDataEddystone[1] && payLoad[3] == serviceDataEddystone[2]) {
74+
// found!
75+
payLoad += 4;
76+
break;
77+
}
78+
payLoad += *payLoad + 1; // payLoad[0] has the field Length
79+
}
7280

73-
BLEUUID checkUrlUUID = (uint16_t)0xfeaa;
74-
75-
if (advertisedDevice.getServiceUUID().equals(checkUrlUUID))
81+
if (payLoad < payLoadEnd) // Eddystone Service Data and respective BLE UUID were found
7682
{
77-
if (payLoad[11] == 0x10)
83+
if (*payLoad == 0x10)
7884
{
7985
Serial.println("Found an EddystoneURL beacon!");
8086
BLEEddystoneURL foundEddyURL = BLEEddystoneURL();
81-
std::string eddyContent((char *)&payLoad[11]); // incomplete EddystoneURL struct!
82-
83-
foundEddyURL.setData(eddyContent);
87+
uint8_t URLLen = *(payLoad - 4) - 3; // Get Field Length less 3 bytes (type and UUID)
88+
foundEddyURL.setData(std::string((char*)payLoad, URLLen));
8489
std::string bareURL = foundEddyURL.getURL();
8590
if (bareURL[0] == 0x00)
8691
{
87-
size_t payLoadLen = advertisedDevice.getPayloadLength();
92+
// dumps all bytes in advertising payload
8893
Serial.println("DATA-->");
94+
uint8_t *payLoad = advertisedDevice.getPayload();
8995
for (int idx = 0; idx < payLoadLen; idx++)
9096
{
91-
Serial.printf("0x%08X ", payLoad[idx]);
97+
Serial.printf("0x%02X ", payLoad[idx]);
9298
}
9399
Serial.println("\nInvalid Data");
94100
return;
@@ -98,30 +104,19 @@ class MyAdvertisedDeviceCallbacks : public BLEAdvertisedDeviceCallbacks
98104
Serial.printf("Decoded URL: %s\n", foundEddyURL.getDecodedURL().c_str());
99105
Serial.printf("TX power %d\n", foundEddyURL.getPower());
100106
Serial.println("\n");
101-
}
102-
else if (payLoad[11] == 0x20)
107+
}
108+
else if (*payLoad == 0x20)
103109
{
104110
Serial.println("Found an EddystoneTLM beacon!");
105-
BLEEddystoneTLM foundEddyURL = BLEEddystoneTLM();
106-
std::string eddyContent((char *)&payLoad[11]); // incomplete EddystoneURL struct!
107-
108-
eddyContent = "01234567890123";
109-
110-
for (int idx = 0; idx < 14; idx++)
111-
{
112-
eddyContent[idx] = payLoad[idx + 11];
113-
}
114-
115-
foundEddyURL.setData(eddyContent);
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)payLoad[16] + (int)(payLoad[15] << 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());
111+
112+
BLEEddystoneTLM eddystoneTLM;
113+
eddystoneTLM.setData(std::string((char*)payLoad, 14));
114+
Serial.printf("Reported battery voltage: %dmV\n", eddystoneTLM.getVolt());
115+
Serial.printf("Reported temperature: %.2f°C (raw data=0x%04X)\n", eddystoneTLM.getTemp(), eddystoneTLM.getRawTemp());
116+
Serial.printf("Reported advertise count: %d\n", eddystoneTLM.getCount());
117+
Serial.printf("Reported time since last reboot: %ds\n", eddystoneTLM.getTime());
123118
Serial.println("\n");
124-
Serial.print(foundEddyURL.toString().c_str());
119+
Serial.print(eddystoneTLM.toString().c_str());
125120
Serial.println("\n");
126121
}
127122
}

‎libraries/BLE/examples/BLE_EddystoneTLM_Beacon/BLE_EddystoneTLM_Beacon.ino

Copy file name to clipboardExpand all lines: libraries/BLE/examples/BLE_EddystoneTLM_Beacon/BLE_EddystoneTLM_Beacon.ino
+10-12Lines changed: 10 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
5. Stop advertising.
1414
6. deep sleep
1515
16+
To read data advertised by this beacon use second ESP with example sketch BLE_Beacon_Scanner
1617
*/
1718
#include "sys/time.h"
1819

@@ -22,7 +23,7 @@
2223
#include "BLEUtils.h"
2324
#include "BLEBeacon.h"
2425
#include "BLEAdvertising.h"
25-
#include "BLEEddystoneURL.h"
26+
#include "BLEEddystoneTLM.h"
2627

2728
#include "esp_sleep.h"
2829

@@ -48,10 +49,10 @@ void setBeacon()
4849
char beacon_data[25];
4950
uint16_t beconUUID = 0xFEAA;
5051
uint16_t volt = random(2800, 3700); // 3300mV = 3.3V
51-
float tempFloat = random(2000, 3100) / 100.0f;
52-
Serial.printf("Random temperature is %.2fC\n", tempFloat);
53-
int temp = (int)(tempFloat * 256); //(uint16_t)((float)23.00);
54-
Serial.printf("Converted to 8.8 format %0X%0X\n", (temp >> 8), (temp & 0xFF));
52+
float tempFloat = random(-3000, 3000) / 100.0f;
53+
Serial.printf("Random temperature is %.2f°C\n", tempFloat);
54+
int temp = (int)(tempFloat * 256);
55+
Serial.printf("Converted to 8.8 format %0X%0X\n", (temp >> 8) & 0xFF, (temp & 0xFF));
5556

5657
BLEAdvertisementData oAdvertisementData = BLEAdvertisementData();
5758
BLEAdvertisementData oScanResponseData = BLEAdvertisementData();
@@ -82,13 +83,11 @@ void setBeacon()
8283

8384
void setup()
8485
{
85-
8686
Serial.begin(115200);
8787
gettimeofday(&nowTimeStruct, NULL);
8888

89-
Serial.printf("start ESP32 %d\n", bootcount++);
90-
91-
Serial.printf("deep sleep (%lds since last reset, %lds since last boot)\n", nowTimeStruct.tv_sec, nowTimeStruct.tv_sec - last);
89+
Serial.printf("Starting ESP32. Bootcount = %d\n", bootcount++);
90+
Serial.printf("Deep sleep (%lds since last reset, %lds since last boot)\n", nowTimeStruct.tv_sec, nowTimeStruct.tv_sec - last);
9291

9392
last = nowTimeStruct.tv_sec;
9493
lastTenth = nowTimeStruct.tv_sec * 10; // Time since last reset as 0.1 second resolution counter
@@ -103,12 +102,11 @@ void setup()
103102
setBeacon();
104103
// Start advertising
105104
pAdvertising->start();
106-
Serial.println("Advertizing started for 10s ...");
105+
Serial.println("Advertising started for 10s ...");
107106
delay(10000);
108107
pAdvertising->stop();
109-
Serial.printf("enter deep sleep for 10s\n");
108+
Serial.printf("Enter deep sleep for 10s\n");
110109
esp_deep_sleep(1000000LL * GPIO_DEEP_SLEEP_DURATION);
111-
Serial.printf("in deep sleep\n");
112110
}
113111

114112
void loop()

‎libraries/BLE/src/BLEBeacon.cpp

Copy file name to clipboardExpand all lines: libraries/BLE/src/BLEBeacon.cpp
+1-1Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ uint16_t BLEBeacon::getMinor() {
4040
}
4141

4242
BLEUUID BLEBeacon::getProximityUUID() {
43-
return BLEUUID(m_beaconData.proximityUUID, 16, false);
43+
return BLEUUID(m_beaconData.proximityUUID, 16, true);
4444
}
4545

4646
int8_t BLEBeacon::getSignalPower() {

‎libraries/BLE/src/BLEEddystoneTLM.cpp

Copy file name to clipboardExpand all lines: libraries/BLE/src/BLEEddystoneTLM.cpp
+22-5Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,6 @@
1717
#include "BLEEddystoneTLM.h"
1818

1919
static const char LOG_TAG[] = "BLEEddystoneTLM";
20-
#define ENDIAN_CHANGE_U16(x) ((((x)&0xFF00)>>8) + (((x)&0xFF)<<8))
21-
#define ENDIAN_CHANGE_U32(x) ((((x)&0xFF000000)>>24) + (((x)&0x00FF0000)>>8)) + ((((x)&0xFF00)<<8) + (((x)&0xFF)<<24))
2220

2321
BLEEddystoneTLM::BLEEddystoneTLM() {
2422
beaconUUID = 0xFEAA;
@@ -47,9 +45,13 @@ uint16_t BLEEddystoneTLM::getVolt() {
4745
} // getVolt
4846

4947
float BLEEddystoneTLM::getTemp() {
50-
return ENDIAN_CHANGE_U16(m_eddystoneData.temp) / 256.0f;
48+
return EDDYSTONE_TEMP_U16_TO_FLOAT(m_eddystoneData.temp);
5149
} // getTemp
5250

51+
uint16_t BLEEddystoneTLM::getRawTemp() {
52+
return ENDIAN_CHANGE_U16(m_eddystoneData.temp);
53+
} // getRawTemp
54+
5355
uint32_t BLEEddystoneTLM::getCount() {
5456
return ENDIAN_CHANGE_U32(m_eddystoneData.advCount);
5557
} // getCount
@@ -73,7 +75,7 @@ std::string BLEEddystoneTLM::toString() {
7375
out += " mV\n";
7476

7577
out += "Temperature ";
76-
snprintf(val, sizeof(val), "%.2f", ENDIAN_CHANGE_U16(m_eddystoneData.temp) / 256.0f);
78+
snprintf(val, sizeof(val), "%.2f", ((int16_t)ENDIAN_CHANGE_U16(m_eddystoneData.temp)) / 256.0f);
7779
out += val;
7880
out += " C\n";
7981

@@ -110,6 +112,21 @@ std::string BLEEddystoneTLM::toString() {
110112

111113
/**
112114
* Set the raw data for the beacon record.
115+
* Example:
116+
* uint8_t *payLoad = advertisedDevice.getPayload();
117+
* eddystoneTLM.setData(std::string((char*)payLoad+22, advertisedDevice.getPayloadLength() - 22));
118+
* Note: the offset 22 works for current implementation of example BLE_EddystoneTLM Beacon.ino, however it is not static and will be reimplemented
119+
* Data frame:
120+
* | Field || Len | Type | UUID | EddyStone TLM |
121+
* | Offset || 0 | 1 | 2 | 4 |
122+
* | Len || 1 B | 1 B | 2 B | 14 B |
123+
* | Data || ?? | ?? | 0xAA | 0xFE | ??? |
124+
*
125+
* EddyStone TLM frame:
126+
* | Field || Type | Version | Batt mV | Beacon temp | Cnt since boot | Time since boot |
127+
* | Offset || 0 | 1 | 2 | 4 | 6 | 10 |
128+
* | Len || 1 B | 1 B | 2 B | 2 B | 4 B | 4 B |
129+
* | Data || 0x20 | ?? | ?? | ?? | ?? | ?? | | | | | | | | |
113130
*/
114131
void BLEEddystoneTLM::setData(std::string data) {
115132
if (data.length() != sizeof(m_eddystoneData)) {
@@ -132,7 +149,7 @@ void BLEEddystoneTLM::setVolt(uint16_t volt) {
132149
} // setVolt
133150

134151
void BLEEddystoneTLM::setTemp(float temp) {
135-
m_eddystoneData.temp = (uint16_t)temp;
152+
m_eddystoneData.temp = EDDYSTONE_TEMP_FLOAT_TO_U16(temp);
136153
} // setTemp
137154

138155
void BLEEddystoneTLM::setCount(uint32_t advCount) {

‎libraries/BLE/src/BLEEddystoneTLM.h

Copy file name to clipboardExpand all lines: libraries/BLE/src/BLEEddystoneTLM.h
+30-25Lines changed: 30 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,10 @@
1010
#include "BLEUUID.h"
1111

1212
#define EDDYSTONE_TLM_FRAME_TYPE 0x20
13+
#define ENDIAN_CHANGE_U16(x) ((((x)&0xFF00)>>8) + (((x)&0xFF)<<8))
14+
#define ENDIAN_CHANGE_U32(x) ((((x)&0xFF000000)>>24) + (((x)&0x00FF0000)>>8)) + ((((x)&0xFF00)<<8) + (((x)&0xFF)<<24))
15+
#define EDDYSTONE_TEMP_U16_TO_FLOAT(tempU16) (((int16_t)ENDIAN_CHANGE_U16(tempU16)) / 256.0f)
16+
#define EDDYSTONE_TEMP_FLOAT_TO_U16(tempFloat) (ENDIAN_CHANGE_U16(((int)((tempFloat) * 256))))
1317

1418
/**
1519
* @brief Representation of a beacon.
@@ -18,33 +22,34 @@
1822
*/
1923
class BLEEddystoneTLM {
2024
public:
21-
BLEEddystoneTLM();
22-
std::string getData();
23-
BLEUUID getUUID();
24-
uint8_t getVersion();
25-
uint16_t getVolt();
26-
float getTemp();
27-
uint32_t getCount();
28-
uint32_t getTime();
29-
std::string toString();
30-
void setData(std::string data);
31-
void setUUID(BLEUUID l_uuid);
32-
void setVersion(uint8_t version);
33-
void setVolt(uint16_t volt);
34-
void setTemp(float temp);
35-
void setCount(uint32_t advCount);
36-
void setTime(uint32_t tmil);
25+
BLEEddystoneTLM();
26+
std::string getData();
27+
BLEUUID getUUID();
28+
uint8_t getVersion();
29+
uint16_t getVolt();
30+
float getTemp();
31+
uint16_t getRawTemp();
32+
uint32_t getCount();
33+
uint32_t getTime();
34+
std::string toString();
35+
void setData(std::string data);
36+
void setUUID(BLEUUID l_uuid);
37+
void setVersion(uint8_t version);
38+
void setVolt(uint16_t volt);
39+
void setTemp(float temp);
40+
void setCount(uint32_t advCount);
41+
void setTime(uint32_t tmil);
3742

3843
private:
39-
uint16_t beaconUUID;
40-
struct {
41-
uint8_t frameType;
42-
uint8_t version;
43-
uint16_t volt;
44-
uint16_t temp;
45-
uint32_t advCount;
46-
uint32_t tmil;
47-
} __attribute__((packed)) m_eddystoneData;
44+
uint16_t beaconUUID;
45+
struct {
46+
uint8_t frameType;
47+
uint8_t version;
48+
uint16_t volt;
49+
uint16_t temp;
50+
uint32_t advCount;
51+
uint32_t tmil;
52+
} __attribute__((packed)) m_eddystoneData;
4853

4954
}; // BLEEddystoneTLM
5055

‎libraries/BLE/src/BLEEddystoneURL.h

Copy file name to clipboardExpand all lines: libraries/BLE/src/BLEEddystoneURL.h
+1-1Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ class BLEEddystoneURL {
3535
struct {
3636
uint8_t frameType;
3737
int8_t advertisedTxPower;
38-
uint8_t url[16];
38+
uint8_t url[18]; // 18 bytes: 1 byte for URL scheme + up to 17 bytes of URL
3939
} __attribute__((packed)) m_eddystoneData;
4040

4141
}; // BLEEddystoneURL

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.