BLE ESP32. Bluetooth. Send. Receive. Arduino IDE. Multitouch

2.- App send text to ESP32. Show on the Serial Monitor.
p110i_esp32_ble_enviar.aia (220.5 KB)

  • Write and Send a text.
  • Texts are sent in packages of 20 characters.
  • Send: “El Ñandú corrió por Cádiz
  • Receive: “El Ñandú corrió p” = 17 chars + special chars: Ñ,ú,ó need 2 bytes.

/*
    Based on Neil Kolban example for IDF: 
https://github.com/nkolban/esp32-snippets/blob/master/cpp_utils/tests/BLE%20Tests/SampleWrite.cpp
    Ported to Arduino ESP32 by Evandro Copercini
*/
// Modificado por Juan Antonio Villalpando.
// http://kio4.com/arduino/160i_Wemos_ESP32_BLE.htm

#include <BLEDevice.h>
#include <BLEUtils.h>
#include <BLEServer.h>

String valor;

#define SERVICE_UUID        "4fafc201-1fb5-459e-8fcc-c5c9c331914b"
#define CHARACTERISTIC_UUID "beb5483e-36e1-4688-b7f5-ea07361b26a8"

class MyCallbacks: public BLECharacteristicCallbacks {
    void onWrite(BLECharacteristic *pCharacteristic) {
      std::string value = pCharacteristic->getValue();

      if (value.length() > 0) {
        valor = "";
        for (int i = 0; i < value.length(); i++){
          // Serial.print(value[i]); // Presenta value.
          valor = valor + value[i];
        }

        Serial.println("*********");
        Serial.print("valor = ");
        Serial.println(valor); // Presenta valor.
      }
    }
};

void setup() {
  Serial.begin(115200);

  BLEDevice::init("MyESP32");
  BLEServer *pServer = BLEDevice::createServer();
  BLEService *pService = pServer->createService(SERVICE_UUID);
  BLECharacteristic *pCharacteristic = pService->createCharacteristic(
                                         CHARACTERISTIC_UUID,
                                         BLECharacteristic::PROPERTY_READ |
                                         BLECharacteristic::PROPERTY_WRITE
                                       );

  pCharacteristic->setCallbacks(new MyCallbacks());
  pCharacteristic->setValue("Hello World");
  pService->start();

  BLEAdvertising *pAdvertising = pServer->getAdvertising();
  pAdvertising->start();
}

void loop() {
  // put your main code here, to run repeatedly:
  delay(2000);
   // Serial.println("valor en el loop = ");
   // Serial.println(valor); // Presenta valor.
}
  • The default Minimum Transmission Unit MTU is 20 bytes.
  • With block RequestMTU, I have been able to increase it to 22 bytes.
1 Like

3.- App sends text and receives random number. With Clock.
p110i_esp32_ble_recibir.aia (221.0 KB)

/*
    Based on Neil Kolban example for IDF: 
https://github.com/nkolban/esp32-snippets/blob/master/cpp_utils/tests/BLE%20Tests/SampleWrite.cpp
    Ported to Arduino ESP32 by Evandro Copercini
*/
// Modificado por Juan Antonio Villalpando.
// http://kio4.com/arduino/160i_Wemos_ESP32_BLE.htm

#include <BLEDevice.h>
#include <BLEUtils.h>
#include <BLEServer.h>

String valor;
int aleatorio;
String alea = "2";


#define SERVICE_UUID        "4fafc201-1fb5-459e-8fcc-c5c9c331914b"
#define CHARACTERISTIC_UUID "beb5483e-36e1-4688-b7f5-ea07361b26a8"

class MyCallbacks: public BLECharacteristicCallbacks {
    void onWrite(BLECharacteristic *pCharacteristic) {
      std::string value = pCharacteristic->getValue();
      pCharacteristic->setValue(alea.c_str()); // Pone el numero aleatorio

      if (value.length() > 0) {
        valor = "";
        for (int i = 0; i < value.length(); i++){
          // Serial.print(value[i]); // Presenta value.
          valor = valor + value[i];
        }

        Serial.println("*********");
        Serial.print("valor = ");
        Serial.println(valor); // Presenta valor.
      }
    }
};

