BLE ESP32. Bluetooth. Send. Receive. Arduino IDE

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

RegisterForStrings also in the examples.

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

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);
}
}
1 Like

Hello Gianfranco

See below, June 1st, Notifications. You can use “Register for Strings” to receive data when it is available (every time it is available), rather than having to request it.

hmm, that cool

1 Like

Hi Juan

Take a look at this DIY UNO:
https://www.instructables.com/id/See-Through-Arduino-UNO/?
:star_struck:

Curious the Arduino Skeleton :bone:

ThankYouuu