If you need to create a battery powered device with esp32, then mqtt looks great but connecting to the WiFi could take 2 seconds of high power consumption, add to that the fact that polling for a subscription can last other 2 seconds adn the result is your battery drained doing connection stuff.
With this library you can comunicate with the mqtt server within 100 ms.
You can build both, the device part and the gateway. Some examples of both.
The idea is letting you making your own device and connecting it to mqtt via gateway:
Therefore this library provides two (singleton) objects. In the iotDevice you use EspNow2MqttClient
to send the data (ie. your sensor reads) and also to gather data (polling) from mqtt (ie. commands for your actuators)
You do not need to put code in your gateway unless you need to show info in a display or something similar, as is done in the display server example
ESP-Now has some limitations that influenced our design:
You cannot connect more than 6 nodes if you use ESP-Now with cyphering. To avoid this we have decided to not using it and using our own cyphering with a software layer based on Chacha (as LoraWan does).
The idea was taken from EnigmaIOT but we decided to build from scrach because our goal is to provide a library instead of a framework where you can place your code in.
You have a very simple protocol defined with nanopb (protocol buffers for iot) that allows to query and write to many mqtt topics with a simple message. Here you can see the definition and limitations. But you don't need to kown the details you can use the helper functios as detailed in the examples folder
Using this simple protocol ensures minimial overhead waste, but remember: ESP-Now limits your messages to 250 bytes, keep your messages low (we capped the payload to 200 bytes and 5 pub/subs per request)
As there is a message size cap, is not sensible to use full canonical topics names, because they whould consume all the available bandwith.
Therefore you only need to especify the las part (call it the name). You can find your data in a topica called:
EspNow/clientId/name
Where
- EspNow is a fixed literal (you can modify in this header)
- clientId is the name you are required when creating your instance of
EspNow2MqttClient
. If various devices share this ID then they will share its topics without need of a third party - name is your choice for any given message (publication or subscrition)
If you look at the examples folder you may see lots of lines of code. But simplicity is a goal. If you don't want to have fancy features you can have as little source as this:
#include <Arduino.h>
#include <EspNow2MqttClient.hpp>
#define LED 2
byte sharedKey[16] = {10,200,23,4,50,3,99,82,39,100,211,112,143,4,15,106};
byte sharedChannel = 8 ;
uint8_t gatewayMac[6] = {0xA4, 0xCF, 0x12, 0x25, 0x9A, 0x30};
EspNow2MqttClient client = EspNow2MqttClient("testLib", sharedKey, gatewayMac, sharedChannel);
void setup() {
pinMode(LED, OUTPUT);
client.init();
}
void loop() {
digitalWrite(LED, HIGH);
client.doSend("ON","led");
delay(1000);
digitalWrite(LED, LOW);
client.doSend("OFF","led");
delay(1000);
}
You may recognice the basic blink program where some have been added to, briefly:
- the include of EspNow2MqttClient, as this example is about a client
- a first block of shared data that is also in your gateway (and in all your devices) and proides privacy.
- client init sentence, to pair with the gateway
- client doSend sentences, to send data
The result of this program is the status of the led also shown in a mqtt queue called <something>/testLib
as a client you need to add this dependence to you program:
#include <EspNow2MqttClient.hpp>
follow the examples on the examples folder
you can send 4 types of messages:
- ping : testing message, does not reach to mqtt, only tests espnow
- send : deliveres a message to the queue of your choice
- subscribe: gives the content of a queue when it changes. this message creates a subscription in the gateway, when the gateway gets the message stores it and delivers to you on the next 'subscribe' message with the same queue
- multiple: any combination of up to 10 atomic messages (ping, send or subscribe). the response will be an array with the same order
remember anycase that you cannot exced 200 bytes as an esp-now limitation
For more information refer to Client User Manual.
You can build gateway server just taking the example as is. Or include this file and build your own:
#include <EspNow2MqttGateway.hpp>
You need to share the key, channel and mac with your clients in order to allow only YOUR clients to connect.
- channel: your ESP cannot use two channels, Therefore you need to configure your esp-now channel to coincide with your WiFi network. All your clients need to know and use this channel. On the sleeping client you can find how to get the channel of your WiFi
- key: all mensages are ciphered. use same key in all clients and the gateway. As the ciphered is performed by software there is no limit in the number of clients.
- mac: all the clients need to know the mac of the gateway. In the example you can find a function to get it printed
For more information refer to Gateway User Manual
- message format
- few operations on a batch (5) to save memory on the stack
- messageId: a new (optional) field on requests and responses that the gateway will return to you to ease response recognition, it an be used
- as a correlation id
- as a message type id
- ignored
- gateway parametrizable identification, to allow having multiple gateways at same time (and extend your network reach)
- callback when mqtt data is received
- methods
int getNumberOfSubscriptions()
gives the number of mqtt topics being listenedint getNumberOfMessages()
gives the number of messages fetched and not (yet) delivered
- sendGwMqttMessage function that allows to publish internal gw user info (for example to send the chip temperature)
- resubscribe to all topics when reconnectig to mqtt server (lost of connection)
- renaming files to increase visualization of the library in platform.io
- changed manifesto format
- nanoPb version updated to 0.4.5
- client and gateway manuals
- include library.json to fix dependences version issues
a brief list (building) of complete projects using the library
- home esp-now gateway, a gateway for more devices
- airCond controller, a battery powered button pusher
- eInk desktop monitor
sometimes the dependencies are not resolved by itself add this manually if happens to you:
Crypto@^0.2.0
Nanopb
knolleary/PubSubClient@^2.8
- regenerate protobuf
- use platform.io and select the profile you need