void setup() {
  Serial.begin(115200);

  BLEDevice::init("MyESP32");
  BLEServer *pServer = BLEDevice::createServer();
  BLEService *pService = pServer->createService(SERVICE_UUID);
  BLECharacteristic *pCharacteristic = pService->createCharacteristic(
                                         CHARACTERISTIC_UUID,
                                         BLECharacteristic::PROPERTY_READ |
                                         BLECharacteristic::PROPERTY_WRITE
                                       );

  pCharacteristic->setCallbacks(new MyCallbacks());
  pCharacteristic->setValue("Iniciado.");
  pService->start();

  BLEAdvertising *pAdvertising = pServer->getAdvertising();
  pAdvertising->start();
}

void loop() {
  // put your main code here, to run repeatedly:
  delay(2000);
  //Serial.println("valor en el loop = ");
  //Serial.println(valor); // Presenta valor.
  aleatorio = random(1,100); // Crea el numero aleatorio.
  alea = (String) aleatorio; // Lo convierte en String.
}
2 Likes

4.- App sends text and receives random number. Without Clock.
p110i_esp32_ble_enviar_recibir.aia (220.9 KB)

// Modificado por Juan Antonio Villalpando.
// http://kio4.com/arduino/160i_Wemos_ESP32_BLE.htm

#include <BLEDevice.h>
#include <BLEUtils.h>
#include <BLEServer.h>

String valor;
int aleatorio;
String alea;

#define SERVICE_UUID        "4fafc201-1fb5-459e-8fcc-c5c9c331914b"
#define CHARACTERISTIC_UUID "beb5483e-36e1-4688-b7f5-ea07361b26a8"

class MyCallbacks: public BLECharacteristicCallbacks {
    void onWrite(BLECharacteristic *pCharacteristic) {
      std::string value = pCharacteristic->getValue();
      pCharacteristic->setValue(alea.c_str()); // Pone el numero aleatorio
      
	  if (value.length() > 0) {
        valor = "";
        for (int i = 0; i < value.length(); i++){
          // Serial.print(value[i]); // Presenta value.
          valor = valor + value[i];
        }

        Serial.println("*********");
        Serial.print("valor = ");
        Serial.println(valor); // Presenta valor.
      }
    }
};

void setup() {
  Serial.begin(115200);

  BLEDevice::init("MyESP32");
  BLEServer *pServer = BLEDevice::createServer();
  BLEService *pService = pServer->createService(SERVICE_UUID);
  BLECharacteristic *pCharacteristic = pService->createCharacteristic(
                                         CHARACTERISTIC_UUID,
                                         BLECharacteristic::PROPERTY_READ |
                                         BLECharacteristic::PROPERTY_WRITE
                                       );

  pCharacteristic->setCallbacks(new MyCallbacks());
  pCharacteristic->setValue("Iniciado.");
  pService->start();

  BLEAdvertising *pAdvertising = pServer->getAdvertising();
  pAdvertising->start();
}

void loop() {
  delay(1000);
  aleatorio = random(1,100); // Crea el numero aleatorio.
  alea = (String) aleatorio; // Lo convierte en String.aleatorio
}
1 Like

5.- App sends text and receives according to the text sent a random number. Without Clock.

  • The same application as the previous example: p110i_esp32_ble_enviar_recibir.aia (220.9 KB)

  • If send text: uno, receive a random number: 1…50

  • If send text: dos, receive a random number: 100…200

  • Ir send text: tres, receive two random numbers: (1…50,100…200)

// Modificado por Juan Antonio Villalpando.
// http://kio4.com/arduino/160i_Wemos_ESP32_BLE.htm

#include <BLEDevice.h>
#include <BLEUtils.h>
#include <BLEServer.h>

String valor;
int aleatorio1;
int aleatorio2;
String alea1;
String alea2;
String alea3;

#define SERVICE_UUID        "4fafc201-1fb5-459e-8fcc-c5c9c331914b"
#define CHARACTERISTIC_UUID "beb5483e-36e1-4688-b7f5-ea07361b26a8"

class MyCallbacks: public BLECharacteristicCallbacks {
    void onWrite(BLECharacteristic *pCharacteristic) {
      std::string value = pCharacteristic->getValue();
     
	  if (value.length() > 0) {
        valor = "";
        for (int i = 0; i < value.length(); i++){
          // Serial.print(value[i]); // Presenta value.
          valor = valor + value[i];
        }

        Serial.println("*********");
        Serial.print("valor = ");
        Serial.println(valor); // Presenta valor.
		
        if(valor == "uno") {
        pCharacteristic->setValue(alea1.c_str()); // Pone el numero aleatorio
          }
        if(valor == "dos") {
        pCharacteristic->setValue(alea2.c_str()); // Pone el numero aleatorio
          }
        if(valor == "tres") {
        pCharacteristic->setValue(alea3.c_str()); // Pone el numero aleatorio
          }
      }
    }
};

