{"id":238920,"date":"2022-01-20T22:26:44","date_gmt":"2022-01-20T21:26:44","guid":{"rendered":"https:\/\/emariete.com\/?p=238920"},"modified":"2022-01-20T22:26:44","modified_gmt":"2022-01-20T21:26:44","slug":"gateway-espnow-mqtt","status":"publish","type":"post","link":"https:\/\/emariete.com\/en\/gateway-espnow-mqtt\/","title":{"rendered":"Gateway ESPNOW to MQTT over WiFi"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\"><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Te traigo mi proyecto de Gateway ESPNOW a MQTT bidireccional con todas las explicaciones necesarias para que puedas utilizar el firmware que he escrito para ESP32 para tu propio uso f\u00e1cilmente.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Un Gateway sencillo que te permite recibir las se\u00f1ales enviadas por diferentes dispositivos con ESPNOW y <strong>reenviarlas mediante WiFi como mensajes MQTT<\/strong>.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Desarroll\u00e9 este Gateway ESPNOW porque tengo varios proyectos con ESP8266 y ESP32 y funcionamiento con bater\u00edas, como por ejemplo <a href=\"https:\/\/emariete.com\/medidor-co2-gadget\/\">CO2 Gadget<\/a>, en los que utilizo el protocolo ESP-NOW para <strong>reducir el consumo de bater\u00eda y aumentar la autonom\u00eda y el alcance.<\/strong><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Una de las ventajas de este proyecto es que utiliza <strong>un solo ESP32<\/strong> tanto para ESPNOW como para  WiFi . En muchos sitios dicen que no es posible utilizar ESPNow y WiFi simult\u00e1neamente y utilizan dos ESP32 conectados a trav\u00e9s de puerto serie, uno para ESPNow y otro para  WiFi, pero yo <strong>lo llevo haciendo desde hace varios meses con un solo ESP32 sin ning\u00fan problema<\/strong>.<\/p>\n\n\n\n<div class=\"wp-block-group has-global-color-8-background-color has-background\"><div class=\"wp-block-group__inner-container is-layout-flow wp-block-group-is-layout-flow\">\n<p class=\"wp-block-paragraph\"><strong>EL FIRMWARE DEL GATEWAY ESPNOW EST\u00c1 EN PREPARACI\u00d3N<\/strong><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">El firmware del Gateway ESPNOW estar\u00e1 disponible pronto. Sigo trabajando en \u00e9l, para que cualquier persona lo pueda utilizar con <a href=\"https:\/\/emariete.com\/medidor-co2-gadget\/\">CO2 Gadget, y<\/a> todav\u00eda est\u00e1 recibiendo muchos cambios y funcionalidades.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Si quieres participar en su beta testing, d\u00edmelo a trav\u00e9s del <a href=\"https:\/\/t.me\/emariete_chat\" target=\"_blank\" rel=\"noreferrer noopener nofollow\">grupo de Telegram<\/a>.<\/p>\n<\/div><\/div>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"h-qu-es-esp-now\">\u00bfQu\u00e9 es ESP-NOW?<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">ESP-NOW es <strong>un protocolo de comunicaciones v\u00eda radio<\/strong> que soportan los ESP8266 y ESP32, desarrollado por Espressif, su fabricante, que permite hacer <strong>transmisiones de datos muy r\u00e1pidas<\/strong> (y cuando digo muy r\u00e1pidas, digo rapid\u00edsimas).<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Su principal objetivo es sustituir al Wifi para permitir consumos de energ\u00eda mucho m\u00e1s bajos y con ello mayor autonom\u00eda en dispositivos que funcionan con bater\u00eda al permitir el env\u00edo de datos en pocos milisegundos, en lugar de los varios segundos (de 3 a 12 segundos) que se emplear\u00edan en realizarlas con Wifi.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Adem\u00e1s de su velocidad hay otro \u00e1mbito donde sobresale, y es en el alcance que proporciona. Donde una comunicaci\u00f3n wifi puede tener un alcance de 25 a 100 metros, con ESP-NOW podemos obtener f\u00e1cilmente <strong>entre 100 y 500 metros de alcance<\/strong>, e incluso m\u00e1s, dependiendo de las condiciones tanto en un caso como en otro.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Si no conoces ESPNOW te recomiendo que leas primero el siguiente art\u00edculo en el que te cuento lo que debes saber sobre \u00e9l:<\/p>\n\n\n\n<figure class=\"wp-block-embed is-type-wp-embed is-provider-emariete wp-block-embed-emariete\"><div class=\"wp-block-embed__wrapper\">\n<blockquote class=\"wp-embedded-content\" data-secret=\"UCNAFXZjLq\"><a href=\"https:\/\/emariete.com\/esp8266-esp32-espnow\/\">Comunicaci\u00f3n v\u00eda radio para ESP8266 y ESP32 con ESPNOW<\/a><\/blockquote><iframe loading=\"lazy\" class=\"wp-embedded-content\" sandbox=\"allow-scripts\" security=\"restricted\" style=\"position: absolute; clip: rect(1px, 1px, 1px, 1px);\" title=\"\u00abComunicaci\u00f3n v\u00eda radio para ESP8266 y ESP32 con ESPNOW\u00bb \u2014 eMariete\" src=\"https:\/\/emariete.com\/esp8266-esp32-espnow\/embed\/#?secret=sqG2c2KZjU#?secret=UCNAFXZjLq\" data-secret=\"UCNAFXZjLq\" width=\"600\" height=\"338\" frameborder=\"0\" marginwidth=\"0\" marginheight=\"0\" scrolling=\"no\"><\/iframe>\n<\/div><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"h-puesta-en-marcha-del-gateway-esp-now-a-mqtt\">Puesta en marcha del gateway ESP-NOW a MQTT<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Poner en marcha el Gateway ESP-NOW te resultar\u00e1 muy sencillo siguiendo estas instrucciones.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Primero te explicar\u00e9 lo b\u00e1sico para que pongas el gateway en marcha y despu\u00e9s te voy a comentar varias partes del c\u00f3digo para que puedas <strong>adaptarlo a tus necesidades<\/strong> f\u00e1cilmente.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">B\u00e1sicamente, la puesta en marcha del gateway consiste en seguir los siguientes pasos:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>Conseguir el c\u00f3digo fuente del gateway<\/li><li>Editar un fichero de texto con la configuraci\u00f3n de tu red<\/li><li>Grabar el firmware en el ESP32 <\/li><\/ul>\n\n\n\n<p class=\"has-global-color-8-background-color has-background wp-block-paragraph\">Estoy trabajando en una serie de mejoras que te permitir\u00e1n, en muchos casos, instalar el Gateway en tu placa con ESP32 directamente desde el navegador, <strong>sin tener que compilar ni instalar nada en tu ordenador<\/strong> (como ya puedes hacer con <a href=\"https:\/\/emariete.com\/medidor-co2-gadget\/\">CO2 Gadget<\/a>), y configurarlo desde una p\u00e1gina web servida por el propio Gateway.<br><br>Cuando estas funcionalidades est\u00e9n disponibles, no tendr\u00e1s que hacer nada de los procesos indicados aqu\u00ed abajo si no necesitas configurar tus propias estructuras de datos y utilizas las que ya vienen predefinidas con el Gateway.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"h-conseguir-el-c-digo-fuente-del-gateway\">Conseguir el c\u00f3digo fuente del gateway<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">El c\u00f3digo fuente del gateway lo puedes encontrar en GitHub, concretamente en:<\/p>\n\n\n\n<p class=\"has-text-align-center wp-block-paragraph\"><strong>[EN PREPARACI\u00d3N SI QUIERES SER BETATESTER CONTACTAME EN EL <a href=\"https:\/\/t.me\/emariete_chat\" target=\"_blank\" rel=\"noreferrer noopener nofollow\">GRUPO DE TELEGRAM<\/a>]<\/strong><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Solo tienes que pulsar en el bot\u00f3n \u00abCode\u00bb y seleccionar \u00abDownload ZIP\u00bb.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Una vez lo hayas descargado tendr\u00e1s que descomprimirlo para extraer su contenido.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"h-editar-el-fichero-de-texto-con-la-configuraci-n-de-tu-red\">Editar el fichero de texto <span style=\"font-size: inherit;\">con la configuraci\u00f3n de tu red<\/span>  <\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Para hac\u00e9rtelo m\u00e1s sencillo y no tener que modificar el c\u00f3digo del gateway, deber\u00e1s poner los datos que son propios de tu instalaci\u00f3n en un fichero de texto que se llame \u00abcredentials.h\u00bb.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Los datos que son propios de tu instalaci\u00f3n y que deber\u00e1s escribir en este fichero son:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>SSID de tu red wifi<\/li><li>El password para acceder a la red<\/li><li>La direcci\u00f3n IP de tu servidor MQTT<\/li><li>El HOSTNAME del gateway (nombre que quieres dar a este dispositivo en tu red).<\/li><\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">Para que no tengas que partir de cero, entre los archivos que has extra\u00eddo del ZIP encontrar\u00e1s uno que se llama \u00abcredentials.tpl\u00bb. Es una <strong>plantilla que puedes modificar<\/strong>.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Tienes que copiar el fichero \u00abcredentials.tpl\u00bb como \u00abcredentials.h\u00bb y <strong>editarlo para introducir tus datos<\/strong> (o renombrar el fichero \u00abcredentials.tpl\u00bb como \u00abcredentials.h\u00bb y editarlo).<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"h-compilar-y-grabar-el-firmware-del-gateway-esp-now-en-el-esp32\">Compilar y grabar el firmware del Gateway ESP-NOW en el ESP32<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Solo te queda compilar y cargar el programa en el ESP.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Si est\u00e1s utilizando Arduino IDE, en el men\u00fa \u00abPrograma\/Subir\u00bb o pulsando Ctrl+U.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Si est\u00e1s usando PlatformIO, en \u00abProject tasks -&gt; Upload and Monitor\u00bb.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">En ambos casos tendr\u00e1s primero que seleccionar tu placa ESP32 y el puerto serie d\u00f3nde est\u00e1 conectada. Entiendo que esto ya sabes hacerlo y no voy a detallar el proceso. Si no supieras hacerlo, tienes much\u00edsimos tutoriales en internet o <strong>puedes pedir ayuda en el grupo de Telegram de eMariete<\/strong>.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Ten en cuenta que el gateway ESP-NOW no se puede instalar en una placa con ESP8266 porque <strong>no permite la comunicaci\u00f3n mediante ESP-NOW y WiFi simult\u00e1neamente<\/strong>. Tienes que instalarlo en un ESP32. No lo confundas con los clientes, que <strong>pueden ser ESP8266 sin ning\u00fan problema, <\/strong>la limitaci\u00f3n est\u00e1 solo en el Gateway.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"h-actualizar-el-firmware-del-gateway-esp-now-en-el-esp-32\">Actualizar <span style=\"font-size: inherit;\">el firmware del Gateway ESP-NOW<\/span> <span style=\"font-size: inherit;\">en el ESP-32 <\/span> <\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">El gateway dispone de actualizaciones inal\u00e1mbricas <strong>OTA <\/strong>(Over The Air). Esto te permite actualizar el firmware sin tenerte que conectar f\u00edsicamente al dispositivo. <\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Al ser este gateway un dispositivo de \u00abconectar y olvidar\u00bb, es habitual colocarlo escondido o en sitios con dif\u00edcil acceso. En estos casos la actualizaci\u00f3n OTA es especialmente \u00fatil, ya que podremos <strong>actualizar el firmware mediante su conexi\u00f3n wifi<\/strong> directamente desde el Arduino IDE (o desde PlatformIO).<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"h-el-c-digo-del-gateway-esp-now-c-mo-funciona\">El c\u00f3digo del Gateway ESP-NOW (c\u00f3mo funciona)<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">En ocasiones, especialmente si vas a utilizar el gateway con tus propios proyectos, tendr\u00e1s que modificar el c\u00f3digo del gateway para adaptarlo a tus necesidades. Los <strong>proyectos de eMariete est\u00e1n soportados directamente y no es necesario que modifiques nada<\/strong>, aunque te invito a hacerlo para adaptarlo a\u00fan m\u00e1s a tus gustos y preferencias.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">A continuaci\u00f3n, te voy a dar algunas pistas para que te sea m\u00e1s sencillo modificar el c\u00f3digo y adaptarlo a tus necesidades.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"h-la-estructura-de-datos\">La estructura de datos<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">De cara a adaptar el gateway a transmisiones con diferentes datos (no se env\u00edan los mismos datos, l\u00f3gicamente, desde un term\u00f3metro que desde un sensor de presencia o un medidor de CO2) es importante que comprendas <strong>el formato de los mensajes que se env\u00edan por ESP-NOW<\/strong> para que puedas crear nuevos formatos de mensaje.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Cuando el <strong>sensor <\/strong>(vamos a llamar <em>sensor <\/em>al emisor que genera los datos y que queremos recibir en el gateway y reenviar mediante MQTT) env\u00eda datos por ESP-NOW, lo hace enviando un mensaje (un conjunto que bytes) que sigue una estructura determinada. <\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Por ejemplo, el medidor de CO2 de ultra bajo consumo de eMariete (en preparaci\u00f3n) env\u00eda en cada mensaje un paquete de datos con una estructura como esta:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>  typedef struct struct_message\n  {\n    int id;\n    float temp;\n    float hum;\n    uint16_t co2;\n    float battery;\n    int readingId;\n    int command = cmdNone;\n    uint16_t parameter = 0;\n  } struct_message;<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Se trata de una estructura que contiene <strong>ocho datos<\/strong> diferentes.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Si te fijas podr\u00e1s ver que tenemos varios tipos de datos:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>Datos de apoyo a la transmisi\u00f3n, como son id (que contiene el n\u00famero de unidad que env\u00eda los datos, para que el gateway pueda diferenciar de qu\u00e9 unidad vienen los datos), readingId (que es un n\u00famero secuencial que se incrementa con cada transmisi\u00f3n y que sirve para que el gateway sepa si se han perdido paquetes).<\/li><li>Datos de medidas, como temp, hum, co2 y battery (la medida de la temperatura, la humedad, la concentraci\u00f3n de CO2 y el voltaje de la bater\u00eda).<\/li><li>Datos de los comandos procesados: qu\u00e9 comando ha recibido el sensor desde el gateway y con qu\u00e9 par\u00e1metro (m\u00e1s sobre esto despu\u00e9s).<\/li><\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">Si ahora quisi\u00e9ramos a\u00f1adir una estructura de datos para ser utilizada por un nodo term\u00f3metro, que no mide nada m\u00e1s que la temperatura, podr\u00edamos crear una estructura de datos como esta:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>  typedef struct struct_message\n  {\n    int id;\n    float temp;\n    float battery;\n  } struct_message;<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Esta estructura tiene solo tres datos diferentes: un dato \u00abid\u00bb (para que el gateway sepa qu\u00e9 sensor lo ha enviado), un dato \u00abtemp\u00bb (que contiene la temperatura) y un dato \u00abbattery\u00bb (que contiene el voltaje de la bater\u00eda del sensor).<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u00bfHubi\u00e9ramos podido utilizar la estructura que utiliz\u00e1bamos para los medidores de CO2 para el term\u00f3metro y de esta forma no hubi\u00e9ramos necesitado modificar el c\u00f3digo? La respuesta es s\u00ed, pod\u00edamos haberlo hecho, simplemente dejando los datos que no necesit\u00e1bamos a 0 (hum, co2, readingId, command y parameter).<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u00bfY entonces, por qu\u00e9 complicarnos la vida con una estructura de datos distinta para el term\u00f3metro? Para <strong>optimizar la transmisi\u00f3n<\/strong> y de esta forma disminuir el consumo energ\u00e9tico y <strong>mejorar la autonom\u00eda<\/strong>.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Con este cambio hemos reducido el env\u00edo de datos de 22 bytes a tan solo 10 bytes. Esto <strong>supone haber mejorado la autonom\u00eda del sensor alrededor de un 50%<\/strong> (de 90 d\u00edas a 180 d\u00edas con la misma bater\u00eda. [Pendiente de realizar nuevas pruebas y mediciones para poner datos reales y unas gr\u00e1ficas que los apoyen]<\/p>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"h-optimizando-la-estructura-de-datos\">Optimizando la estructura de datos<\/h4>\n\n\n\n<p class=\"wp-block-paragraph\">Como hemos visto en el ejemplo anterior, de la estructura de datos para el term\u00f3metro, <strong>cada byte que enviemos en el mensaje ESP-NOW cuenta y reducir\u00e1 la autonom\u00eda del sensor<\/strong>.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Es importante que los mensajes est\u00e9n bien <strong>optimizados<\/strong>. Por ejemplo, podr\u00edamos optimizar la estructura de mensajes del medidor de CO2 de esta manera:<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">En lugar de utilizar este formato de mensaje<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>  typedef struct struct_message\n  {\n    int id;\n    float temp;\n    float hum;\n    uint16_t co2;\n    float battery;\n    int readingId;\n    int command = cmdNone;\n    uint16_t parameter = 0;\n  } struct_message;<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Utilizar este otro:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>  typedef struct struct_message\n  {\n    byte id;\n    int temp; \/\/ temp * 100;\n    byte hum;\n    uint16_t co2;\n    byte battery;\n  } struct_message;<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">El primer mensaje ocupa 22 bytes, el segundo ocupa solamente 7 bytes. Menos de <strong>un tercio de tiempo de transmisi\u00f3n<\/strong>, lo que probablemente pueda incrementar la autonom\u00eda entre un 25 y un 50%.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Para ello, lo \u00fanico que hemos hecho ha sido:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>Eliminar los datos superfluos que no son imprescindibles para un medidor de CO2<\/li><li>Optimizar el tama\u00f1o de los datos<\/li><\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">Hemos dedicado un byte en vez de dos al id. Con esto hemos reducido el n\u00famero de sensores de 65536 a 256 pero \u00bfRealmente tienes m\u00e1s de 256 sensores?<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Hemos reducido la temperatura de 4 a 2 bytes, simplemente multiplic\u00e1ndola por 100 para eliminar los decimales sin perder precisi\u00f3n. En el receptor la dividiremos por 100 y volveremos a tener los decimales.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Hemos reducido la humedad de 4 a 2 bytes, redondeando el dato para eliminar los decimales que no suelen ser necesarios cuando se mide humedad (y si los quisi\u00e9ramos mantener podr\u00edamos hacerlo multiplicando por 100, como hemos hecho con la temperatura, y seguir\u00edan siendo dos bytes).<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Hemos reducido la bater\u00eda de 4 a 1 byte, enviando el porcentaje en vez del voltaje (si quisi\u00e9ramos enviar el voltaje en un solo byte tambi\u00e9n podr\u00edamos: por ejemplo, podr\u00edamos aplicar en el emisor bater\u00eda = (voltaje * 100) &#8211; 255 y en el receptor   voltaje = (bateria  * 100 + 255); esto nos permitir\u00eda transmitir voltajes de entre 2.55V y 5.1V con dos decimales utilizando un solo byte).<\/p>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"h-otra-vuelta-de-tuerca-a-la-estructura-de-datos\">Otra vuelta de tuerca a la estructura de datos<\/h4>\n\n\n\n<p class=\"wp-block-paragraph\">Acabamos de ver un buen ejemplo de optimizaci\u00f3n, pero podr\u00edamos optimizar mucho m\u00e1s&#8230;<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u00bfPor qu\u00e9 ce\u00f1irnos a los tipos de datos oficiales de Arduino o C++ y a hacer grupos de 1 byte (8 bits)?<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Podr\u00edamos estructurar y <strong>optimizar la informaci\u00f3n a nivel de bit individual<\/strong>, lo que nos permitir\u00eda ahorrar bastante espacio.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>  typedef struct struct_message\n  {\n    byte id:4;\n    int temp; \/\/ temp * 100;\n    byte hum:7;\n    uint16_t co2:11;\n    byte battery:7;\n  } struct_message;<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Aqu\u00ed, por ejemplo, para el id hemos dedicado 4 bits, lo que nos permite tener hasta 16 sensores, que en la mayor parte de casos ser\u00e1 suficiente y nos ahorramos 4 bits (y si queremos m\u00e1s le podemos dar 5 bits y podr\u00edamos tener 32 sensores y seguir ahorrando 3 bits). <\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Con 11 bits para el CO2 podr\u00edamos enviar valores de hasta 2047 ppm, ahorr\u00e1ndonos 5 bits (y si queremos m\u00e1s le podemos dar 12 bits y podr\u00edamos enviar datos de hasta 4095 ppm y seguir\u00edamos ahorrando 4 bits).<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Lo importante es que hemos reducido los datos enviados de 56 bits (7 bytes) a solo 50 (un 10% de ahorro). Desde la estructura original hemos reducido ya de 176 bits a solo 50 <strong>\u00a1m\u00e1s de un 70% de ahorro!<\/strong><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Y todav\u00eda nos queda espacio para optimizar&#8230; \u00bfy si en vez de usar 16 bits para enviar la temperatura no enviamos un n\u00famero que sea, por ejemplo, los incrementos de 0.5\u00baC desde -30\u00baC? Si le dedicamos 8 bits podr\u00edamos enviar la temperatura desde -30\u00baC hasta 98\u00baC con una precisi\u00f3n de 0.5\u00baC ahorrando 8 bits m\u00e1s de los 50.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u00bfY si en vez de usar 7 bits para la bater\u00eda no enviamos los incrementos de 100mV desde 3V? el 12 ser\u00eda 4.2V y solo necesitar\u00edamos 4 bits, ahorrando otros 4.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u00bfY si enviamos un solo dato cada vez? CO2 cada minuto, Temperatura cada 5 minutos (\u00bfpara qu\u00e9 la queremos cada minuto en condiciones normales?), la humedad cada 10 minutos y la bater\u00eda cada 6 horas? Solo necesitar\u00edamos a\u00f1adir a la estructura dos bits para indicar cu\u00e1l de los cuatro datos se est\u00e1 enviando. <strong>Estar\u00edamos enviando mensajes de solo 20 bits, \u00a1un ahorro de casi un 88%!<\/strong><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>  typedef struct struct_message\n  {\n    byte id:4;\n    int dato;\n  } struct_message;<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Como ves las posibilidades de optimizaci\u00f3n son enormes.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Yo no he optimizado mucho la estructura de datos a prop\u00f3sito, para que sea f\u00e1cil de entender el c\u00f3digo para cualquiera.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"h-c-mo-reenviar-mensajes-esp-now-a-mqtt\">\u00bfC\u00f3mo reenviar mensajes ESP-NOW a MQTT?<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Para que el gateway reenv\u00ede a trav\u00e9s de MQTT los mensajes que recibe por ESP-NOW, b\u00e1sicamente tiene que hacer lo siguiente:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>Identificar el mensaje recibido como un mensaje que debe reenviar<\/li><li>Extraer los datos de la estructura de datos ESP-NOW (struct_message)<\/li><li>Crear el topic y el payload del mensaje a enviar<\/li><li>Publicar el mensaje MQTT<\/li><\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">Tienes que tener en cuenta que, este gateway ha sido dise\u00f1ado para optimizar el env\u00edo de datos no cr\u00edticos (se puede perder alguno de vez en cuando sin problemas) y conseguir que los sensores est\u00e9n despiertos en m\u00ednimo tiempo posible, por ese motivo el env\u00edo de datos del sensor al gateway no dispone de ning\u00fan sistema que asegure que el dato es recibido.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Para aplicaciones m\u00e1s cr\u00edticas de las que yo he necesitado ser\u00eda necesario establecer un protocolo de acuse de recibo y reenv\u00edo de la informaci\u00f3n.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Hay que tener en cuenta que cuanto m\u00e1s robusto y m\u00e1s opciones y refinamientos tenga el protocolo m\u00e1s sobrecarga de datos tendr\u00e1, con lo que las transmisiones ser\u00e1n m\u00e1s largas y los dispositivos tendr\u00e1n que estar despiertos m\u00e1s tiempo (esperando mensajes de respuesta, por ejemplo). <\/p>\n\n\n\n<p class=\"wp-block-paragraph\">En mi caso, si estoy enviando datos de temperatura o CO2 cada minuto, por ejemplo, no me importa que alg\u00fan mensaje que otro se pierda, ya se actualizar\u00e1 con el siguiente mensaje un minuto m\u00e1s tarde, no es cr\u00edtico (la experiencia me ha dicho que son muy pocos los que se pierden).<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"h-c-mo-reenviar-mensajes-mqtt-a-esp-now\">\u00bfC\u00f3mo reenviar mensajes MQTT a ESP-NOW?  <\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Para que el gateway reenv\u00ede los mensajes que recibe por MQTT a trav\u00e9s de ESP-NOW a un sensor, tiene que hacer lo siguiente:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>Suscribirse a los topic MQTT que quiera reenviar <\/li><li>Cuando recibe un mensaje MQTT extraer los datos del payload<\/li><li>Con los datos extra\u00eddos, copiar dichos datos a la estructura de datos ESP-NOW (struct_message)<\/li><li>Enviar el mensaje ESP-Now <strong>en el momento justo en el que el sensor est\u00e9 despierto y recibiendo<\/strong>.<\/li><\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">Como podr\u00e1s imaginar, enviar datos mediante ESP-NOW a un sensor que <strong>normalmente est\u00e1 dormido, se despierta unos pocos milisegundos y se vuelve a dormir<\/strong> no es f\u00e1cil. <\/p>\n\n\n\n<p class=\"wp-block-paragraph\">El principal problema es que no sabemos cu\u00e1ndo el sensor est\u00e1 despierto. <\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Normalmente no tenemos en el sensor un reloj en tiempo real preciso (que nos podr\u00eda ayudar a sincronizar los env\u00edos). <\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Lo m\u00e1s que podemos hacer es esperar a que el sensor se comunique con el gateway y mantener el sensor despierto unos milisegundos escuchando; <strong>es inmediatamente despu\u00e9s de recibir cuando el gateway puede enviar el mensaje<\/strong>, asumiendo que el sensor todav\u00eda estar\u00e1 despierto y escuchando.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">El sistema de env\u00edo de datos de MQTT a ESP-NOW no es perfecto, tal y como est\u00e1 implementado, y espero mejorarlo con el tiempo:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>Es dif\u00edcil asegurarse de que el sensor est\u00e1 despierto y recibiendo en el momento en el que el gateway env\u00eda su mensaje.<\/li><li>No se ha implementado un sistema de acuse de recibo por parte del sensor para asegurarse de que no se pierdan mensajes.<\/li><li>No podemos enviar mensajes al sensor en cualquier momento, solo cuando nos env\u00ede un mensaje.<\/li><li>Si dejamos el sensor despierto demasiado tiempo a la espera de recibir un hipot\u00e9tico mensaje desperdiciaremos un mont\u00f3n de energ\u00eda. Si lo dejamos despierto demasiado poco tiempo tendremos problemas de sincronizaci\u00f3n.<\/li><\/ul>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"h-ampliaciones-y-mejoras-del-gateway-esp-now\">Ampliaciones y mejoras del gateway ESP-NOW<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>He tratado de programar este gateway de una forma muy sencilla<\/strong>, para que cualquier aficionado con un poquito de idea de programaci\u00f3n pueda entender el c\u00f3digo y modificarlo con relativa facilidad para implementar cualquier otro tipo de pasarela.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Entre las pasarelas que podr\u00edas incluir en el gateway, tendr\u00edas:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>Grabaci\u00f3n directa de datos en BBDD&nbsp;<strong>InfluxDB, MySQL, MariaDB<\/strong>&nbsp;y similares.<\/li><li>Env\u00edo de notificaciones y alertas mediante&nbsp;<strong>email, Telegram, Pushover<\/strong>, etc.<\/li><li>Integraci\u00f3n en cualquier sistema de control,&nbsp;<strong>dom\u00f3tica, inm\u00f3tica, PLC<\/strong>, etc.<\/li><li>Cualquier otro tipo de implementaci\u00f3n RF, con el hardware RF necesario (<strong>LoRa, LoRaWan, BLE, BLE Mesh, Bluetooth Smart<\/strong>, etc.).<\/li><\/ul>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"h-mejoras-en-el-sistema-de-datos-y-estructura-esp-now\">Mejoras en el sistema de datos y estructura ESP-NOW<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Una mejora importante con la que todav\u00eda no me he puesto (porque no la he necesitado) ser\u00eda un sistema de env\u00edo de datos ESP-NOW m\u00e1s flexible, que permita estructuras flexibles (que solo haya que definir en el emisor o sensor) y que incluya, de alguna forma, la configuraci\u00f3n MQTT.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">El principal problema es la optimizaci\u00f3n del tama\u00f1o de los datos, para evitar que en los mensajes ESP-NOW viaje demasiada informaci\u00f3n (por ejemplo, evitar que el sensor env\u00ede con cada paquete el topic MQTT y formato del payload MQTT d\u00f3nde debe ser reenviado).<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Te invito a discutir la posible implementaci\u00f3n en el grupo de Telegram de eMariete o, si la desarrollas por tu cuenta, hacer un pull request para valorar incluirla en la versi\u00f3n p\u00fablica del gateway.<\/p>\n<div class=\"essb_break_scroll\"><\/div>","protected":false},"excerpt":{"rendered":"<p>A Gateway that allows you to receive signals sent with ESPNOW and forward them as MQTT messages.<\/p>","protected":false},"author":1,"featured_media":240560,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_uag_custom_page_level_css":"","_lmt_disableupdate":"yes","_lmt_disable":"no","footnotes":""},"categories":[17],"tags":[20,21,26,27,28,29,41],"class_list":["post-238920","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-proyectos-arduino","tag-arduino","tag-bajo-consumo","tag-espeasy","tag-esp32","tag-esp8266","tag-espnow","tag-nodemcu"],"modified_by":"Mariete","uagb_featured_image_src":{"full":["https:\/\/emariete.com\/wp-content\/uploads\/2022\/02\/Gateway-ESPNOW-MQTT-WIFI.png",1080,608,false],"thumbnail":["https:\/\/emariete.com\/wp-content\/uploads\/2022\/02\/Gateway-ESPNOW-MQTT-WIFI-150x150.png",150,150,true],"medium":["https:\/\/emariete.com\/wp-content\/uploads\/2022\/02\/Gateway-ESPNOW-MQTT-WIFI-300x169.png",300,169,true],"medium_large":["https:\/\/emariete.com\/wp-content\/uploads\/2022\/02\/Gateway-ESPNOW-MQTT-WIFI-768x432.png",768,432,true],"large":["https:\/\/emariete.com\/wp-content\/uploads\/2022\/02\/Gateway-ESPNOW-MQTT-WIFI-1024x576.png",1024,576,true],"1536x1536":["https:\/\/emariete.com\/wp-content\/uploads\/2022\/02\/Gateway-ESPNOW-MQTT-WIFI.png",1080,608,false],"2048x2048":["https:\/\/emariete.com\/wp-content\/uploads\/2022\/02\/Gateway-ESPNOW-MQTT-WIFI.png",1080,608,false],"trp-custom-language-flag":["https:\/\/emariete.com\/wp-content\/uploads\/2022\/02\/Gateway-ESPNOW-MQTT-WIFI.png",18,10,false]},"uagb_author_info":{"display_name":"Mariete","author_link":"https:\/\/emariete.com\/en\/author\/admin_xlyz052h\/"},"uagb_comment_info":6,"uagb_excerpt":"Un Gateway que te permite recibir se\u00f1ales enviadas con ESPNOW y reenviarlas como mensajes MQTT","_links":{"self":[{"href":"https:\/\/emariete.com\/en\/wp-json\/wp\/v2\/posts\/238920","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/emariete.com\/en\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/emariete.com\/en\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/emariete.com\/en\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/emariete.com\/en\/wp-json\/wp\/v2\/comments?post=238920"}],"version-history":[{"count":0,"href":"https:\/\/emariete.com\/en\/wp-json\/wp\/v2\/posts\/238920\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/emariete.com\/en\/wp-json\/wp\/v2\/media\/240560"}],"wp:attachment":[{"href":"https:\/\/emariete.com\/en\/wp-json\/wp\/v2\/media?parent=238920"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/emariete.com\/en\/wp-json\/wp\/v2\/categories?post=238920"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/emariete.com\/en\/wp-json\/wp\/v2\/tags?post=238920"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}