|     Inicio    |   |         |  |   FOROS      |  |      |      
   Elastix - VoIP B4A (Basic4Android) App inventor 2 PHP - MySQL
  Estación meteorológica B4J (Basic4Java) ADB Shell - Android Arduino
  Raspberry Pi Visual Basic Script (VBS) FireBase (BD autoactualizable) NodeMCU como Arduino
  AutoIt (Programación) Visual Basic Cosas de Windows Webs interesantes
Translate:
Búsqueda en este sitio:


.

Tutorial del Internet de las Cosas y Bluetooth con el ESP32
Juan Antonio Villalpando

Volver al índice del tutorial

____________________________

160.- Bluetooth Low Energy. BLE. Librería. De AI2 a ESP32. De ESP32 a AI2.

_________________________________
- BLE. Librería.

- El módulo Wemos D1 R32 con el chip ESP32, tiene Bluetooth: v4.2 BR/EDR y Bluetooth Low Energy (BLE), así que lo podemos utilizar con el Bluetooth clásico 4.0 y con el BLE.

- En esta página podemos encontrar una extensión para que App Inventor pueda trabajar con BLE:

- http://iot.appinventor.mit.edu/#/bluetoothle/bluetoothleintro

- Aquí muestro distintas versiones de esta extensión, en estos tutoriales vamos a utilizar la 2019-06-27

BLE-with-new-ConnectDevice.aix (2019-06-27) (Si tienes problema con esta versión, utiliza la 20181124.) (mirror)

edu.mit.appinventor.ble-20181124.aix (20181124)

edu.mit.appinventor.ble.aix (20171109)

edu.mit.appinventor.BluetoothLE.aix (version 2)

- http://ai2.appinventor.mit.edu/reference/other/IoT.html

 

- Por otra parte me voy a basar en los ejemplos que podemos consultar en esta dirección:

https://github.com/nkolban/ESP32_BLE_Arduino/tree/7951347ed68313d75c367e1f2cce763cb56d1eb2

 

- Lo primero que tendría que hacer es bajar y descomprimir este archivo: ESP32_BLE.zip

- (Otra versión: ESP32_BLE_2.zip)

- Obtendremos la carpeta ESP32_BLE, copiamos esa carpeta en la carpeta ../Arduino/libraries/

- Puedes encontrar ejemplos en su carpeta examples.

________________________________________________________________

- NOTA: en estos ejemplos que vamos a realizar debemos tener en cuenta que a veces el MIT COMPANION no actualiza el Bluetooth cuando hacemos cambios en el código, así que si no obtienes en el listado el BLE de la tarjeta Wemos, desconecta la app del MIT COMPANION y vuélvela a conectar.

- Otra cosa importante es que cada vez que hagamos cambios en los códigos Deshabilitemos y Habilitemos el Bluetooth del móvil, para eso he puesto la extensión KIO4_Bluetooth.aix en estos ejemplos.

com.KIO4_Bluetooth.aix

- Si sigue sin funcionarte estos ejemplos, instala la aplicación en vez de utilizar el emulador de MIT Companion.

- En los ejemplos de Notificaciones he puesto:

- El bloque de solicitud de permisos.

- En Android 5 me ha funcionado mejor que en Android 9. A veces para que funcionara en Android 9 lo ejecutaba antes en Android 5 y después en Android 9.

- Para que funcione BLE, el móvil debe tener activado el permiso de Ubicación (Location)
https://stackoverflow.com/questions/33045581/location-needs-to-be-enabled-for-bluetooth-low-energy-scanning-on-android-6-0

https://stackoverflow.com/questions/33043582/bluetooth-low-energy-startscan-on-android-6-0-does-not-find-devices/33045489#33045489

- He puesto estos tutoriales en la Community de App Inventor:

https://community.appinventor.mit.edu/t/ble-esp32-bluetooth-send-receive-arduino-ide/1980

- Si instalamos una vieja versión de esta la extensión BLE y más tarde instalamos una nueva en la misma aplicación, puede ocurrir que se mantengan las dos extensiones, y cuando volvamos a abrir la aplicación los bloque salgan de forma atenuada como indico en la imagen:

- Para solucionarlo debemos exportar nuestra aplicación, abrirla con un compresor de archivos, como en Winrar, y Eliminar el com.google.appinventor.components.runtime.BluetoothLE y volver a cargar esta aplicación.

_________________________________
1.- Listado de BLE cercanos.

https://github.com/nkolban/ESP32_BLE_Arduino/tree/master/examples/BLE_scan

scan_ble.ino

/*
   Based on Neil Kolban example for IDF: 
https://github.com/nkolban/esp32-snippets/blob/master/cpp_utils/tests/BLE%20Tests/SampleScan.cpp
   Ported to Arduino ESP32 by Evandro Copercini
*/

#include <BLEDevice.h>
#include <BLEUtils.h>
#include <BLEScan.h>
#include <BLEAdvertisedDevice.h>

int scanTime = 30; //In seconds

class MyAdvertisedDeviceCallbacks: public BLEAdvertisedDeviceCallbacks {
    void onResult(BLEAdvertisedDevice advertisedDevice) {
      Serial.printf("Advertised Device: %s \n", advertisedDevice.toString().c_str());
    }
};

