- Terminologías relacionadas con BLE (Bluetooth Low Energy)
- Preparando el hardware
- Programación de ESP32 para indicación de nivel de batería mediante el servicio GATT
- Probando su servicio GATT en ESP32 BLE
Auriculares inalámbricos, bandas de fitness, parlantes Bluetooth, auriculares internos, teléfonos móviles, computadoras portátiles… hay tantos dispositivos Bluetooth a nuestro alrededor y la mayoría de estos dispositivos funcionan con baterías. ¿Alguna vez se ha preguntado que, cuando conecta un dispositivo Bluetooth a su teléfono móvil, cómo entiende automáticamente que el dispositivo conectado es una computadora, un dispositivo de audio o un teléfono móvil? Para algunos dispositivos, nuestro teléfono puede incluso mostrar automáticamente el porcentaje de batería del dispositivo conectado en la barra de notificaciones. ¿Cómo sucede todo esto por su cuenta? ¡Debe haber algún protocolo común compartido entre el teléfono y el dispositivo Bluetooth, verdad!
Mantén la curiosidad, obtendrás respuestas a estas preguntas a medida que intentemos entender Bluetooth Low Energy (BLE para abreviar), con el popular módulo ESP32. A diferencia del Bluetooth clásico en ESP32, el BLE funciona solo cuando se activa una comunicación y permanece en modo de suspensión; de lo contrario, esto lo convierte en la elección correcta para aplicaciones con batería. BLE también puede formar redes de malla y actuar como balizas. Normalmente un módulo BLE funciona como servidor o como cliente, aquí usaremos ESP32 BLE como servidor.
Aquí hemos dividido el ESP32 Bluetooth completo en tres segmentos para facilitar su comprensión.
1. Bluetooth serial en ESP32 alternando LED desde el teléfono móvil
2 . Servidor BLE para enviar datos de nivel de batería al teléfono móvil mediante el servicio GATT
3. Cliente BLE para buscar dispositivos BLE y actuar como baliza.
Ya hemos cubierto el primer artículo; En este artículo aprenderemos cómo hacer que el ESP32 BLE funcione como servidor y use el Servicio GATT para enviar información sobre el nivel de la batería. Para fines de prueba, enviaremos valores codificados desde ESP32 como porcentaje de batería a nuestro teléfono móvil a través del servicio BLE GATT, de esta manera nuestro móvil asumirá que ESP32 es un dispositivo Bluetooth que funciona con batería que está tratando de enviar a su porcentaje de batería. Antes de entrar en detalles, entenderemos algunas terminologías relacionadas con Bluetooth Low Energy.
Terminologías relacionadas con BLE (Bluetooth Low Energy)
Servidor BLE: Como se dijo anteriormente, el BLE se puede programar para que funcione como servidor o como cliente. Cuando funciona como servidor, el BLE solo puede proporcionar datos y no puede iniciar una conexión. Un ejemplo sería una banda de fitness. Un servidor puede enviar información solo si el cliente lo solicita.
Por lo general, el BLE del ESP32 se usa como servidor. Cada Servidor tendrá uno o más Servicios dentro de él y, de manera similar, cada servicio tendrá una o más características asociadas. Una Característica puede tener cero, uno o más de un Descriptor dentro. Cada servicio, característica o descriptor tendrá su propio ID único predefinido llamado UUID.
Cliente BLE: el cliente puede escanear, conectarse y escuchar otros dispositivos Bluetooth. Un ejemplo sería su teléfono móvil. Tenga en cuenta que la mayoría de los dispositivos de hardware BLE pueden funcionar como servidor y como cliente, es el software que decide la función del dispositivo.
Dispositivo periférico / Dispositivo central: En una red BLE podría haber solo un Dispositivo central, pero puede tener tantos dispositivos periféricos como sea necesario. El dispositivo central puede conectarse a todos los dispositivos periféricos al mismo tiempo, pero el dispositivo periférico puede conectarse solo al dispositivo central, de esta manera no hay dos dispositivos periféricos que puedan compartir datos entre sí. Un mejor ejemplo de dispositivo central serán nuestros teléfonos inteligentes y para dispositivos periféricos serán nuestros auriculares Bluetooth o bandas de fitness.
Publicidad BLE: Una publicidad BLE es el término geek que indica que el dispositivo Bluetooth debe ser visible para todos para que pueda emparejarse y establecer una conexión. Puede considerarse como una comunicación unidireccional. Aquí, el servidor sigue publicitando datos esperando que un servidor los reciba. BLE Beacon es un tipo de BLE.
UUID (Identificador único universal): cada dispositivo BLE Bluetooth recibe un Número de identificador único universal cuando lo programa el programador. Puede pensar en este identificador como una secuencia de números que representa la funcionalidad / función del dispositivo BLE. Nuevamente, hay dos tipos de UUID. Uno es el UUID del servicio y el otro es el UUID característico.
Servicio GATT: GATT son las siglas de Generic Attribute Profile; esto define algunas formas estándar mediante las cuales dos dispositivos BLE siempre deben comunicarse. Este protocolo de atributo (ATT) está predefinido y es común para todos los dispositivos BLE, por lo que de esta manera dos dispositivos BLE pueden identificarse entre sí. Por tanto, el GATT fue la respuesta a nuestra pregunta anterior.
La técnica mediante la cual dos dispositivos BLE deben enviar y recibir datos se define mediante el concepto denominado servicios y características.
Servicio BLE / Característica BLE: El UUID del Servicio nos dice qué tipo de servicio va a realizar el dispositivo BLE y el UUID Característico indica cuáles son los parámetros o funciones que realizará ese servicio. Entonces, cada Servicio tendrá una o más características debajo de ellos. ¡Bueno! ¿De dónde obtiene el programador este UUID? Cada UUID ya está definido por el GATT (Perfil de atributo genérico); puede visitar su sitio web y seleccionar el UUID según sea necesario para el proyecto. Sé que ha rebotado un poco sobre nuestra cabeza; intentemos entenderlo con un ejemplo.
Supongamos el dispositivo BLE de un reproductor de audio. Inicialmente, cuando lo empareja con su teléfono, su teléfono lo identifica como un dispositivo de audio y también muestra el nivel de batería en la barra de estado. Entonces, para que esto suceda, el reproductor de audio tiene que decirle a su teléfono de alguna manera que está dispuesto a compartir el nivel de batería y el porcentaje de carga que tiene. Esto se hace usando el UUID, hay un UUID específico que dice que el dado BLE proporcionará detalles sobre el nivel de la batería, este UUID que dice que el tipo de servicio se llama UUID de servicio, nuevamente , podría haber tantos parámetros que deben intercambiarse por completar un servicio como el valor de la batería está en dicho parámetro, cada parámetro tendrá su propio UUID y estos se denominan UUID característico.La función común que realiza una característica es Leer, Escribir, Notificar e Indicar.
Descriptor BLE: El descriptor es un atributo opcional que está presente dentro de la característica. Un descriptor normalmente especifica cómo acceder a una característica.
Baliza BLE: una baliza Bluetooth es más como un interruptor de proximidad que realiza una acción predefinida cuando el usuario se pone en un rango (proximidad cercana). Anuncia su identidad todo el tiempo y, por lo tanto, está siempre listo para emparejarse.
BLE2902: Todavía soy escéptico acerca de esto, pero puede pensar en ello como una pieza de software en el lado del cliente que le informa al servidor que active o desactive la notificación, esto nos ayudará a ahorrar energía
Espero que tengas una idea aproximada, lo bueno es que no necesitamos saber mucho ya que todo el trabajo manual ya está hecho por nosotros a través de las bibliotecas.
Preparando el hardware
El proyecto no requiere configuración de hardware, pero asegúrese de haber agregado los detalles de la placa ESP32 en su IDE de Arduino y haber probado el programa de parpadeo de muestra mínimo para verificar si todo funciona como se esperaba. Si es escéptico sobre cómo hacerlo, puede seguir el tutorial Introducción a ESP32 con Arduino para hacer lo mismo.
Además, para probar los servicios BLE usaremos la aplicación de Android nRF en nuestro móvil que se puede descargar directamente desde PlayStore. También está disponible en iTunes Store para usuarios de Iphone. Si planea trabajar con BLE durante mucho tiempo, esta aplicación será realmente útil para fines de depuración.
Programación de ESP32 para indicación de nivel de batería mediante el servicio GATT
En este momento, supongo que tiene una idea clara de qué servicio del GATT y cómo se implementa utilizando los modelos de servicio y características. Ahora, profundicemos en el programa para aprender cómo se implementa en ESP32 usando el IDE de Arduino. Antes de continuar, me gustaría usar este espacio para agradecer a Andreas Spiess por su video BLE que dejó las cosas muy claras de mi parte.
Comenzamos el programa importando las bibliotecas requeridas en nuestro boceto. Hay muchas cosas que configurar para usar la funcionalidad BLE de ESP32, con suerte, gracias a Neil Kolban, quien ya ha hecho el trabajo duro por nosotros y nos ha proporcionado las bibliotecas. Si desea comprender la funcionalidad de las bibliotecas, puede consultar su documentación en la página de github.
#incluir
A continuación, tenemos que definir la función de devolución de llamada del servidor para nuestro dispositivo Bluetooth. Antes de eso, entendamos qué es la función de devolución de llamada en BLE.
¿Qué es la función de devolución de llamada en BLE?
Cuando BLE funciona como servidor, es importante definir una función de devolución de llamada del servidor. Hay muchos tipos de devoluciones de llamada asociadas con BLE, pero en pocas palabras, las considera como un reconocimiento que se está realizando para asegurarse de que la acción se haya completado. Se utiliza una devolución de llamada del servidor para garantizar que la conexión entre el cliente y el servidor se establezca correctamente.
Usamos las siguientes líneas de código para realizar una devolución de llamada del servidor.
bool _BLEClientConnected = falso; class MyServerCallbacks : public BLEServerCallbacks { void onConnect (BLEServer * pServer) { _BLEClientConnected = true; }; void onDisconnect (BLEServer * pServer) { _BLEClientConnected = false; } };
Dentro de la función de configuración vacía , iniciamos la comunicación serial en 115200 para depurar y luego inicializamos el dispositivo Bluetooth a través de la función InitBLE .
configuración vacía () { Serial.begin (115200); Serial.println ("Indicador de nivel de batería - BLE"); InitBLE (); }
El initBLE es el lugar donde todo sucede la magia. Tenemos que crear un servidor Bluetooth y usar el servicio de nivel de batería aquí. Pero antes de eso tenemos que definir el UUID para Servicio, Característica y Descriptor para leer el Nivel de la batería. Todo el UUID se puede obtener en el sitio web del servicio Bluetooth GATT. En nuestro caso, estamos intentando utilizar el servicio de batería y el UUID se define como 0X180F como se muestra a continuación.
A continuación, necesitamos conocer la característica asociada a este servicio. Para saber eso, simplemente haga clic en Servicio de batería y será llevado a la página de Características del servicio, donde se menciona que el nivel de batería es el nombre de las características y toma el valor de 0 a 100. También tenga en cuenta que solo podemos realizar dos acciones con esta característica, una es Leer que es obligatorio hacer y la otra es Notificar que es Opcional. Así que tenemos que enviar el valor de la batería al cliente (teléfono) que es obligatorio y si es necesario podemos notificar al teléfono sobre cuál es opcional.
Pero espere, todavía no encontramos el valor UUID para el nivel de batería característico. Para hacer eso, ingrese a la página Características de la batería y busque el nombre del nivel de batería, encontrará su UUID como 0X2A19, la instantánea del mismo se muestra a continuación.
Ahora que tenemos todos los valores, pongamos el programa como se muestra a continuación. El nombre BatterySerivce , BatteryLevelCharacteristic y BatteryLevelDescriptor son variables definidas por el usuario para referirse al Servicio, característico y descriptores que estamos utilizando en el programa. El valor para el descriptor 0X2901 se utiliza cuando el tamaño del valor es de 8 bits; se puede encontrar más información en la página Descripción del descriptor.
#define BatteryService BLEUUID ((uint16_t) 0x180F)
BLECharacteristic BatteryLevelCharacteristic (BLEUUID ((uint16_t) 0x2A19), BLECharacteristic :: PROPERTY_READ - BLECharacteristic :: PROPERTY_NOTIFY); BLEDescriptor BatteryLevelDescriptor (BLEUUID ((uint16_t) 0x2901));
Volviendo a la función initBLE . Primero tenemos que iniciar el servidor BLE y hacer que se anuncie con un nombre. Las siguientes líneas se utilizan para iniciar el BLE como servidor. El nombre que le he dado a mi servidor BLe es “Batería BLE”, pero puedes elegir el tuyo.
BLEDevice:: init ("Batería BLE"); // Crea el servidor BLE BLEServer * pServer = BLEDevice:: createServer (); pServer-> setCallbacks (new MyServerCallbacks ());
A continuación, tenemos que iniciar el servicio GATT ya que ya hemos definido el UUID, simplemente podemos iniciar el servicio usando la línea a continuación.
// Crea el servicio BLE BLEService * pBattery = pServer-> createService (BatteryService);
Una vez iniciado el servicio podemos vincular el descriptor con las características y establecer los valores. El servicio BLE2902 también se agrega aquí como se muestra a continuación.
pBattery-> addCharacteristic (& BatteryLevelCharacteristic); BatteryLevelDescriptor.setValue ("Porcentaje 0 - 100"); BatteryLevelCharacteristic.addDescriptor (y BatteryLevelDescriptor); BatteryLevelCharacteristic.addDescriptor (nuevo BLE2902 ());
Finalmente todo está listo, ahora solo queda pedirle al ESP32 que anuncie para que otros dispositivos como nuestro teléfono puedan descubrirlo y conectarse a él, y cuando se conecte a un cliente debe iniciar el servicio de Batería que se puede hacer a través del siguientes líneas.
pServer-> getAdvertising () -> addServiceUUID (BatteryService); pBattery-> start (); // Iniciar publicidad pServer-> getAdvertising () -> start ();
Eso es hasta ahora todo bien, el último paso es decirle al descriptor cuál es el valor de la batería en porcentaje que debe enviarse al cliente (Teléfono). Este valor puede ser de 0 a 100 como leímos anteriormente, para simplificar las cosas, simplemente codifiqué el valor de la batería para que sea 57 y luego lo incremente cada 5 segundos y comience desde 0 una vez que llegue a 100. que se muestra a continuación. Tenga en cuenta que el valor que se envía tiene el formato unit8_t.
uint8_t nivel = 57; bucle vacío () { BatteryLevelCharacteristic.setValue (& nivel, 1); BatteryLevelCharacteristic.notify (); retraso (5000); nivel ++; Serial.println (int (nivel)); if (int (nivel) == 100) nivel = 0; }
Probando su servicio GATT en ESP32 BLE
El código completo explicado anteriormente se proporciona al final de la página. Sube el código a tu placa ESP32. Una vez cargado, su teléfono debería descubrir un dispositivo Bluetooth llamado "Batería BLE" Emparejar con él.
Luego instale la aplicación de Android nRF y ábrala y conéctese al dispositivo BLE Battery BLE. Expanda la sección Servicio de la batería y debería encontrar la siguiente pantalla.
Como puede ver, la Aplicación ha identificado automáticamente que el BLE brinda Servicio de Batería y tiene las características de Nivel de Batería debido al UUID que usamos en el programa. También puede ver que el valor actual de la batería que es del 67% espera 5 segundos y también puede notar que aumenta.
Lo bueno de usar BLE es que ahora cualquier aplicación que funcione con BLE pensará que su ESP32 es un dispositivo BLE que notifica el nivel de batería. Para probarlo, usé una aplicación llamada BatON y la aplicación identificó el ESP32 como un dispositivo Bluetooth alimentado por batería y dio la notificación de porcentaje en mi teléfono de esta manera
¡¡Frio!! ¿Correcto? También he mostrado el trabajo completo en el video a continuación. Ahora que ha aprendido a usar los servicios de batería BLE con ESP32, puede probar también otros servicios GATT que son muy interesantes como frecuencia de pulso, HID, frecuencia cardíaca, etc. Diviértase….