void setup() {
  Serial.begin(115200);

  BLEDevice::init("MyESP32");
  BLEServer *pServer = BLEDevice::createServer();
  BLEService *pService = pServer->createService(SERVICE_UUID);
  BLECharacteristic *pCharacteristic = pService->createCharacteristic(
                                         CHARACTERISTIC_UUID,
                                         BLECharacteristic::PROPERTY_READ |
                                         BLECharacteristic::PROPERTY_WRITE
                                       );

  pCharacteristic->setCallbacks(new MyCallbacks());
  pCharacteristic->setValue("Iniciado.");
  pService->start();

  BLEAdvertising *pAdvertising = pServer->getAdvertising();
  pAdvertising->start();
}

void loop() {
  delay(1000);
  aleatorio1 = random(1,50); // Crea el numero aleatorio.
  alea1 = (String) aleatorio1; // Lo convierte en String.aleatorio
  aleatorio2 = random(100,200); // Crea el numero aleatorio.
  alea2 = (String) aleatorio2; // Lo convierte en String.aleatorio
  alea3 = alea1 + "," + alea2;
       }

6.- ESP32 sends automatically (Notify) a random number to App.
p110i_esp32_ble_notifica.aia (220.6 KB)
The Bluetooth LE specification includes a mechanism known as notify that lets you know when data’s changed. When notify on a characteristic is enabled and the sender writes to it, the new value is automatically sent to the receiver, without the receiver explicitly issuing a read command. (Reference ArduinoBLE)

ESP32 code generates a random number every 500 milisecond and notifies (sends) it to the application.


/*
    Based on Neil Kolban example for IDF:
   https://github.com/nkolban/esp32-snippets/blob/master/cpp_utils/tests/BLE%20Tests/SampleNotify.cpp
   Ported to Arduino ESP32 by Evandro Copercini updated by chegewara
   Create a BLE server that, once we receive a connection, will send periodic notifications.
   A connect hander associated with the server starts a background task that performs notification
   every couple of seconds.
*/

// Modificado por Juan A. Villalpando
// http://kio4.com/arduino/160i_Wemos_ESP32_BLE.htm

#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;

// See the following for generating UUIDs:
// https://www.uuidgenerator.net/

#define SERVICE_UUID        "4fafc201-1fb5-459e-8fcc-c5c9c331914b"
#define CHARACTERISTIC_UUID "beb5483e-36e1-4688-b7f5-ea07361b26a8"


class MyServerCallbacks: public BLEServerCallbacks {
    void onConnect(BLEServer* pServer) {
      deviceConnected = true;
    };

    void onDisconnect(BLEServer* pServer) {
      deviceConnected = false;
    }
};

void setup() {
  Serial.begin(115200);

  // Create the BLE Device
  BLEDevice::init("MyESP32");

  // 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...");
}

void loop() {
    // notify changed value
    if (deviceConnected) {
       // pCharacteristic->setValue((uint8_t*)&value, 4);
        int aleatorio = random(1,100); // Crea el numero aleatorio.
        String alea = (String) aleatorio; // Lo convierte en String.
        pCharacteristic->setValue(alea.c_str()); // Pone el numero aleatorio
        pCharacteristic->notify();
        delay(500); // bluetooth stack will go into congestion, if too many packets are sent.
    }
    // disconnecting
    if (!deviceConnected && oldDeviceConnected) {
        delay(500); // give the bluetooth stack the chance to get things ready
        pServer->startAdvertising(); // restart advertising
        Serial.println("start advertising");
        oldDeviceConnected = deviceConnected;
    }
    // connecting
    if (deviceConnected && !oldDeviceConnected) {
        // do stuff here on connecting
        oldDeviceConnected = deviceConnected;
    }
}
2 Likes

That must have been a lot of work.
I don't see any use of the Register block in your examples.
I remember a thread

where having it made a difference.

7.- App sends a number by a Slider to ESP32. ESP32 return double. Notify.
p110i_esp32_ble_notifica_Deslizador.aia (221.1 KB)