void setup() {
  Serial.begin(115200);
  Serial.println("Scanning...");

  BLEDevice::init("");
  BLEScan* pBLEScan = BLEDevice::getScan(); //create new scan
  pBLEScan->setAdvertisedDeviceCallbacks(new MyAdvertisedDeviceCallbacks());
  pBLEScan->setActiveScan(true); //active scan uses more power, but get results faster
  BLEScanResults foundDevices = pBLEScan->start(scanTime);
  Serial.print("Devices found: ");
  Serial.println(foundDevices.getCount());
  Serial.println("Scan done!");
}

void loop() {
  // put your main code here, to run repeatedly:
  delay(2000);
}

- BLE Scanner.

- Podemos ver los UUID con esta aplicación:

https://play.google.com/store/apps/details?id=com.macdom.ble.blescanner&hl=es

_________________________________
1B.- Conexión mínima.

p110_esp32_ble_enviar.aia

- Este es un código mínimo que solo trata de probar la conexión.

- Utiliza la extensión com.KIO4_Bluetooth.aix.

- Simplemente conecta e indica que el ESP32 está conectado.

- He utilizado Android 9 y la extensión BLE 20201223.

- Si no te funciona con esa extensión prueba con BLE-device-sort.aix que puedes encontrar en:
https://community.appinventor.mit.edu/t/bluetooth-ble-not-connect/22771/7

_________________________________
- Diseño.

_________________________________
- Bloques.

__________________________________
- Código para el ESP32.

conexion_ble.ino

// 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.- App Inventor envía información a la tarjeta mediante BLE. Monitor Serie.

p110_esp32_ble_enviar.aia

- App Inventor (Android) conecta por BLE con la tarjeta. Escribimos un mensaje y lo enviamos. La tarjeta tomará ese mensaje y lo presentará en el Monitor Serie.

- Este mensaje estará en las variables value y valor.

- Se presentará de varias forma, una mediante value y otra mediante el String valor en la parte del código de BLE.

- Además la variable valor se presentará cada 2 segundos mediante el bloque loop {}

_________________________________
- Diseño.

_________________________________
- Bloques.

- Observa los números de serviceUuid y characteristicUuid, están tomados del código que cargará en la tarjeta del ESP32.

_________________________________
- Código.

https://github.com/nkolban/ESP32_BLE_Arduino/tree/7951347ed68313d75c367e1f2cce763cb56d1eb2/examples/BLE_write

- Consulta el Monitor Serie.

ble_enviar.ino

/*
    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/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++){
          // 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.
}

_________________________________
3.- La tarjeta mediante BLE envía número aleatorio a App. Monitor Serie.

p110_esp32_ble_recibir.aia

- El código de la tarjeta crea un número aleatorio del 0 al 100. Lo convierte en String.

- Cuando pulsamos el Botón de "Recibir" en App Inventor, recibimos un número aleatorio y se muestra en una Etiqueta.

- Los números aleatorios son creados cada 2 segundos.

- He querido mantener tanto el código de App Inventor como el de la tarjeta Wemos del ejemplo anterior, así que simplemente he modificado esos dos códigos, algunas líneas no son necesarias. El bloque de lectura es ReadStrings.

- En este ejemplo he puesto un Reloj.

- Consulta el Monitor Serie.

_________________________________
- Diseño.

_________________________________
- Bloques.

- Observa los números de serviceUuid y characteristicUuid, están tomados del código que cargará en la tarjeta.

_________________________________
- Código.

https://github.com/nkolban/ESP32_BLE_Arduino/tree/7951347ed68313d75c367e1f2cce763cb56d1eb2/examples/BLE_write

- Observa cómo toma el dato: pCharacteristic->setValue(alea.c_str()); // Pone el numero aleatorio

ble_recibir.ino

/*
    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/160_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.
}

_________________________________
4.- BLE Server envía número aleatorio a App. Monitor Serie.

https://github.com/nkolban/ESP32_BLE_Arduino/tree/master/examples/BLE_server

p110_esp32_ble_server.aia

- Es un código similar al anterior, crea un número aleatorio del 0 al 100. Lo convierte en String.

- El Reloj de App Inventor chequea el valor de aleatorio cada 2 segundos.

- Observa el Monitor Serie.

_________________________________
- Diseño.

_________________________________
- Bloques.

_________________________________
- Código.

ble_server.ino

/*
    Based on Neil Kolban example for IDF: 
https://github.com/nkolban/esp32-snippets/blob/master/cpp_utils/tests/BLE%20Tests/SampleServer.cpp
    Ported to Arduino ESP32 by Evandro Copercini
*/
// Modificado por Juan Antonio Villalpando.
// 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"

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

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

void setup() {
  Serial.begin(115200);
  Serial.println("Starting BLE work!");

  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("Inicio.");
  pService->start();
  BLEAdvertising *pAdvertising = pServer->getAdvertising();
  pAdvertising->start();
  Serial.println("Characteristic defined! Now you can read it in your phone!");
}

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

_________________________________
5.- Sin Reloj. App Inventor envía un dato cualquiera. BLE reenvía un número aleatorio.

p110_esp32_ble_enviar_recibir.aia

- Observa que recibiremos una respuesta del módulo BLE y la tendremos en App Inventor sin utilizar el Reloj.

- Enviamos cualquier texto escrito en el CampoDeTexto al módulo BLE mediante "Envía información".

- Observaremos el texto enviado en el Monitor Serie.

