ESP Now Communication

Utilisation du mode de communication ESP Now en Domotique.

Le mode de communication ESP Now utilise la couche physique et le data link layer du WiFi (802.11 b/g/n).

  • Data link layer (SLIP/PPP/MTU)

Elle coexiste avec le WiFi traditionnel, le Bluetooth et le ZigBee, elle utilise cependant beaucoups moins de resources que le WiFi car les couches supérieures OSI ne sont pas implémentées donc les couches suivantes

  • Network (IP/ICMP/RIP)
  • Transport layer (TCP/UDP)
  • Session layer (RPC/ASP)
  • Presentation layer (ASCII/EBCDIC)
  • Application layer (FTP/HTTP/SMTP/DNS)

ne sont pas disponibles d’où le gain de resource car il faut pas les constituer.

Connexions: point to point ou broadcast

Comme il n’y a pas d’entêtes nécessaires aux couches supérieures, les messages sont plus courts et moins soumis aux collisions, mais les pertes ne sont pas récupérables (Ack/Nack).

Caractéristiques:

Par défaut

1 Mbit par secondes à 214 Kbps en environement ouvert (donc soumis aux influences des autres occupants de a bande de fréquence). Extension du range WiFi à 220 mètres Les packet d’information sont limités à 250 bytes. Latence réduite (4 ms pour 10 bytes, 8 ms pour 250 bytes).

Pour essayer la chose j’ai récupéré un ESP8266 (LoLin D1 Mini) avec un détecteur de présence (IR HC-SR501). Celui-ci est utilisé avec WiFi et mqtt, il va envoyer un message via mqtt et via ESP-Now.

Côté récepteur, un esp32-S3.

Le récepteur recoit tout les messages envoyés sur le canal WiFi en ESP-Now et renvoit les messages sur le broker mqtt.

Voiçi le résultat, le concept utilise une structure qui définit les données à envoyer, par exemple une chaîne de caractère de 6 bytes et un entier.

typedef struct struct_message {
int presence;
char a[6];
} struct_message;

Cette même structure est implémentée dans le récepteur pour extraire les donées dans le bon format.

Soit l’encodage et l’envoit

struct_message myData; //la structure

strcpy(myData.a, "FALSE");
myData.presence = 0;

esp_now_send(0, (uint8_t *) &myData, sizeof(myData)); //on va donc encoyer le contenu de la structure en bloc

à la réceptions:

// la même structure doit être définie

typedef struct struct_message {
    int presence;
    char a[6];
} struct_message;

struct_message myData; //la structure

// callback function exécutée a la réception d'un bloc de données

void OnDataRecv(const esp_now_recv_info_t *recv_info, const uint8_t *data, int len) {
    uint8_t * mac_addr = recv_info->src_addr;
    uint8_t * des_addr = recv_info->des_addr;
    memcpy(&myData, data, len);
    doc["presence"]=myData.presence;
    doc["motion"]=myData.a;
    int Slen = serializeJson(doc,command);
    client.publish("ESPnowGW/PIR2",command.c_str());
    flag=1; //indicateur de réception de données
}

Ce qui donne:

IDE