/*
    Video: https://www.youtube.com/watch?v=oCMOYS71NIU
    Based on Neil Kolban example for IDF: 
    https://github.com/nkolban/esp32-snippets/blob/master/cpp_utils/tests/BLE%20Tests/SampleNotify.cpp
    Ported to Arduino ESP32 by Evandro Copercini
    updated by chegewara
   Create a BLE server that, once we receive a connection, will send periodic notifications.
   A connect hander associated with the server starts a background task that performs notification
   every couple of seconds.
*/

// Modificado por Juan A. Villalpando
// http://kio4.com/arduino/160i_Wemos_ESP32_BLE.htm

#include <BLEDevice.h>
#include <BLEServer.h>
#include <BLEUtils.h>
#include <BLE2902.h>

String valor;

BLEServer* pServer = NULL;
BLECharacteristic* pCharacteristic = NULL;
bool deviceConnected = false;
bool oldDeviceConnected = false;
//uint32_t value = 0;

#define SERVICE_UUID        "4fafc201-1fb5-459e-8fcc-c5c9c331914b"
#define CHARACTERISTIC_UUID "beb5483e-36e1-4688-b7f5-ea07361b26a8"

class MyServerCallbacks: public BLEServerCallbacks {
    void onConnect(BLEServer* pServer) {
      deviceConnected = true;
    };

    void onDisconnect(BLEServer* pServer) {
      deviceConnected = false;
    }
};

////////////////////// WriteStrings /////////////////////////////
class MyCallbacks: public BLECharacteristicCallbacks {
    void onWrite(BLECharacteristic *pCharacteristic) {
      std::string value = pCharacteristic->getValue();

      if (value.length() > 0) {
        valor = "";
        for (int i = 0; i < value.length(); i++){
          // Serial.print(value[i]); // Presenta value.
          valor = valor + value[i];
        }

        Serial.println("*********");
        Serial.print("valor = ");
        Serial.println(valor); // Presenta valor.
      }
    }
};
///////////////////////////////////////////////////

void setup() {
  Serial.begin(115200);

  // Create the BLE Device
  BLEDevice::init("MyESP32");

  // 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());
  // Esta línea es para el WriteStrings:
  pCharacteristic->setCallbacks(new MyCallbacks());

  // 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...");
}

void loop() {
    // notify changed value
    if (deviceConnected) {
          std::string value = pCharacteristic->getValue();
       // pCharacteristic->setValue((uint8_t*)&value, 4);
        int doble = valor.toInt() * 2 ;
        String doblado = (String) doble; // Lo convierte en String.
       
        pCharacteristic->setValue(doblado.c_str()); // Pone el numero doble
        pCharacteristic->notify();
        delay(5); // bluetooth stack will go into congestion, if too many packets are sent.
    }
    // disconnecting
    if (!deviceConnected && oldDeviceConnected) {
        delay(500); // give the bluetooth stack the chance to get things ready
        pServer->startAdvertising(); // restart advertising
        Serial.println("start advertising");
        oldDeviceConnected = deviceConnected;
    }
    // connecting
    if (deviceConnected && !oldDeviceConnected) {
        // do stuff here on connecting
        oldDeviceConnected = deviceConnected;
    }
}

Regards.
Juan Antonio Villalpando.

More information: http://kio4.com/arduino/160i_Wemos_ESP32_BLE.htm

1 Like

(This post was edited).
RegisterForStrings also in the examples.

7B.- App sends a number by a Slider to ESP32. ESP32 sends a number from Serial Monitor to app. Notify.

p110i_esp32_ble_notifica_Texto.aia (202.1 KB)


esp32_ble23

// Juan A. Villalpando
// http://kio4.com/arduino/160_Wemos_ESP32_BLE.htm

#include <BLEDevice.h>
#include <BLEUtils.h>
#include <BLEServer.h>

String valor;

BLEServer* pServer = NULL;
BLECharacteristic* pCharacteristic = NULL;

char char_received = '0';
String fromSerial = "";

#define SERVICE_UUID        "4fafc201-1fb5-459e-8fcc-c5c9c331914b"
#define CHARACTERISTIC_UUID "beb5483e-36e1-4688-b7f5-ea07361b26a8"

class MyCallbacks: public BLECharacteristicCallbacks {
    // RECEIVE NUMBER FROM APP (Slider).
    void onWrite(BLECharacteristic *pCharacteristic) {
      std::string value = pCharacteristic->getValue();
      
      if (value.length() > 0) {
        valor = "";
        for (int i = 0; i < value.length(); i++){
          valor = valor + value[i];          
        }
       Serial.println(valor); // Presenta valor.
     }
    }
};