- El módulo BLE genera un número aleatorio del 0 al 100, y nos lo devuelve. Se presenta en una Etiqueta.

_________________________________
- Diseño.

_________________________________
- Bloques.

_________________________________
- Código.

ble_envia_recibe.ino

// Modificado por Juan Antonio Villalpando.
// http://kio4.com/arduino/160_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
}

_________________________________
6.- Sin Reloj. App Inventor envía un dato. BLE reenvía un número aleatorio según el dato.

p110_esp32_ble_enviar_recibir.aia (es el mismo código que el anterior)

- Si escribimos "uno" en el CampoDeTexto, nos devolverá un número aleatorio del 1 al 50.
- Si escribimos "dos" en el CampoDeTexto, nos devolverá un número aleatorio del 100 al 200.
- Si escribimos "tres" en el CampoDeTexto, nos devolverá dos números aleatorios, ejemplo (34,148)

- Si escribimos otra palabra, nos devolverá esa palabra.

- Observa el Monitor Serie.

ble_envia_recibe.ino

// Modificado por Juan Antonio Villalpando.
// KIO4.COM

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

_________________________________
7.- Sin Reloj. App Inventor envía tres números para un LED tricolor. BLE devuelve el dato.

p110_esp32_ble_LED.aia

- App Inventor enviará tres números de la forma: 129,34,142 y se encenderá cada LED con esos valores de luminosidad.

- Se utilizará PWM.

- El ESP32 devolverá los mismos números recibidos: (129,34,142)

_________________________________
- Diseño.

_________________________________
- Bloques.

_________________________________
- Código.

- La librería del ESP32 que estoy utilizando no tiene la función analogWrite, para solventarlo instalo en el IDE una librería que funciona como analogWrite.

- Consulta esta información: 211_Wemos_analogWrite.htm

- Bajas este archivo, lo descomprimes y lo copias en la carpeta libraries de Arduino con el nombre: analogWrite

analogWrite.zip

- Para que los LED tengan más o menos iluminación se utiliza la técnica de PWM, esto lo hace directamente la librería analogWrite.

ble_led_tricolor.ino

// 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 rojo;
String verde;
String azul;
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(',');
        rojo = valor.substring(0, ind1);
        ind2 = valor.indexOf(',', ind1+1 );
        verde = valor.substring(ind1+1, ind2);
        ind3 = valor.indexOf(',', ind2+1 );
        azul = valor.substring(ind2+1);

        Serial.print("rojo = ");
        Serial.println(rojo);
        Serial.print("verde = ");
        Serial.println(verde);
        Serial.print("azul = ");
        Serial.println(azul);
        Serial.println();

      analogWrite(12, rojo.toInt());
      analogWrite(14, verde.toInt());
      analogWrite(27, azul.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() {
//
}

- En la aplicación anterior, prueba poner cambiar lo que indico en la siguiente imagen.

- Anula:

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

- Ahora al mover cualquiera de los Deslizadores se enviarán los datos.

_________________________________
8.- Sin Reloj. App Inventor apaga/enciende 3 LED. Obtiene el estado de los tres LED.

p110_esp32_ble_3LED.aia

- Conectamos 3 LED a los terminales 12, 14 y 27, pueden ser LED independientes, pero si tenemos un LED tricolor podemos conectarlo como está en la imagen.

- La App tendrá varios botones desde los cuales podemos encender y apagar cada uno de esos tres LED.

- Además también dispondrá de un botón para consultar el estado actual de los LED.

_________________________________
- Diseño.

_________________________________
- Bloques.

_________________________________
- Código.

ble_3led.ino

// 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 en terminal 12
#define LED14  14    // LED en terminal 14
#define LED27  27    // LED en terminal 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()); // Devuelve el valor.
  }
      }
    }
};

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() {
//
}

_________________________________
9.- Sin Reloj. App Inventor envía Bytes. Solicita respuesta. Los recibe. Ver Monitor Serie.

p110_esp32_ble_Bytes.aia

- La App envía los números decimales 97,109,105,101,111 como WriteBytes. Solicitando respuesta. WriteBytesWithResponse.

- El ESP32 los recibe y escribe su valor: amigo en el Monitor Serie.

- Lo convierte a bytes. También muestra esos valores binario en el Monitor Serie.

- Devuelve el valor recibido.

_________________________________
- Diseño.

_________________________________
- Bloques.

_________________________________
- Código.

ble_bytes.ino

// 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() {
//
}

_________________________________
_________________________________

- Ejemplos con Notificación.
__________________________________________________________________
10.- Mediante Registry y Notificación. El ESP32 envía números aleatorios.

p110_esp32_ble_notifica.aia

- En el ejemplo 4, vimos cómo el ESP32 generaba números aleatorios y App Inventor los recibía mediante el bloque ReadStrings y un Reloj. También debíamos utilizar el bloque WriteStrings para solicitarle la información.

- Ahora también el ESP32 va a generar números aleatorios, pero App Inventor los va a recibir de otra manera.

- Se utilizará el bloque RegisterForStrings, esta acción configurará a la extensión para que esté comprobando si hay un cambio de información recibida, sin utilizar el Reloj.

- El Bloque StringReceived, recibirá el valor enviado por el ESP32.

- El Reloj no es necesario en este código.

_________________________________
- Diseño.

_________________________________
- Bloques.

_________________________________
- Código.

- Basado en este código:

