Hello,
Attached is the code I used.
It was only a test to prove that I was able to control the HUE.
I would appreciate if you share if it works for you, or if you find improvements.
In case I ever have time again to do further research on this topic.
Best regards
Code: Select all
/**
* A BLE client example that is rich in capabilities.
* There is a lot new capabilities implemented.
* author unknown
* updated by chegewara
*
* https://github.com/0015/ThatProject/blob/master/Esp32_BLE_to_BLE/ESP32_ble_client/ESP32_ble_client.ino
*
* mas o menos funciona en el sentido que aparentemente el ESP32 (CLIENT) se conecta con el HUE (SERVER)
* pero no puedo hacer nada en la version _2_HUE voy a intentar tener dos servicios cada uno con una caracteristica
*/
#include "BLEDevice.h"
////////////////////////////////////////////////////////////////////////
/* las siguientes 2 lineas añadidas para recibir comandos */
String Orden_Recibida;
long valor_numerico_Recibido;
////////////////////////////////////////////////////////////////////////
// The remote service we wish to connect to.
static BLEUUID serviceUUID("0000fe0f-0000-1000-8000-00805f9b34fb"); // cambiado del original
static BLEUUID serviceUUID_2("932c32bd-0000-47a2-835a-a8d455b859dd"); // cambiado del original SERVICIO donde esta la caraacterisctica de apagado y encendido
// The characteristic of the remote service we are interested in.
static BLEUUID charUUID("97fe6561-0003-4f62-86e9-b71ee2da3d22"); // segunda caracteristica del servicio anterior
static BLEUUID charUUID_2("932c32bd-0002-47a2-835a-a8d455b859dd"); // en esta caracteristica se puede apagar y encender la bombilla
static BLEUUID charUUID_3("932c32bd-0003-47a2-835a-a8d455b859dd"); // en esta caracteristica cambio el brillo
static boolean doConnect = false;
static boolean connected = false;
static boolean doScan = false;
static BLERemoteCharacteristic* pRemoteCharacteristic;
static BLERemoteCharacteristic* pRemoteCharacteristic_2; // apagado y encendido
static BLERemoteCharacteristic* pRemoteCharacteristic_3; // control del brillo
static BLEAdvertisedDevice* myDevice;
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);
Serial.print("data: ");
Serial.println((char*)pData);
}
class MyClientCallback : public BLEClientCallbacks {
void onConnect(BLEClient* pclient) {
}
void onDisconnect(BLEClient* pclient) {
connected = false;
Serial.println("onDisconnect");
}
};
bool connectToServer() {
Serial.print("Forming a connection to ");
Serial.println(myDevice->getAddress().toString().c_str());
BLEDevice::setEncryptionLevel(ESP_BLE_SEC_ENCRYPT); // añadido al original
BLEClient* pClient = BLEDevice::createClient();
Serial.println(" - Created client");
pClient->setClientCallbacks(new MyClientCallback());
// Connect to the remove BLE Server.
pClient->connect(myDevice); // if you pass BLEAdvertisedDevice instead of address, it will be recognized type of peer device address (public or private)
Serial.println(" - Connected to server");
// Obtain a reference to the service we are after in the remote BLE server.
BLERemoteService* pRemoteService = pClient->getService(serviceUUID);
if (pRemoteService == nullptr) {
Serial.print("Failed to find our service UUID: ");
Serial.println(serviceUUID.toString().c_str());
pClient->disconnect();
return false;
}
Serial.println(" - Found our service 1");
////busco un segundo servicio
BLERemoteService* pRemoteService_2 = pClient->getService(serviceUUID_2);
if (pRemoteService_2 == nullptr) {
Serial.print("Failed to find our service UUID_2: ");
Serial.println(serviceUUID.toString().c_str());
pClient->disconnect();
return false;
}
Serial.println(" - Found our service 2");
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// 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());
pClient->disconnect();
return false;
}
Serial.println(" - Found our characteristic 1");
//////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// encedido apagado
/// servicio 2 caracteristica 2
// Obtain a reference to the characteristic in the service of the remote BLE server.
pRemoteCharacteristic_2 = pRemoteService_2->getCharacteristic(charUUID_2);
if (pRemoteCharacteristic_2 == nullptr) {
Serial.print("Failed to find our characteristic UUID_2: ");
Serial.println(charUUID.toString().c_str());
pClient->disconnect();
return false;
}
Serial.println(" - Found our characteristic 2");
// Set the characteristic's value to be the array of bytes that is actually a string.
//pRemoteCharacteristic_2->writeValue("00",1);
//byte OFF1 = 0x00;
//pRemoteCharacteristic_2->writeValue(OFF1, sizeof(OFF1));
//////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// BRILLO
/// servicio 2 caracteristica 3
// Obtain a reference to the characteristic in the service of the remote BLE server.
pRemoteCharacteristic_3 = pRemoteService_2->getCharacteristic(charUUID_3);
if (pRemoteCharacteristic_3 == nullptr) {
Serial.print("Failed to find our characteristic UUID_3: ");
Serial.println(charUUID.toString().c_str());
pClient->disconnect();
return false;
}
Serial.println(" - Found our characteristic 3 (Brillo)");
// Set the characteristic's value to be the array of bytes that is actually a string.
// pRemoteCharacteristic_2->writeValue("00",1);
// byte Brillo_1 = 0x7F;
// pRemoteCharacteristic_3->writeValue(Brillo_1, sizeof(Brillo_1));
//////////////////////////////////////////////////////////////////////////////////////////////////////////////
connected = true;
}
/**
* Scan for BLE servers and find the first one that advertises the service we are looking for.
*/
class MyAdvertisedDeviceCallbacks: public BLEAdvertisedDeviceCallbacks {
/**
* Called for each advertising BLE server.
*/
void onResult(BLEAdvertisedDevice advertisedDevice) {
Serial.print("BLE Advertised Device found: ");
Serial.println(advertisedDevice.toString().c_str());
String currDevAddr = advertisedDevice.getAddress().toString().c_str();
Serial.print("BLE Advertised adress: ");
Serial.println(currDevAddr);
// We have found a device, let us now see if it contains the service we are looking for.
if (advertisedDevice.haveServiceUUID() && advertisedDevice.isAdvertisingService(serviceUUID)) {
BLEDevice::getScan()->stop();
myDevice = new BLEAdvertisedDevice(advertisedDevice);
doConnect = true;
doScan = true;
} // Found our server
} // onResult
}; // MyAdvertisedDeviceCallbacks
void setup() {
delay(5000);
Serial.begin(115200);
Serial.println("Starting Arduino BLE Client application...");
BLEDevice::init("");
// Retrieve a Scanner and set the callback we want to use to be informed when we
// have detected a new device. Specify that we want active scanning and start the
// scan to run for 5 seconds.
BLEScan* pBLEScan = BLEDevice::getScan();
pBLEScan->setAdvertisedDeviceCallbacks(new MyAdvertisedDeviceCallbacks());
pBLEScan->setInterval(1349);
pBLEScan->setWindow(449);
pBLEScan->setActiveScan(true);
pBLEScan->start(5, false);
} // End of setup.
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void convertidor_String_Char(String CadenaPruebas){
// parte A convierte un string en cadena de caracteres
int CadenaPruebas_len = CadenaPruebas.length() +1; // calcula la longitud de la cadena original
char str[CadenaPruebas_len];
CadenaPruebas.toCharArray(str, CadenaPruebas_len); // aqui queda el resultado
Serial.println(CadenaPruebas);
char *pch;
int i=0;
pch = strtok (str,";");
String buff[sizeof(str)];
while (pch != NULL)
{
buff[i]=(pch);
pch = strtok (NULL, ";");i++;
}
// una vez separado los almaceno en variables String
Orden_Recibida = buff[0];
String Valor_Recibido;
Valor_Recibido = buff[1];
valor_numerico_Recibido = Valor_Recibido.toInt(); //por ultimo genero un valor numerico del segundo trozo del string
}
////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////
// This is the Arduino main loop function.
void loop() {
// If the flag "doConnect" is true then we have scanned for and found the desired
// BLE Server with which we wish to connect. Now we connect to it. Once we are
// connected we set the connected flag to be true.
if (doConnect == true) {
if (connectToServer()) {
Serial.println("We are now connected to the BLE Server.");
} else {
Serial.println("We have failed to connect to the server; there is nothin more we will do.");
}
doConnect = false;
}
// If we are connected to a peer BLE Server, update the characteristic each time we are reached
// with the current time since boot.
if (connected) {
}else if(doScan){
BLEDevice::getScan()->start(0); // this is just eample to start scan after disconnect, most likely there is better way to do it in arduino
}
String command_recibido; // comando recibido desde monitor es el comando + valor separado por ;
String command;
String command_value;
int valor_command_value;
if(Serial.available()){
command_recibido = Serial.readStringUntil('\n');
Serial.printf("Command received %s \n", command_recibido);
convertidor_String_Char(command_recibido);
Serial.println( Orden_Recibida);
Serial.println(valor_numerico_Recibido);
byte valor_byte = 10;
command= Orden_Recibida;
if(command.equals("1")){
byte ON1 = 0x01;
pRemoteCharacteristic_2->writeValue(ON1, sizeof(ON1));
} else if(command.equals("0")){
byte OFF1 = 0x00;
pRemoteCharacteristic_2->writeValue(OFF1, sizeof(OFF1));
} else if(command.equals("b")){
byte brillo_Low_1 = 0x10;
pRemoteCharacteristic_3->writeValue(brillo_Low_1, sizeof(brillo_Low_1));
} else if(command.equals("a")){
byte brillo_High_1 = 0xfe;
pRemoteCharacteristic_3->writeValue(brillo_High_1, sizeof(brillo_High_1));
}
} // fin serial available
delay(1000); // Delay a second between loops.
} // End of loop