void setup() {
  Serial.begin(115200);

  BLEDevice::init("MyESP32");
  pServer = BLEDevice::createServer();
  BLEService *pService = pServer->createService(SERVICE_UUID);
  pCharacteristic = pService->createCharacteristic(
                                         CHARACTERISTIC_UUID,
                                         BLECharacteristic::PROPERTY_READ |
                                         BLECharacteristic::PROPERTY_WRITE |
                                         BLECharacteristic::PROPERTY_NOTIFY |
                                         BLECharacteristic::PROPERTY_INDICATE
                                        );

  pCharacteristic->setCallbacks(new MyCallbacks());
  pService->start();

  BLEAdvertising *pAdvertising = pServer->getAdvertising();
  pAdvertising->start();
}

void loop() {
  // SEND NUMBER FROM SERIAL MONITOR TO APP.
  // Get number from Serial Monitor.
  if (Serial.available() > 0) { // ¿Hay algún caracter?
    char_received = Serial.read(); // Toma el caracter
    fromSerial += char_received;
    
    if (char_received == '\n') {
      std::string value = pCharacteristic->getValue();
      pCharacteristic->setValue(fromSerial.c_str()); // Notify fromSerial.
      pCharacteristic->notify();
      delay(5); 
      fromSerial = ""; 
    }
  }  
}
1 Like

I see them now, examples 6 & 7.
Sorry for the confusion!

Invaluable help Juan. A much needed guide.

1 Like

Juan,
This is great work! I am looking for a way to modify this so that instead of printing the result to the serial monitor it prints it to a 16x2 I2C LCD screen. I am able to get this working in part by adding lcd.print(valor); to the main loop, but of course then it just loops that text on the screen. What I would like to be able to do is to send a bit of text, have it stay on the screen until another string of text is sent. Could you point me in the right direction?

Thank you!

michael

Here a code with ESP32 working as classic Bluetooth and Screen LCD.

http://kio4.com/arduino/153_Wemos_Bluetooth_AI2_LCD.htm

1 Like

Sorry for the bother…
Is this a simple example for receive a command from Esp32 (or Arduino)?
I tried one.
I mean: We can turn on/off a led on Esp32 (Arduino) from cell phone.
But I am not able to turn on/off a “led” on cell phone from Esp32 (Arduino)…
I tried… But it works only if you repress on/off from cell phone…
So I am trying to make a simple app with a simple “ON” or “OFF” and in Esp32 (Arduino) building simple button… (simply writing on terminal)…
How do it???
“When BluetoothLE1.StringsReceived” doesn’t work…

Thanks

@}-,-’-------
Gianfranco

8.- PushButton in ESP2 sends HIGH/LOW to App Inventor. Notify.

p110_esp32_ble_notifica_Pulsador.aia (185.0 KB)

  • PushButton in pin12 of ESP32 sends “HIGH” or “LOW” to App Inventor by BLE Notify.

  • It also turns ON/OFF LED2 of the ESP32 (it is a LED_BUILTIN)



      /*    Based on Neil Kolban example for IDF:
         https://github.com/nkolban/esp32-snippets/blob/master/cpp_utils/tests/BLE%20Tests/SampleNotify.cpp
         Ported to Arduino ESP32 by Evandro Copercini updated by chegewara
         Create a BLE server that, once we receive a connection, will send periodic notifications.
         A connect hander associated with the server starts a background task that performs notification
         every couple of seconds. */
    
      // Modificado por Juan A. Villalpando
      // http://kio4.com/arduino/160i_Wemos_ESP32_BLE.htm
    
      #include <BLEDevice.h>
      #include <BLEServer.h>
      #include <BLEUtils.h>
      #include <BLE2902.h>
      #define pin12 12 //  pin12 PushButton
      #define pin2 2 //  pin2  LED2
      int valor12; // Status PushButton
      String output ="LOW"; // Output to App. Notify.
    
      BLEServer* pServer = NULL;
      BLECharacteristic* pCharacteristic = NULL;
      bool deviceConnected = false;
      bool oldDeviceConnected = false;
      uint32_t value = 0;
    
      #define SERVICE_UUID        "4fafc201-1fb5-459e-8fcc-c5c9c331914b"
      #define CHARACTERISTIC_UUID "beb5483e-36e1-4688-b7f5-ea07361b26a8"
    
      class MyServerCallbacks: public BLEServerCallbacks {
      void onConnect(BLEServer* pServer) {
        deviceConnected = true;
      };
    
      void onDisconnect(BLEServer* pServer) {
        deviceConnected = false;
      }
      };
    
      void setup() {
      pinMode(pin12, INPUT); // pin12 PushButton
      pinMode(pin2, OUTPUT); // pin2 LED2
      Serial.begin(115200);
    
        // Create the BLE Device
        BLEDevice::init("MyESP32");
    
        // 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
                      );
    
        // 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...");
      }
    
      void loop() {
      // notify changed value
      if (deviceConnected) {
        pCharacteristic->setValue(output.c_str()); // Output
        pCharacteristic->notify();
        
      valor12 = digitalRead(pin12); // Read  pin12 --> valor12. ( 0 or 1)
      if (valor12 == HIGH) { 
      digitalWrite(pin2, HIGH); // if valor12 is HIGH, set pin2 HIGH
      Serial.println("Pulsado");
      output ="HIGH"; // Notify HIGH
      } 
    
      if (valor12 == LOW) { 
      digitalWrite(pin2, LOW); // If valor12 is LOW, set pin2 LOW
      Serial.println("No Pulsado");
      output ="LOW"; // Notify LOW
      } 
      delay(100); // bluetooth stack will go into congestion, if too many packets are sent.       
      }
      // disconnecting
      if (!deviceConnected && oldDeviceConnected) {
          delay(500); // give the bluetooth stack the chance to get things ready
          pServer->startAdvertising(); // restart advertising
          Serial.println("start advertising");
          oldDeviceConnected = deviceConnected;
      }
      // connecting
      if (deviceConnected && !oldDeviceConnected) {
          // do stuff here on connecting
          oldDeviceConnected = deviceConnected;
      }
      }