https://github.com/nkolban/ESP32_BLE_Arduino/blob/master/examples/BLE_notify/BLE_notify.ino

ble_notificacion.ino

/*
    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.
   The service advertises itself as: 4fafc201-1fb5-459e-8fcc-c5c9c331914b
   And has a characteristic of: beb5483e-36e1-4688-b7f5-ea07361b26a8
   The design of creating the BLE server is:
   1. Create a BLE Server
   2. Create a BLE Service
   3. Create a BLE Characteristic on the Service
   4. Create a BLE Descriptor on the characteristic
   5. Start the service.
   6. Start advertising.
   A connect hander associated with the server starts a background task that performs notification
   every couple of seconds.
*/

// Modificado por Juan A. Villalpando
// KIO4.COM

#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("ESP32");

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

  // Create the BLE Service
  BLEService *pService = pServer->createService(SERVICE_UUID);

  // Create a BLE Characteristic
  pCharacteristic = pService->createCharacteristic(
                      CHARACTERISTIC_UUID,
                      BLECharacteristic::PROPERTY_READ   |
                      BLECharacteristic::PROPERTY_WRITE  |
                      BLECharacteristic::PROPERTY_NOTIFY |
                      BLECharacteristic::PROPERTY_INDICATE
                    );

  // https://www.bluetooth.com/specifications/gatt/viewer?
  // attributeXmlFile=org.bluetooth.descriptor.gatt.client_characteristic_configuration.xml
  // Create a BLE Descriptor
  pCharacteristic->addDescriptor(new BLE2902());

  // Start the service
  pService->start();

  // Start advertising
  BLEAdvertising *pAdvertising = BLEDevice::getAdvertising();
  pAdvertising->addServiceUUID(SERVICE_UUID);
  pAdvertising->setScanResponse(false);
  pAdvertising->setMinPreferred(0x0);  // set value to 0x00 to not advertise this parameter
  BLEDevice::startAdvertising();
  Serial.println("Waiting a client connection to notify...");
}

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();
        value++;
        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;
    }
}

_________________________________
11.- Mediante Registry y Notificación. El ESP32 envía números aleatorios. App Inventor envía números con un Deslizador.

p110_esp32_ble_notifica_Deslizador.aia

- Este ejemplo es la unión del ejemplo anterior, el 7 y el 2.

- En el ejemplo 7 acabamos de ver que el ESP32 envía un número aleatorio y App Inventor lo recibe como Notificación (sin utilizar reloj)

- El ejemplo 2 trataba de enviar una información desde App Inventor al ESP32

- En este ejemplo la información enviada desde App Inventor al ESP32 será un número creado por un Deslizador.

- El envío del número de App Inventor al ESP32 por una parte, y el envío de aleatorio desde ESP32 a App Inventor son independientes.

- En este ejemplo el bloque RegisterForStrings lo he puesto dentro del evento Connected.

- Ese número se verá en forma de caracter en el Monitor Serie.

- He probado los códigos en Android 5 y Android 9, fue mejor en el Android 5.

_________________________________
- Diseño.

 

_________________________________
- Bloques.

- Observa que he puesto solicitud de permiso.

- También he utilizado mi extensión para Habilitar y Deshabilitar el Bluetooth del móvil.

_________________________________
- Código.

ble_notificacion.ino

/*
    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.
   The service advertises itself as: 4fafc201-1fb5-459e-8fcc-c5c9c331914b
   And has a characteristic of: beb5483e-36e1-4688-b7f5-ea07361b26a8
   The design of creating the BLE server is:
   1. Create a BLE Server
   2. Create a BLE Service
   3. Create a BLE Characteristic on the Service
   4. Create a BLE Descriptor on the characteristic
   5. Start the service.
   6. Start advertising.
   A connect hander associated with the server starts a background task that performs notification
   every couple of seconds.
*/

// Modificado por Juan A. Villalpando
// KIO4.COM

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

// 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;
    }
};

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

      if (value.length() > 0) {
        Serial.println("*********");
        Serial.print("New value: ");
        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.
        Serial.println("*********");
      }
    }
};
///////////////////////////////////////////////////

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

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

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

  // Create the BLE Service
  BLEService *pService = pServer->createService(SERVICE_UUID);

  // Create a BLE Characteristic
  pCharacteristic = pService->createCharacteristic(
                      CHARACTERISTIC_UUID,
                      BLECharacteristic::PROPERTY_READ   |
                      BLECharacteristic::PROPERTY_WRITE  |
                      BLECharacteristic::PROPERTY_NOTIFY |
                      BLECharacteristic::PROPERTY_INDICATE
                    );

  // https://www.bluetooth.com/specifications/gatt/viewer?
// attributeXmlFile=org.bluetooth.descriptor.gatt.client_characteristic_configuration.xml // Create a BLE Descriptor pCharacteristic->addDescriptor(new BLE2902()); // 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 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(); // value++; 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; } }

_________________________________
12.- Mediante Registry y Notificación. App Inventor envía números mediante un Deslizador y ESP32 le devuelve el doble de ese número.

p110_esp32_ble_notifica_Deslizador.aia (es la misma aplicación que la del ejemplo anterior)

- Mediante un Deslizador y el bloque WriteStrings, App Inventor envía un número del 1 al 100.

- Utilizamos el bloque RegisterForStrings, gracias a este bloque la aplicación está preparada para recibir un String por Bluetooth BLE sin necesidad de utilizar el Reloj.

