Desde el principio tenía en mente que quería utilizar Bluetooth BLE. Es moderno, muy flexible, de bajo consumo y ampliamente usado en dispositivos IoT. Con flexibilidad me refiero a que BLE simplifica enormemente el proceso de descubrimiento de carácteristicas y facilita la conexión y reconexión con el dispositivo.
BLE describe una jerarquía de estructuras de datos estándar que permiten descubrir información sobre el dispositivo de manera automática facilitando la independencia entre la aplicación cliente y servidor. En la imagen inferior se puede ver como se estructura la jerarquía. Cada dispositivo está representado como un perfil con información básica sobre el dispositivo como puede ser el nombre público. Dentro del perfil se declaran lo que se conoce como servicios que agrupan características similares o el comportamiento de una parte del dispositivo. Las características son atributos con un único valor que por estándar pueden ser configurados para ser, o bien leidos por el cliente, escritos, o permiten la subscripción para ser notificados cuando el valor cambia. Como ejemplo tenemos el servicio de información de dispositivo en el que se incluyen las características nombre de dispositivo, número de serie, versión de software,...
Para los servicios ofrecidos buscaba realizar una interfaz lo más estándar posible para permitir que otro tipo de aplicaciones mostráran datos en el sistema. El problema es, que en la web de Bluetooth donde se describen todos los estándares sobre BLE (https://www.bluetooth.com/specifications/gatt/services), no hay ningún servicio que cubra o se parezca a las necesidades de la aplicación. El único servicio estándar que he usado ha sido el de información del dispositivo en el que muestro las características nombre e ID. Quedando el servicio final:
Como se puede ver las características se recogen bajo el mismo servicio dado que ofrecen información del dispositivo y por tanto, realizan la misma función.
Para la aplicación lo que se va a mostrar es la orientación, velocidad y distancia. Por tanto para la interfaz Bluetooth necesitamos 3 características:
Dado que el display es una matrix de leds 8x8 los valores mostrados tienen límites, la velocidad tiene un rango de 0-99 y la distancia un rango de 0-199. La orientación hace referencia a ángulo de diferencia respecto al norte en sentido antihorario. Dado que el rango de 8bits es de 0-255 y los ángulos tienen un rango de 0-359 lo que se hace es mapear el rango 0-359 en el rango 0-255 dado que no conlleva una perdida significativa en la precisión si tenemos en cuenta la visualización.
Para la implementación se ha usado una serie de utilidades C++ del usuario nkolban de github. Dentro del repositorio https://github.com/nkolban/esp32-snippets nos descargamos la carpeta "cpp_utils" esta carpeta la copiaremos en una nueva carpeta llamada components en el directorio raiz del proyecto.
Estas utilidades permiten crear los distintos servicios BLE de manera muy sencilla, debajo tenemos el código necesario para crear el servicio de información de dispositivo. Dado que son características de lectura basta con asignar un valor al inicio y el servicio por sí mismo atendera las peticiones recibidas.
A la hora de recibir datos de un cliente se añaden calbacks que reciben los valores deseados. Debajo se muestra el calback necesario para recibir la velocidad de parte del usuario.