1 Like

9.- App sends three values ​​for a tricolor LED RGB. Receive those same values.

p110i_esp32_ble_LED.aia (236.1 KB)


// Juan Antonio Villalpando.
// http://kio4.com/arduino/160_Wemos_ESP32_BLE.htm

#include <BLEDevice.h>
#include <BLEUtils.h>
#include <BLEServer.h>
#include <Arduino.h>
#include <analogWrite.h>

String valor;
String red;
String green;
String blue;
int ind1;
int ind2;
int ind3;


#define SERVICE_UUID        "4fafc201-1fb5-459e-8fcc-c5c9c331914b"
#define CHARACTERISTIC_UUID "beb5483e-36e1-4688-b7f5-ea07361b26a8"

class MyCallbacks: public BLECharacteristicCallbacks {
    void onWrite(BLECharacteristic *pCharacteristic) {
      std::string value = pCharacteristic->getValue();
      if (value.length() > 0) {
        valor = "";
        for (int i = 0; i < value.length(); i++){
          valor = valor + value[i];
        }

        Serial.print("valor = ");
        Serial.println(valor);
        ind1 = valor.indexOf(',');
        red = valor.substring(0, ind1);
        ind2 = valor.indexOf(',', ind1+1 );
        green = valor.substring(ind1+1, ind2);
        ind3 = valor.indexOf(',', ind2+1 );
        blue = valor.substring(ind2+1);

        Serial.print("red = ");
        Serial.println(red);
        Serial.print("green = ");
        Serial.println(green);
        Serial.print("blue = ");
        Serial.println(blue);
        Serial.println();

      analogWrite(12, red.toInt());
      analogWrite(14, green.toInt());
      analogWrite(27, blue.toInt());

      pCharacteristic->setValue(valor.c_str()); // Devuelve el valor.
      }
    }
};

void setup() {
  analogWriteResolution(12, 8); // Resolución 8 bits
  analogWriteResolution(14, 8);
  analogWriteResolution(27, 8);
  Serial.begin(115200);

  BLEDevice::init("MyESP32");
  BLEServer *pServer = BLEDevice::createServer();

  BLEService *pService = pServer->createService(SERVICE_UUID);

  BLECharacteristic *pCharacteristic = pService->createCharacteristic(
                                         CHARACTERISTIC_UUID,
                                         BLECharacteristic::PROPERTY_READ |
                                         BLECharacteristic::PROPERTY_WRITE
                                       );

  pCharacteristic->setCallbacks(new MyCallbacks());
  pCharacteristic->setValue("Iniciado.");
  pService->start();

  BLEAdvertising *pAdvertising = pServer->getAdvertising();
  pAdvertising->start();
}

void loop() {
//
}
1 Like