- El código del ESP32 recibe el número y devuelve el doble del número recibido.

- Observarás que hay un pequeño retraso en el recibo del número.

- He probado los códigos en Android 5 y Android 9, fue mejor en el Android 5.

_________________________________
- Diseño.
(es la misma aplicación que la del ejemplo anterior)

_________________________________
- Bloques.
(es la misma aplicación que la del ejemplo anterior)

_________________________________
- Código.

ble_notificacion_envia_recibe_doble.ino

/*
    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. The service advertises itself as: 4fafc201-1fb5-459e-8fcc-c5c9c331914b And has a characteristic of: beb5483e-36e1-4688-b7f5-ea07361b26a8 The design of creating the BLE server is: 1. Create a BLE Server 2. Create a BLE Service 3. Create a BLE Characteristic on the Service 4. Create a BLE Descriptor on the characteristic 5. Start the service. 6. Start advertising. A connect hander associated with the server starts a background task that performs notification every couple of seconds. */ // Modificado por Juan A. Villalpando // KIO4.COM #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; // 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; } }; ////////////////////// WriteStrings ///////////////////////////// class MyCallbacks: public BLECharacteristicCallbacks { void onWrite(BLECharacteristic *pCharacteristic) { std::string value = pCharacteristic->getValue(); if (value.length() > 0) { Serial.println("*********"); Serial.print("New value: "); 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. Serial.println("*********"); } } }; /////////////////////////////////////////////////// void setup() { Serial.begin(115200); // Create the BLE Device BLEDevice::init("ESP32"); // Create the BLE Server pServer = BLEDevice::createServer(); pServer->setCallbacks(new MyServerCallbacks()); // Create the BLE Service BLEService *pService = pServer->createService(SERVICE_UUID); // Create a BLE Characteristic pCharacteristic = pService->createCharacteristic( CHARACTERISTIC_UUID, BLECharacteristic::PROPERTY_READ | BLECharacteristic::PROPERTY_WRITE | BLECharacteristic::PROPERTY_NOTIFY | BLECharacteristic::PROPERTY_INDICATE ); // https://www.bluetooth.com/specifications/gatt/viewer? // attributeXmlFile=org.bluetooth.descriptor.gatt.client_characteristic_configuration.xml // Create a BLE Descriptor pCharacteristic->addDescriptor(new BLE2902()); // 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(); // value++; 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; } }

_________________________________
13.- Mediante Registry y Notificación. ESP32 tiene un pulsador. Cuando lo pulsamos envía ALTO o BAJO a App Inventor.

p110_esp32_ble_notifica_Pulsador.aia

- Ponemos un pulsador en el terminal 12 del ESP32.

- Cuando lo pulsemos se encenderá el LED2. No es necesario conectar un LED externo ya que utilizaremos el LED de la placa que está conectado al terminal 2.

- Además de encender el LED2, enviará la palabra ALTO o BAJO a App Inventor. Lo enviará mediante Notificación, es decir no es necesario poner Reloj en App Inventor.

- En el Monitor Serie saldrá el estado actual del pulsador.

_________________________________
- Diseño.

_________________________________
- Bloques.

_________________________________
- Conexiones.

- No es necesario conectar un LED externo al terminal 2 ya que utilizaremos el LED azul integrado en la placa que está conectado al terminal 2.

- Por eso he puesto el rectángulo azul en D2.

_________________________________
- Código.

ble_notificacion_pulsador.ino

