Hi
I was able to continuously notify if a Button was pressed or not on my firebeetle esp32 to nrfconnect. Now if I only want to notify when the button state has changed (to save battery) nrfconnect does not automatically detect the change (if I click on the arrow down then I see the change but I does not update itself) and also Droidscript does not see the change (it sees the change when I notify continuously). Serial monitor though shows the change. Why is that? (sorry for my bad english). Here is the code:
#include <BLEDevice.h>
#include <BLEServer.h>
#include <BLEUtils.h>
#include <BLE2902.h>
BLEServer* pServer = NULL;
BLECharacteristic* pCharacteristic = NULL;
bool deviceConnected = false;
bool oldDeviceConnected = false;
uint32_t value = 0;
boolean oldState = LOW;
// constants won't change. They're used here to set pin numbers:
const int BUTTON_PIN = 27; // the number of the pushbutton pin
// Variables will change:
int currentState; // the current reading from the input pin
// See the following for generating UUIDs:
// https://www.uuidgenerator.net/
#define SERVICE_UUID "4fdf794f-74dd-49be-a7fb-72c4236aa9b1"
#define CHARACTERISTIC_UUID "84017151-f16e-4206-a8a0-5e910f805200"
class MyServerCallbacks: public BLEServerCallbacks {
void onConnect(BLEServer* pServer) {
deviceConnected = true;
BLEDevice::startAdvertising();
};
void onDisconnect(BLEServer* pServer) {
deviceConnected = false;
}
};
void setup() {
//setCpuFrequencyMhz(80);
Serial.begin(115200);
// Create the BLE Device
BLEDevice::init("ESP32");
// Create the BLE Server
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,
BLECharacteristic::PROPERTY_READ |
BLECharacteristic::PROPERTY_WRITE |
BLECharacteristic::PROPERTY_NOTIFY |
BLECharacteristic::PROPERTY_INDICATE
);
// https://www.bluetooth.com/specifications/gatt/viewer?attributeXmlFile=org.bluetooth.descriptor.gatt.client_characteristic_configuration.xml
// Create a BLE Descriptor
pCharacteristic->addDescriptor(new BLE2902());
// Start the service
pService->start();
// Start advertising
BLEAdvertising *pAdvertising = BLEDevice::getAdvertising();
pAdvertising->addServiceUUID(SERVICE_UUID);
pAdvertising->setScanResponse(false);
pAdvertising->setMinPreferred(0x0); // set value to 0x00 to not advertise this parameter
BLEDevice::startAdvertising();
Serial.println("Waiting a client connection to notify...");
pinMode(BUTTON_PIN, INPUT);
}
void loop() {
boolean newState = digitalRead(BUTTON_PIN);
if (deviceConnected) {
if (newState != oldState) {
if (newState == LOW) {
value=0;
}
else {
value=1;
}
Serial.println(value);
pCharacteristic->setValue((uint8_t*)&value, 4);
pCharacteristic->notify();
delay(10);
}
oldState = newState;
delay(50);
}
}
Here is the loop that works when the state of the button is notified continuously:
void loop() {
currentState = digitalRead(BUTTON_PIN);
if(currentState == HIGH){ value=1;} else if(currentState == LOW){value=0;}
// notify changed value
if (deviceConnected) {
pCharacteristic->setValue((uint8_t*)&value, 4);
pCharacteristic->notify();
delay(10); // bluetooth stack will go into congestion, if too many packets are sent, in 6 hours test i was able to go as low as 3ms
}
delay(1000);
}
