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

Hello friends,

I'll write in this topic about BLE on ESP32, send and receive text, with clock and without clock. Notify. I'll use the codes of Neil Kolban.

0.- Board D1 R32 ESP32.
This is a cheap card ($ 5) with the dimensions and shape of the Arduino UNO, but with the ESP32.

Search images: D1 R32 ESP32

This card has classic Bluetooth, BLE, WiFi, ADC, DAC, and more feature.

This card can be programmed with the Arduino IDE.

comparativa

There is another smaller ESP32 model.
Search images: D1 Mini ESP32

4 Likes

1.- Software.

---- Connection. Bare minimum.

p110i_esp32_ble_conexion.aia (199.5 KB)

  • This code is tested with an Android 9, the extension BLE 20201223 and an ESP32.
    If it doesn't work for you with that extension, try this ...
    Bluetooth bLE not connect

// http://kio4.com/arduino/160_Wemos_ESP32_BLE.htm

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

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

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

  pCharacteristic->setValue("Connected.");
  pService->start();

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

void loop() {
  // put your main code here, to run repeatedly:
}
2 Likes

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