/*    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 // Al terminal 12 lo llamamos pin12. Aquí irá el pulsador.
#define pin2 2 // Al terminal 2 lo llamamos pin2. Aquí irá el LED.
int valor12; // Estado del potenciometro
String output ="BAJO"; // Salida de Notify.

BLEServer* pServer = NULL;
BLECharacteristic* pCharacteristic = NULL;
bool deviceConnected = false;
bool oldDeviceConnected = false;

// 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() {
pinMode(pin12, INPUT); // El pin12 será entrada. Pulsador.
pinMode(pin2, OUTPUT); // El pin2 será salida. LED.
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(output.c_str()); // Pone el numero aleatorio
      pCharacteristic->notify();
      
valor12 = digitalRead(pin12); // Lee el valor del pin12 y se lo asigna a valor12. (Puede ser 0 o 1)
if (valor12 == HIGH) { 
digitalWrite(pin2, HIGH); // Si valor12 es ALTO, pone el pin2 en ALTO
//Serial.println("Pulsado");
output ="ALTO";
} 

if (valor12 == LOW) { 
digitalWrite(pin2, LOW); // Si valor12 es BAJO, pone el pin2 en BAJO
//Serial.println("No Pulsado");
output ="BAJO";
} 
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("Disconecting. No hay dispositivo conectado. Habia un dispositivo anteriormente.");
        oldDeviceConnected = deviceConnected;
    }
    // connecting
    if (deviceConnected && !oldDeviceConnected) {
        // do stuff here on connecting
        Serial.println("Conecting. Hay dispositivo conectado. No habia otro dispositivo anteriormente.");
        oldDeviceConnected = deviceConnected;
        pServer->startAdvertising(); // restart advertising
    }
}

__________________________________________________
14.- Notificación. Ejemplo simple.

p110_esp32_ble_notifica.aia

https://openlabpro.com/guide/ble-notify-on-esp32-controller/

- Para Notificar cada cliente móvil debe tener un UUID distinto, podemos obtener UUID de:

https://www.uuidgenerator.net/

- Observa que en este código he cambiado el
#define CHARACTERISTIC_UUID "d6f841fa-a37d-11ea-bb37-0242ac130002"

ya que lo voy a utilizar con otro móvil. También debocambiar ese número en los Bloques de App Inventor.

ble_notificacion.ino

// 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.
//pCharacteristic->indicate(); 
value++; 
delay(800);
}
}

__________________________________________________
15.- Notificación. Dos móviles.

- Esto no me ha funcionado, se trata de crear dos números aleatorios, uno del 0 al 100 y otro del 200 al 300.

- Enviar el primero a un dispositivo mediante Notify y el segundo a otro dispositivo.

- Si un móvil está conectado al ESP32, el otro no lo reconoce.

- Si solo pongo el Android 9, funciona. Si solo pongo el Android 5.1 no funciona.

- Los dos no puedo conectarlos a la vez.

_________________________________
- Bloques.

_________________________________
- Bloques.

ble_notificacion.ino

// 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_1 "beb5483e-36e1-4688-b7f5-ea07361b26a8" // Meizu Android 5.1 
#define CHARACTERISTIC_UUID_2 "d6f841fa-a37d-11ea-bb37-0242ac130002" // Xiaomi Android 9

BLEServer* pServer = NULL;
BLECharacteristic* pCharacteristic1 = NULL;
BLECharacteristic* pCharacteristic2 = NULL;
bool deviceConnected = false;

String valor1 = "";
String valor2 = "";

// 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);
pCharacteristic1 = pService->createCharacteristic(
                      CHARACTERISTIC_UUID_1,
                      BLECharacteristic::PROPERTY_READ   |
                      BLECharacteristic::PROPERTY_WRITE  |
                      BLECharacteristic::PROPERTY_NOTIFY
                    );
pCharacteristic2 = pService->createCharacteristic(
                      CHARACTERISTIC_UUID_2,
                      BLECharacteristic::PROPERTY_READ   |
                      BLECharacteristic::PROPERTY_WRITE  |
                      BLECharacteristic::PROPERTY_NOTIFY
                    );
// BLE descriptor.                    
pCharacteristic1->addDescriptor(new BLE2902());
pCharacteristic2->addDescriptor(new BLE2902());

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

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

void loop() {
if (deviceConnected) { 
int aleatorio1 = random(1,100);
valor1 = (String) aleatorio1;
pCharacteristic1->setValue(valor1.c_str()); // Set value1.
pCharacteristic1->notify(CHARACTERISTIC_UUID_1); // Notify value1.

int aleatorio2 = random(200,300);
valor2 = (String) aleatorio2;
pCharacteristic2->setValue(valor2.c_str()); // Set value2.
pCharacteristic2->notify(CHARACTERISTIC_UUID_2); // Notify value2.

delay(800);
}
}

__________________________________________________
16.- Multitouch. Pulsar varias teclas a la vez.

p110i_esp32_ble_Multitouch.aia

- Multitouch consiste en pulsar varios Botones a la vez.

- Aquí he puesto un ejemplo, suponemos que tenemos 4 motores o 4 LEDs.

- Al pulsar los Botones se encenderán los LEDS y al dejar de pulsar se apagarán.

- Podemos pulsar varios botones a la vez.

_________________________________
- Diseño.

_________________________________
- Bloques.

_________________________________
- Código.

ble_multitouch.ino

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

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

String valor;
byte byte_received;
byte bytes;
#define LED12  12    // LED pin 12
#define LED14  14    // LED pin 14
#define LED27  27    // LED pin 27
#define LED16  16    // LED pin 16
String estado ="";
void motores();

#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];
        }
          byte_received = valor.charAt(0);
          Serial.print(byte_received);  
          Serial.print("    "); 
          
       /**  // print byte_received in byte, ejemplo: 00000110
            // Convert valor to bytes.
            for(int i=0; i<valor.length(); i++){
               char myChar = valor.charAt(i);
                for(int i=7; i>=0; i--){
                 bytes = bitRead(myChar,i);
                 Serial.print(bytes, BIN); // Binario
                }
                 Serial.println("");
            }
            */

motores();
pCharacteristic->setValue(estado.c_str()); // Return status
 }

    }
};