10.- From App ON/OFF 3 LEDs. Get status of the LEDs.

p110i_esp32_ble_3LED.aia (185.7 KB)

  • We can use independent LEDs, in my example I have used a tricolor LED.
  • Every time ON/OFF a LED we get a response.
  • When we press “Check status” we obtain the status of the three LEDs.

// Juan Antonio Villalpando.
// http://kio4.com/arduino/160_Wemos_ESP32_BLE.htm

#include <BLEDevice.h>
#include <BLEUtils.h>
#include <BLEServer.h>

String valor;
#define LED12  12    // LED pin 12
#define LED14  14    // LED pin 14
#define LED27  27    // LED pin 27
String estado ="";


#define SERVICE_UUID        "4fafc201-1fb5-459e-8fcc-c5c9c331914b"
#define CHARACTERISTIC_UUID "beb5483e-36e1-4688-b7f5-ea07361b26a8"

class MyCallbacks: public BLECharacteristicCallbacks {
    void onWrite(BLECharacteristic *pCharacteristic) {
      std::string value = pCharacteristic->getValue();
      if (value.length() > 0) {
        valor = "";
        for (int i = 0; i < value.length(); i++){
          valor = valor + value[i];
        }
 Serial.println(valor);
 if (valor == "on12") {digitalWrite(LED12,HIGH); pCharacteristic->setValue("LED12 ON");}
 if (valor == "off12"){digitalWrite(LED12,LOW);  pCharacteristic->setValue("LED12 OFF");}
 if (valor == "on14") {digitalWrite(LED14,HIGH); pCharacteristic->setValue("LED14 ON");}
 if (valor == "off14"){digitalWrite(LED14,LOW);  pCharacteristic->setValue("LED14 OFF");}
 if (valor == "on27") {digitalWrite(LED27,HIGH); pCharacteristic->setValue("LED27 ON");}
 if (valor == "off27"){digitalWrite(LED27,LOW);  pCharacteristic->setValue("LED27 OFF");}
 if (valor == "check"){
   estado ="";
   if (digitalRead(LED12) == HIGH) {estado = "LED12 ON,";} else {estado = "LED12 OFF,";}
   if (digitalRead(LED14) == HIGH) {estado = estado + "LED14 ON,";} else {estado = estado + "LED14 OFF,";}
   if (digitalRead(LED27) == HIGH) {estado = estado + "LED27 ON";} else {estado = estado + "LED27 OFF";}
   pCharacteristic->setValue(estado.c_str()); // Return status
  }
      }
    }
};

void setup() {
  pinMode(LED12, OUTPUT);
  pinMode(LED14, OUTPUT);
  pinMode(LED27, OUTPUT);
  Serial.begin(115200);

  BLEDevice::init("MyESP32");
  BLEServer *pServer = BLEDevice::createServer();

  BLEService *pService = pServer->createService(SERVICE_UUID);

  BLECharacteristic *pCharacteristic = pService->createCharacteristic(
                                         CHARACTERISTIC_UUID,
                                         BLECharacteristic::PROPERTY_READ |
                                         BLECharacteristic::PROPERTY_WRITE
                                       );

  pCharacteristic->setCallbacks(new MyCallbacks());
  pCharacteristic->setValue("Iniciado.");
  pService->start();

  BLEAdvertising *pAdvertising = pServer->getAdvertising();
  pAdvertising->start();
}

void loop() {
//
}
1 Like

11.- App sends Bytes by WriteBytesWithResponse.

p110i_esp32_ble_Bytes.aia (184.3 KB)

  • App sends list of Bytes as decimal numbers: 97,109,105,103,111 (ASCII: a,m,i,g,o)
  • ESP32 receives those bytes and converts them to binaries:
    01100001
    01101101
    01101001
    01100111
    01101111
  • Return values as list.

// Juan Antonio Villalpando.
// http://kio4.com/arduino/160_Wemos_ESP32_BLE.htm

#include <BLEDevice.h>
#include <BLEUtils.h>
#include <BLEServer.h>

String valor;

#define SERVICE_UUID        "4fafc201-1fb5-459e-8fcc-c5c9c331914b"
#define CHARACTERISTIC_UUID "beb5483e-36e1-4688-b7f5-ea07361b26a8"

