I have a Tilt hydrometer that acts as a beacon and transmits Temperature and specific gravity.
I installed the ESP32 board in the Arduino IDE.
I loaded the sketch BLE_scan from the ESP32 BLE Arduino examples .
The hydrometer is perfectly detected:
Address
F7:44:3E:01:7F:36
ManufacturerData
4C 00 02 15 A4 95 BB 20 C5 B1 4B 44 B5 12 13 70 F0 2D 74 DE 00 4A 03 F1 22
4C 00 :Apple beacon
02 :type ( constant ,defined by ibeacon spec )
15 :length ( constant defined by ibeacon spec )
A4 95 BB 20 C5 B1 4B 44 B5 12 13 70 F0 2D 74 DE :device UUID
00 4A :major - temperature (in degrees fahrenheit)
03 F1 :minor - specific gravity (x1000)
22 signal power ?? maybe
Is there a sketch that allows me to get the manufacturer data by passing the address as a parameter ?
Robin2
July 14, 2019, 6:49am
2
If the BLE_scan program (which you have not posted) can display the values you are interested in then I'm sure it can be adapted to do other stuff with those values.
What have you tried?
...R
Here is the BLE_scan sketch:
/*
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
*/
#include <BLEDevice.h>
#include <BLEUtils.h>
#include <BLEScan.h>
#include <BLEAdvertisedDevice.h>
int scanTime = 5; //In seconds
BLEScan* pBLEScan;
class MyAdvertisedDeviceCallbacks: public BLEAdvertisedDeviceCallbacks {
void onResult(BLEAdvertisedDevice advertisedDevice) {
Serial.printf("Advertised Device: %s \n", advertisedDevice.toString().c_str());
}
};
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);
}
Here is the BLEAdvertisedDevice.h
The interesting part looks like at line 34 std::string getManufacturerData();
/*
* BLEAdvertisedDevice.h
*
* Created on: Jul 3, 2017
* Author: kolban
*/
#ifndef COMPONENTS_CPP_UTILS_BLEADVERTISEDDEVICE_H_
#define COMPONENTS_CPP_UTILS_BLEADVERTISEDDEVICE_H_
#include "sdkconfig.h"
#if defined(CONFIG_BT_ENABLED)
#include <esp_gattc_api.h>
#include <map>
#include "BLEAddress.h"
#include "BLEScan.h"
#include "BLEUUID.h"
class BLEScan;
class BLEAdvertisedDevice {
public:
BLEAdvertisedDevice();
BLEAddress getAddress();
uint16_t getApperance();
std::string getManufacturerData();
std::string getName();
int getRSSI();
BLEScan* getScan();
BLEUUID getServiceUUID();
int8_t getTXPower();
bool haveAppearance();
bool haveManufacturerData();
bool haveName();
bool haveRSSI();
bool haveServiceUUID();
bool haveTXPower();
std::string toString();
private:
friend class BLEScan;
void parseAdvertisement(uint8_t* payload);
void setAddress(BLEAddress address);
void setAdFlag(uint8_t adFlag);
void setAdvertizementResult(uint8_t* payload);
void setAppearance(uint16_t appearance);
void setManufacturerData(std::string manufacturerData);
void setName(std::string name);
void setRSSI(int rssi);
void setScan(BLEScan* pScan);
void setServiceUUID(BLEUUID serviceUUID);
void setTXPower(int8_t txPower);
bool m_haveAppearance;
bool m_haveManufacturerData;
bool m_haveName;
bool m_haveRSSI;
bool m_haveServiceUUID;
bool m_haveTXPower;
BLEAddress m_address = BLEAddress((uint8_t*)"\0\0\0\0\0\0");
uint8_t m_adFlag;
uint16_t m_appearance;
int m_deviceType;
std::string m_manufacturerData;
std::string m_name;
BLEScan* m_pScan;
int m_rssi;
BLEUUID m_serviceUUID;
int8_t m_txPower;
};
class BLEAdvertisedDeviceCallbacks {
public:
virtual ~BLEAdvertisedDeviceCallbacks() {}
virtual void onResult(BLEAdvertisedDevice* pAdvertisedDevice) = 0;
};
#endif /* CONFIG_BT_ENABLED */
#endif /* COMPONENTS_CPP_UTILS_BLEADVERTISEDDEVICE_H_ */
Robin2
July 14, 2019, 4:32pm
4
Biasedturkey:
The interesting part looks like at line 34 std::string getManufacturerData();
So what happened when you tried using that function ?
...R
I completed the following sketch.
The tilt hydrometer address is defined at :
String knownAddresses[] = { "f7:44:3e:01:7f:36"};
The Tilt address is found using an Android Beacon Scanner.
The Gravity and temperature are displayed on the arduio IDE terminal.
#include "BLEDevice.h"
int Lampara = 33;
int Contador = 0;
long Temperature;
long Gravity;
float TempDec;
float GravDec;
static BLEAddress *pServerAddress;
BLEScan* pBLEScan;
BLEClient* pClient;
bool deviceFound = false;
bool Encendida = false;
bool BotonOff = false;
String knownAddresses[] = { "f7:44:3e:01:7f:36"};
unsigned long entry;
static void notifyCallback(
BLERemoteCharacteristic* pBLERemoteCharacteristic,
uint8_t* pData,
size_t length,
bool isNotify) {
Serial.print("Notify callback for characteristic ");
Serial.print(pBLERemoteCharacteristic->getUUID().toString().c_str());
Serial.print(" of data length ");
Serial.println(length);
}
class MyAdvertisedDeviceCallbacks: public BLEAdvertisedDeviceCallbacks {
void onResult(BLEAdvertisedDevice Device){
//Serial.print("BLE Advertised Device found: ");
//Serial.println(Device.toString().c_str());
pServerAddress = new BLEAddress(Device.getAddress());
bool known = false;
bool Master = false;
String ManufData = Device.toString().c_str();
String TempHex = ManufData.substring(95,99 );
String GravHex = ManufData.substring( 99,103 );
//long Temperature = strtol( TempHex.c_str, NULL, 16 );
for (int i = 0; i < (sizeof(knownAddresses) / sizeof(knownAddresses[0])); i++) {
if (strcmp(pServerAddress->toString().c_str(), knownAddresses[i].c_str()) == 0)
known = true;
}
if (known) {
Serial.print("Device found: ");
Serial.println(Device.getRSSI());
Serial.print("Temperature ");
Serial.print(TempHex);
Serial.print (" " );
Temperature = strtol( TempHex.c_str() , NULL, 16 );
TempDec = ( (Temperature - 32.0 ) * (5.0 / 9.0 ));
Serial.println ( TempDec );
//Serial.println( Temperature );
//Serial.println(strtol(TempHex.c_str(), NULL, 16));
Serial.print("Gravity ");
Serial.print(GravHex);
Serial.print (" " );
Gravity = strtol ( GravHex.c_str() , NULL, 16 );
GravDec = ( Gravity / 1000.0 );
Serial.println( GravDec ,3 );
//Serial.println( Gravity );
//Serial.println(strtol(GravHex.c_str(), NULL, 16));
if (Device.getRSSI() > -85) {
deviceFound = true;
}
else {
deviceFound = false;
}
Device.getScan()->stop();
delay(100);
}
}
};
void setup() {
Serial.begin(115200);
pinMode(Lampara,OUTPUT);
digitalWrite(Lampara,LOW);
BLEDevice::init("");
pClient = BLEDevice::createClient();
pBLEScan = BLEDevice::getScan();
pBLEScan->setAdvertisedDeviceCallbacks(new MyAdvertisedDeviceCallbacks());
pBLEScan->setActiveScan(true);
Serial.println("Done");
}
void Bluetooth() {
Serial.println();
Serial.println("BLE Scan restarted.....");
deviceFound = false;
BLEScanResults scanResults = pBLEScan->start(5);
if (deviceFound) {
Serial.println("Encender Lamara");
Encendida = true;
digitalWrite(Lampara,HIGH);
Contador = 0;
delay(10000);
}
else{
digitalWrite(Lampara,LOW);
delay(1000);
}
}
void loop() {
Bluetooth();
}
1 Like
Robin2
July 16, 2019, 6:30am
6
Does Reply #4 mean that the problem is solved?
...R
Yes, problem solved, but I don't know how to show that it is solved.
Robin2
July 16, 2019, 2:30pm
8
Biasedturkey:
Yes, problem solved, but I don't know how to show that it is solved.
The usual thing is to edit your Original Post and add the word [SOLVED] to the title.
...R