void setup() {
  pinMode(LED12, OUTPUT);
  pinMode(LED14, OUTPUT);
  pinMode(LED27, OUTPUT);
  pinMode(LED16, 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() {
//
}

void motores(){
if (bitRead(byte_received, 0)){digitalWrite(LED12,HIGH); Serial.print("Motor0: RUN  ");}
else {digitalWrite(LED12,LOW); Serial.print("Motor0: ---  ");}
if (bitRead(byte_received, 1)){digitalWrite(LED14,HIGH); Serial.print("Motor1: RUN  ");} 
else {digitalWrite(LED14,LOW); Serial.print("Motor1: ---  ");}
if (bitRead(byte_received, 2)){digitalWrite(LED27,HIGH); Serial.print("Motor2: RUN  ");} 
else {digitalWrite(LED27,LOW); Serial.print("Motor2: ---  ");}
if (bitRead(byte_received, 3)){digitalWrite(LED16,HIGH); Serial.print("Motor3: RUN  ");} 
else {digitalWrite(LED16,LOW); Serial.print("Motor3: ---  ");} 
Serial.println();
   estado ="";
   if (digitalRead(LED12) == HIGH) {estado = "Motor0: RUN,";} else {estado = "Motor0: ---,";}
   if (digitalRead(LED14) == HIGH) {estado = estado + "Motor1: RUN,";} else {estado = estado + "Motor1: ---,";}
   if (digitalRead(LED27) == HIGH) {estado = estado + "Motor2: RUN,";} else {estado = estado + "Motor2: ---";}
   if (digitalRead(LED16) == HIGH) {estado = estado + "Motor3: RUN";} else {estado = estado + "Motor3: ---";}
}

__________________________________________________
17.- Enviar un texto largo, de más de 20 caracteres. MTU.

p110i_esp32_ble_mtu.aia

- La extensión BLE envía los mensajes en paquetes de 20 bytes, esto se denomina MTU (Minimum Transmission Unit). El tamaño de estos paquetes se puede cambiar mediante el bloque RequestMTU, pero este cambio de tamaño habría que cambiarlo en el código de bloques y en el dispositivo.

- Vamos a ver un código para enviar un texto largo en paquetes de 20 bytes que se concatenarán en el código del ESP32, es decir se irán enviando paquetes de 20 bytes y se irán juntando en el código hasta obtener el texto completo.

- Enviaremos este texo:

La cigüeña voló a su nido.\nEl "Niño" provocó grandes inundaciones.\nEl señor Sánchez no es de Cádiz.\nThe stork flew to its nest.\nThe "Niño" caused great floods.\nMr. Sánchez is not from Cádiz.\n

- Cortaremos el textos en trozos de 15 caracteres, esto es porque los caracteres de idioma como la ü, ñ, ó, á, necesitan dos bytes, si enviamos

La cigüeña voló

- hemos cortado 15 caracteres, pero estamos enviando 18 bytes, ya que ü, ñ, ó necesitan 2 bytes. En realidad estamos enviando un paquete de 20 bytes, los 18 bytes indicados y 2 bytes más hasta completar los 20.

- Esos 15 caractes llegarán al ESP32 y mostrarán en el Monitor Serie mediante:

Serial.print(valor); // Presenta valor.

- Según vayan llegando esos paquetes se irán mostrando.

- Además en otra variable llamada valor_return se irán añadiendo todos los caracteres que vayan llegando.

- Cuando llegue el caracter "#", indicará que ha llegado el fin de texto y se devolverá todo el texto a la aplicación.

_________________________________
- Diseño.

_________________________________
- Bloques.

_________________________________
- Código.

ble_mtu.ino

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

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

String valor;
String valor_return = "";

#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); // Presenta valor.
        valor_return = valor_return + valor;
      }
      pCharacteristic->setValue(valor_return.c_str()); // Valor return.
      if(valor_return.indexOf("#") != -1){valor_return = "";}
    }

};

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());
  pService->start();

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

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

 

__________________________________________________
17B.- Enviar un texto largo, de más de 20 caracteres. MTU. El mismo ejemplo que acabamos de ver pero con un código más simplificado.

p110i_esp32_ble_mtu2.aia

- Esto es lo mismo que hemos visto en el ejemplo anterior pero con un código más simplificado.

- Enviamos los caracteres uno a uno.

_________________________________
- Bloques.

_________________________________
- Código.

ble_mtu2.ino

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

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

String valor;
String valor_return = "";

#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];          
        }
      valor_return = valor_return + valor;
     }
      pCharacteristic->setValue(valor_return.c_str()); // Valor return.
      if(valor_return.indexOf("#") != -1){Serial.print(valor_return); valor_return = "";}
    }
};

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());
  pService->start();

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

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

__________________________________________________
18.- La aplicación envia un número mediante un Deslizador. El ESP32 envía un número mediante el Monitor Serie. Notificación.

p110i_esp32_ble_notifica_Texto.aia

- La aplicación envía un valor mediante un Deslizador, al ESP32.

- El ESP32 envía el valor que escribimos en el Monitor Serie a la aplicación, mediante RegisterForStrings.

_________________________________
- Diseño.

_________________________________
- Bloques.

_________________________________
- Código.

ble_notifica.ino

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

__________________________________________________
19.- Dos ESP32 envían temperatura y humedad aleatorios a la aplicación. Deslizador común. Notificación.

p110i_esp32_ble_notifica_Two.aia

- Tenemos dos ESP32 con BLE. Cada uno genera un valor aleatorio de temperatura y humedad y lo notifica a la aplicación cada cierto tiempo aleatorio independiente.

- Además la aplicación envía mediante un Deslizador un número a los dos ESP32.

_________________________________
- Diseño.

_________________________________
- Bloques.

_________________________________
- Código para BLE1.

BLE1_notifica.ino

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

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

String valor;
long previousMillis_BLE1 = 0;
int interval_BLE1 = 1000;

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

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

  // Create the BLE1 Device
  BLEDevice::init("MyESP32_BLE1");

  // Create the BLE Server
  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() {
  unsigned long currentMillis = millis();

  if(currentMillis - previousMillis_BLE1 > interval_BLE1) {
  float TemperatureBLE1 = random(10,60000)/1000.0; // 3 decimals
  float HumidityBLE1 = random(5,99000)/1000.0;  // 3 decimals

  String temperatureBLE1 = String(TemperatureBLE1,3);
  String humidityBLE1 = String(HumidityBLE1,3);
  String tem_hum_BLE1 = temperatureBLE1 + "," + humidityBLE1;

      std::string value = pCharacteristic->getValue();
      pCharacteristic->setValue(tem_hum_BLE1.c_str()); // Notify.
      pCharacteristic->notify();
      
  previousMillis_BLE1 = currentMillis;     
  interval_BLE1 = random(500,1000);
  }
}