class MyCallbacks: public BLECharacteristicCallbacks {
    void onWrite(BLECharacteristic *pCharacteristic) {
      std::string value = pCharacteristic->getValue();
      if (value.length() > 0) {
        valor = "";
        for (int i = 0; i < value.length(); i++){
          valor = valor + value[i];
        }
           Serial.println(valor);
            // Convert valor to bytes.
            for(int i=0; i<valor.length(); i++){
               char myChar = valor.charAt(i);
                for(int i=7; i>=0; i--){
                  byte bytes = bitRead(myChar,i);
                  Serial.print(bytes, BIN);
                }
                 Serial.println("");
            }
 
   pCharacteristic->setValue(valor.c_str()); // Return valor
      }
    }
};

void setup() {
  Serial.begin(115200);

  BLEDevice::init("MyESP32");
  BLEServer *pServer = BLEDevice::createServer();

  BLEService *pService = pServer->createService(SERVICE_UUID);

  BLECharacteristic *pCharacteristic = pService->createCharacteristic(
                                         CHARACTERISTIC_UUID,
                                         BLECharacteristic::PROPERTY_READ |
                                         BLECharacteristic::PROPERTY_WRITE
                                       );

  pCharacteristic->setCallbacks(new MyCallbacks());
  pCharacteristic->setValue("Iniciado.");
  pService->start();

  BLEAdvertising *pAdvertising = pServer->getAdvertising();
  pAdvertising->start();
}

void loop() {
//
}

Check Serial Monitor:

This tutorial in Spanish.

1 Like

@Juan_Antonio, I’m getting started with esp32 BLE connection and MIT app inventor. I don’t know what is happening, but I got this error when I try to use any off the apps. Can someone help me?
Note: I’m just copying and pasting both code and app

Location needs to be enabled for Bluetooth Low Energy Scanning.

Use ESP32_BLE.zip library in this page:
http://kio4.com/arduino/160_Wemos_ESP32_BLE.htm

You can Scan UUID with this app:

12.- Notify. Simple and didactic example.

Important: each mobile device must have a CHARACTERISTIC_UUID. If you have multiple mobiles, set a CHARACTERISTIC_UUID for each one. You can generate UUID: https://www.uuidgenerator.net/

// Modified Juan A. Villalpando.
// http://kio4.com/arduino/160_Wemos_ESP32_BLE.htm			
			
#include <BLEDevice.h>
#include <BLEServer.h>
#include <BLEUtils.h>
#include <BLE2902.h>

// Each client, mobile with a CHARACTERISTIC_UUID.
// Generate UUID: https://www.uuidgenerator.net/
#define SERVICE_UUID "4fafc201-1fb5-459e-8fcc-c5c9c331914b"
//#define CHARACTERISTIC_UUID "beb5483e-36e1-4688-b7f5-ea07361b26a8"
  #define CHARACTERISTIC_UUID "d6f841fa-a37d-11ea-bb37-0242ac130002"

BLEServer* pServer = NULL;
BLECharacteristic* pCharacteristic = NULL;
bool deviceConnected = false;
int value = 0;
String valor = "";

// These functions will detect when the device is connected or disconnected.
class MyServerCallbacks: public BLEServerCallbacks {
    void onConnect(BLEServer* pServer) {
      deviceConnected = true;
    }; 
    void onDisconnect(BLEServer* pServer) {
      deviceConnected = false;
    }
};

void setup() {
Serial.begin(115200);
BLEDevice::init("MyESP32");

// Create BLE Server.
BLEServer *pServer = BLEDevice::createServer();
pServer->setCallbacks(new MyServerCallbacks());

// Create BLE Service with properties READ, WRITE, NOTIFY, INDICATE
BLEService *pService = pServer->createService(SERVICE_UUID);
pCharacteristic = pService->createCharacteristic(
                      CHARACTERISTIC_UUID,
                      BLECharacteristic::PROPERTY_READ   |
                      BLECharacteristic::PROPERTY_WRITE  |
                      BLECharacteristic::PROPERTY_NOTIFY |
                      BLECharacteristic::PROPERTY_INDICATE
                    );
// BLE descriptor.                    
pCharacteristic->addDescriptor(new BLE2902());

// Start BLE service.
pService->start();

// Start BLE advertising.
pServer->getAdvertising()->start(); 
}  

void loop() {
if (deviceConnected) { 
Serial.printf("*** NOTIFY: %d ***\n", value);
valor = (String) value;
pCharacteristic->setValue(valor.c_str()); // Set value.
pCharacteristic->notify();                // Notify value.
//pCharacteristic->indicate(); 
value++; 
delay(800);
}
}
2 Likes