|
|
|
# Esp Now Basic Steps
|
|
|
|
## ESP32
|
|
|
|
The ESP32 uses the [Espressif ESPNow Library](https://docs.espressif.com/projects/esp-idf/en/latest/esp32c3/api-reference/network/esp_now.html), the basic usage of which is as follows:
|
|
|
|
|
|
|
|
- include <esp_now.h>
|
|
|
|
- include <WiFi.h>
|
|
|
|
- set Wifi to station mode and call ```esp_now_init()```
|
|
|
|
- add a peer to espnow
|
|
|
|
- create a ```esp_now_peer_info_t``` struct (called host in ``espnow.cpp`` as we try to connect to the fipy-host)
|
|
|
|
- add the MAC Address of the peer you want to connect to to the struct
|
|
|
|
- define whether to use encryption and which channel to use
|
|
|
|
- call ```esp_now_add_peer()``` with the struct
|
|
|
|
- register callback functions for sending and receiving
|
|
|
|
- our callback function for sending is just an empty function, as everything to do after sending makes more sense to do later based on return values
|
|
|
|
- our callback function for receiving saves the MAC Address contained in the message (which should be the MAC of the fipy) and updates the time.
|
|
|
|
|
|
|
|
## Fipy
|
|
|
|
The Fipy uses [Pycom's Espnow Library](https://development.pycom.io/firmwareapi/pycom/network/espnow/), which works in a similar fashion to Espressif's library:
|
|
|
|
|
|
|
|
- from network import ESPNOW and WLAN
|
|
|
|
- initialize WLAN
|
|
|
|
- initialize ESPNOW
|
|
|
|
- register callback functions for sending and recieving
|
|
|
|
|
|
|
|
As the Fipy is only going to respond to messages (data sent from an ESP32), it is not necessary to register a peer in advance, as the ESP32 always sends its MAC address in every message. If the Fipy receives a message from an unregistered peer it **assumes that the peer is to be trusted**, registers it and responds with its own MAC address and the current time.
|
|
|
|
|
|
|
|
###### It is not necessary to register both sending and receiving callback functions if either one isn't needed (e.g. the ESP32 doesn't need a ``on_data_sent``)
|
|
|
|
|
|
|
|
## Communication
|
|
|
|
To send a message to a peer, the peer has to be registered. This peer can either have a specific MAC address, or use the broadcast mac ``(0xffffffffffff)``.
|
|
|
|
|
|
|
|
To send data from the ESP32, use the Message class:
|
|
|
|
|
|
|
|
- create a new instance of ```Message```
|
|
|
|
- call the ```add_data()``` method using a value (float) and an identifier (int)
|
|
|
|
- call the ```send()``` method to send the Message.
|
|
|
|
|
|
|
|
###### The maximum amount of values that can be sent at one time is 10.
|
|
|
|
|
|
|
|
The first Message will always be broadcast, as the MAC address of the host is not yet known. If everything works as intended, the host will respond to the message and the client will save it's MAC. Messages sent afterwards will be sent directly to the host.
|
|
|
|
|
|
|
|
#### Receiving messages on the Fipy
|
|
|
|
The way it is currently implemented, receiving messages on the Fipy should not have to be changed, I'm going to explain it here anyways, as it is a bit daunting at first glance:
|
|
|
|
|
|
|
|
- ESPNOW uses C structs to send the data
|
|
|
|
- the [struct library](https://docs.python.org/3/library/struct.html) enables python to work with C structs:
|
|
|
|
- the ```struct.unpack()``` and ```struct.pack()``` methods use a format string to know what the struct looks like. For example, in line 46 in ```host/fipy/lib/espnow.py``` the string ```"<10i10fil"``` defines a struct of 10 integers (i), 10 floats (f), another integer and a long (l) in little endian (<). In C:
|
|
|
|
```
|
|
|
|
struct ClientDataPackage {
|
|
|
|
int identifiers[NUM_SENSORS];
|
|
|
|
float values[NUM_SENSORS];
|
|
|
|
int amountData;
|
|
|
|
long timestamp;
|
|
|
|
};
|
|
|
|
```
|
|
|
|
The result of this method is a tuple.
|
|
|
|
|
|
|
|
- conversely, line 20 in ```host/fipy/lib/espnow.py``` uses the format string ```"<6sl"```, defining a struct of 6 bytes (s) and a long (l) in little endian (<). In C:
|
|
|
|
```
|
|
|
|
typedef struct config {
|
|
|
|
uint8_t host[6];
|
|
|
|
long time_millis;
|
|
|
|
} config;
|
|
|
|
```
|
|
|
|
##### the struct library would also require the user to specify the padding bytes in the format string, which is the reason to use ```#pragma pack(1)``` in C++, to create the struct without padding bytes.
|
|
|
|
|
|
|
|
|
|
|
|
<details><summary>Deprecated</summary>
|
|
|
|
- Define Mac address of receiving esp32
|
|
|
|
|
|
|
|
- create a ```esp_now_peer_info_t```
|
|
|
|
|
|
|
|
- define a function for sending/receiving
|
|
|
|
|
|
|
|
```
|
| ... | ... | @@ -18,3 +85,4 @@ |
|
|
|
```
|
|
|
|
|
|
|
|
- Now you can send in your ```loop()```, or leave ```loop()``` empty to only receive
|
|
|
|
</details> |
|
|
\ No newline at end of file |