_________________________________
- Código para BLE2.

BLE2_notifica.ino

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

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

String valor;
long previousMillis_BLE2 = 0;
int interval_BLE2 = 1000;

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

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

  // Create the BLE2 Device
  BLEDevice::init("MyESP32_BLE2");

  // Create the BLE Server
  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() {
  unsigned long currentMillis = millis();

  if(currentMillis - previousMillis_BLE2 > interval_BLE2) {
  float TemperatureBLE2 = random(10,60000)/1000.0; // 3 decimals
  float HumidityBLE2 = random(5,99000)/1000.0;  // 3 decimals

  String temperatureBLE2 = String(TemperatureBLE2,3);
  String humidityBLE2 = String(HumidityBLE2,3);
  String tem_hum_BLE2 = temperatureBLE2 + "," + humidityBLE2;

      std::string value = pCharacteristic->getValue();
      pCharacteristic->setValue(tem_hum_BLE2.c_str()); // Notify.
      pCharacteristic->notify();
      
  previousMillis_BLE2 = currentMillis;     
  interval_BLE2 = random(500,2000);
  }
}

__________________________________________________
20.- ESP32 envía un número aleatorio mediante 4 Bytes.

p110_esp32_ble_notifica_byte.aia

_________________________________
- Diseño.

_________________________________
- Bloques.

BLE2_notifica_byte.ino

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

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

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

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

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

  // Create the BLE Server
  pServer = BLEDevice::createServer();
 
  // Create the BLE Service
  BLEService *pService = pServer->createService(SERVICE_UUID);

  // Create a BLE Characteristic
  pCharacteristic = pService->createCharacteristic(
                      CHARACTERISTIC_UUID,
                      BLECharacteristic::PROPERTY_NOTIFY
                    );

  // Start the service
  pService->start();

  // Start advertising
  BLEAdvertising *pAdvertising = BLEDevice::getAdvertising();
  pAdvertising->addServiceUUID(SERVICE_UUID);
  BLEDevice::startAdvertising();
}

void loop() {
    // notify changed value
      int aleatorio = random(1,99999); // Crea el numero aleatorio.
      String alea = (String) aleatorio; // Lo convierte en String.
     // pCharacteristic->setValue(alea.c_str()); // Envia STRING
      Serial.println(aleatorio);
      pCharacteristic->setValue((uint8_t*)&aleatorio, 4);  // Envia 4 BYTES
      pCharacteristic->notify();
      delay(500);
}

__________________________________________________
21.- ESP32 genera dos números aleatorios. App los recibe y cambia el color de etiquetas. Notificación.

p160_Wemos_ESP32_VUmeter.aia

- ESP32 crea dos números aleatorios y los envía cada cierto tiempo aleatorio.

Ejemplo: 4,9

- La aplicación obtiene esos valores mediante notificación, los separa

izq = 4
der = 9

y rellena el fondo de las Etiquetas según los valores obtenidos.

_________________________________
- Diseño.

_________________________________
- Bloques.

BLE2_notifica_string.ino

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

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

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

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

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

  // Create the BLE Server
  pServer = BLEDevice::createServer();
 
  // Create the BLE Service
  BLEService *pService = pServer->createService(SERVICE_UUID);

  // Create a BLE Characteristic
  pCharacteristic = pService->createCharacteristic(
                      CHARACTERISTIC_UUID,
                      BLECharacteristic::PROPERTY_NOTIFY
                    );

  // Start the service
  pService->start();

  // Start advertising
  BLEAdvertising *pAdvertising = BLEDevice::getAdvertising();
  pAdvertising->addServiceUUID(SERVICE_UUID);
  BLEDevice::startAdvertising();
}

void loop() {
    // notify changed value
      int izq = random(0,11); // Crea el numero aleatorio izq.
      int der = random(0,11); // Crea el numero aleatorio der.
      String alea = (String) izq + "," + (String) der; // Lo convierte en String.
      Serial.println(alea);
      pCharacteristic->setValue(alea.c_str()); // Envia STRING
      pCharacteristic->notify();
      int random_delay = random(500,2000);
      delay(random_delay);
}

 

______________________________________________
- Generador de UUID para BLE.

- Cada servicio, característica y descriptor tiene un UUID (Universally Unique Identifier). Un UUID es un número único de 16 bytes.

- Hay algunos UUID normalizados: SIG (Bluetooth Special Interest Group).

- Pero podemos crearnos unos UUID personales para nuestra aplicación: UUID generator.

_______________________________

- Mi correo:
juana1991@yahoo.com
- KIO4.COM - Política de cookies. Textos e imágenes propiedad del autor:
© Juan A. Villalpando
No se permite la copia de información ni imágenes.
Usamos cookies propias y de terceros que entre otras cosas recogen datos sobre sus hábitos de navegación y realizan análisis de uso de nuestro sitio.
Si continúa navegando consideramos que acepta su uso. Acepto    Más información