I have 2 ESP32s, a server and a client in the Arduino platform. The notifyCallback works fine when a sensor message is sent from the server code in the loop(). However, I plan to use the server (sensor) ESP32 in a battery operated scenario. I'd like to send the sensor value, then put the ESP32 into deep sleep mode. When I moved the code out of the loop(), to be in the setup() with deep sleep functionality, I don't get a notification back from the client. Following is my code:
Server Code:
Code: Untitled.cpp Select all
#include <BLEDevice.h>
#include <BLEServer.h>
#include <BLEUtils.h>
#include <BLE2902.h>
#include "DHT.h"
#define DHTPIN 4
#define DHTTYPE DHT22
#define uS_TO_S_FACTOR 1000000 //Conversion factor for micro seconds to seconds
#define TIME_TO_SLEEP 15 //Time ESP32 will go to sleep (in seconds)
RTC_DATA_ATTR int bootCount = 0;
DHT dht(DHTPIN, DHTTYPE);
BLECharacteristic *pCharacteristic;
bool deviceConnected = false;
uint8_t txValue = 50;
#define SERVICE_UUID "4fafc201-1fb5-459e-8fcc-c5c9c331914b" // UART service UUID
#define CHARACTERISTIC_UUID_TX "beb5483e-36e1-4688-b7f5-ea07361b26a8"
class MyServerCallbacks: public BLEServerCallbacks {
void onConnect(BLEServer* pServer) {
deviceConnected = true;
};
void onDisconnect(BLEServer* pServer) {
deviceConnected = false;
}
};
//Function that prints the reason by which ESP32 has been awaken from sleep
void print_wakeup_reason(){
esp_sleep_wakeup_cause_t wakeup_reason;
wakeup_reason = esp_sleep_get_wakeup_cause();
switch(wakeup_reason)
{
case 1 : Serial.println("Wakeup caused by external signal using RTC_IO"); break;
case 2 : Serial.println("Wakeup caused by external signal using RTC_CNTL"); break;
case 3 : Serial.println("Wakeup caused by timer"); break;
case 4 : Serial.println("Wakeup caused by touchpad"); break;
case 5 : Serial.println("Wakeup caused by ULP program"); break;
default : Serial.println("Wakeup was not caused by deep sleep"); break;
}
}
void setup() {
Serial.begin(115200);
Serial.println(F("initating DHT22..."));
dht.begin();
// Create the BLE Device
BLEDevice::init("UART"); // Name must not be longer than 5 chars!!!
// Create the BLE Server
BLEServer *pServer = BLEDevice::createServer();
pServer->setCallbacks(new MyServerCallbacks());
// Create the BLE Service
BLEService *pService = pServer->createService(SERVICE_UUID);
// Create a BLE Characteristic
pCharacteristic = pService->createCharacteristic(
CHARACTERISTIC_UUID_TX,
BLECharacteristic::PROPERTY_NOTIFY|BLECharacteristic::PROPERTY_READ|BLECharacteristic::PROPERTY_WRITE
);
BLE2902 *desc = new BLE2902();
desc->setNotifications(true);
pCharacteristic->addDescriptor(desc);
// Start the service
pService->start();
pServer->getAdvertising()->addServiceUUID(SERVICE_UUID);
// Start advertising
pServer->getAdvertising()->start();
Serial.println(pService->getUUID().toString().c_str());
Serial.println("Waiting for a client connection to notify...");
if (deviceConnected) {
float f = dht.readTemperature(true);
char fStr[10];
sprintf(fStr, "%4.4f", f);
Serial.print("Temperature reading: ");
Serial.println(fStr);
Serial.printf("*** Sent Value: %d ***\n", fStr);
pCharacteristic->setValue(fStr);
delay(3000);
pCharacteristic->setValue(fStr);
pCharacteristic->notify();
//Set timer to 5 seconds
esp_sleep_enable_timer_wakeup(TIME_TO_SLEEP * uS_TO_S_FACTOR);
Serial.println("Setup ESP32 to sleep for every " + String(TIME_TO_SLEEP) +
" Seconds");
//Go to sleep now
esp_deep_sleep_start();
}
//delay(60000);
}
void loop() {}rst:0x1 (POWERON_RESET),boot:0x17 (SPI_FAST_FLASH_BOOT)
configsip: 0, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:1
load:0x3fff0018,len:4
load:0x3fff001c,len:1216
ho 0 tail 12 room 4
load:0x40078000,len:9720
ho 0 tail 12 room 4
load:0x40080400,len:6352
entry 0x400806b8
initating DHT22...
4fafc201-1fb5-459e-8fcc-c5c9c331914b
Waiting a client connection to notify...
Client code:
Code: Untitled.cpp Select all
#include "BLEDevice.h"
// The remote service we wish to connect to.
static BLEUUID serviceUUID("4fafc201-1fb5-459e-8fcc-c5c9c331914b");
static BLEUUID charUUID("beb5483e-36e1-4688-b7f5-ea07361b26a8");
static BLEAddress *pServerAddress;
static boolean doConnect = false;
static boolean connected = false;
static BLERemoteCharacteristic* pRemoteCharacteristic;
static void notifyCallback(
BLERemoteCharacteristic* pBLERemoteCharacteristic,
uint8_t* pData,
size_t length,
bool isNotify) {
Serial.print(pBLERemoteCharacteristic->getUUID().toString().c_str());
Serial.print(" of data length ");
Serial.println(length);
byte buffer[42];
Serial.print("The characteristic value sent was: ");
std::string farhenheight = pRemoteCharacteristic->readValue();
Serial.print("Farheinheight: ");
Serial.println(farhenheight.c_str());
}
class MyClientCallback : public BLEClientCallbacks {
void onConnect(BLEClient* pclient) {
Serial.println("connected again ... ");
}
void onDisconnect(BLEClient* pclient) {
connected = false;
Serial.println("onDisconnect");
}
};
bool connectToServer(BLEAddress pAddress) {
Serial.print("Forming a connection to ");
Serial.println(pAddress.toString().c_str());
BLEClient* pClient = BLEDevice::createClient();
Serial.println(" - Created client");
pClient->setClientCallbacks(new MyClientCallback());
// Connect to the remove BLE Server.
pClient->connect(pAddress);
Serial.println(" - Connected to server");
// Obtain a reference to the service we are after in the remote BLE server.
BLERemoteService* pRemoteService = pClient->getService(serviceUUID);
Serial.println(pRemoteService->toString().c_str());
if (pRemoteService == nullptr) {
Serial.print("Failed to find our service UUID: ");
Serial.println(serviceUUID.toString().c_str());
return false;
}
Serial.println(" - Found our service");
// Obtain a reference to the characteristic in the service of the remote BLE server.
pRemoteCharacteristic = pRemoteService->getCharacteristic(charUUID);
if (pRemoteCharacteristic == nullptr) {
Serial.print("Failed to find our characteristic UUID: ");
Serial.println(charUUID.toString().c_str());
return false;
}
Serial.println(" - Found our characteristic");
//
// Serial.print("The characteristic value sent was: ");
// std::string farhenheight = pRemoteCharacteristic->readValue();
// Serial.print("Farheinheight: ");
// Serial.println(farhenheight.c_str());
pRemoteCharacteristic->registerForNotify(notifyCallback);
}
class MyAdvertisedDeviceCallbacks: public BLEAdvertisedDeviceCallbacks {
void onResult(BLEAdvertisedDevice advertisedDevice) {
Serial.print("BLE Advertised Device found: ");
Serial.println(advertisedDevice.toString().c_str());
//Serial.print(advertisedDevice.haveServiceUUID());
if(advertisedDevice.haveServiceUUID()){
Serial.println(advertisedDevice.getServiceUUID().toString().c_str());
}
// We have found a device, let us now see if it contains the service we are looking for.
if (advertisedDevice.haveServiceUUID() && advertisedDevice.getServiceUUID().equals(serviceUUID)) {
//
Serial.print("Found our device! address: ");
advertisedDevice.getScan()->stop();
pServerAddress = new BLEAddress(advertisedDevice.getAddress());
doConnect = true;
} // Found our server
} // onResult
}; // MyAdvertisedDeviceCallbacks
void setup() {
Serial.begin(115200);
Serial.println("Starting Arduino BLE Client application...");
BLEDevice::init("");
BLEScan* pBLEScan = BLEDevice::getScan();
pBLEScan->setAdvertisedDeviceCallbacks(new MyAdvertisedDeviceCallbacks());
pBLEScan->setActiveScan(true);
pBLEScan->start(30);
} // End of setup.
// This is the Arduino main loop function.
void loop() {
if (doConnect == true) {
if (connectToServer(*pServerAddress)) {
Serial.println("We are now connected to the BLE Server.");
connected = true;
} else {
Serial.println("We have failed to connect to the server; there is nothin more we will do.");
}
//doConnect = false;
}
if (connected == false){
BLEDevice::getScan()->start(0);
}
else{
doConnect = false;
}
delay(1000); // Delay a second between loops.
} // End of looprst:0x1 (POWERON_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
configsip: 0, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:1
load:0x3fff0018,len:4
load:0x3fff001c,len:1216
ho 0 tail 12 room 4
load:0x40078000,len:9720
ho 0 tail 12 room 4
load:0x40080400,len:6352
entry 0x400806b8
Starting Arduino BLE Client application...
BLE Advertised Device found: Name: , Address: 19:e7:99:d9:32:64, manufacturer data: 060001092002e206e435e8b3b0de4daa475d8a7609aad95f554fc87cd5
BLE Advertised Device found: Name: , Address: 78:bd:bc:41:75:fc, manufacturer data: 7500420401808078bdbc4175fc7abdbc819fc201000000000000
BLE Advertised Device found: Name: , Address: 79:1a:60:1b:5a:40, manufacturer data: 4c001005481c78327b, txPower: 12
BLE Advertised Device found: Name: , Address: 74:3e:c8:ef:1b:57, manufacturer data: 4c001005051c4e8858, txPower: 12
BLE Advertised Device found: Name: , Address: 55
BLE Advertised Device found: Name: UART, Address: 80:7d:3a:c5:06:e6, serviceUUID: 4fafc201-1fb5-459e-8fcc-c5c9c331914b, txPower: 3
4fafc201-1fb5-459e-8fcc-c5c9c331914b
Found our device! address: Forming a connection to 80:7d:3a:c5:06:e6
- Created client
connected again ...
- Connected to server
Service: uuid: 4fafc201-1fb5-459e-8fcc-c5c9c331914b, start_handle: 40 0x0028, end_handle: 65535 0xffff
- Found our service
- Found our characteristic
We are now connected to the BLE Server.
As you can see, the code in the client never reaches the notifyCallback handler method. I have looked for answers on this forum, tried quite a few things, but no luck. Any idea what I am doing wrong?
Thx in advance for any suggestions.