Autres articles / Other articles

ESP-NOW gestion de la couche applicative

publication: 3 janvier 2026 / mis à jour 5 janvier 2026

Read this page in english

 


La couche applicative

Dans notre projet exploitant ESP-NOW, nous désignerons la couche applicative l'ensemble des mots agissant coté récepteur. Pour notre article, un exemple de la couche applicative est disponible ici:
  github.com/MPETREMANN11/ESP32forth/blob/main/espnow/ledsCommand.fs

Dans ce fichier ledsCommand.fs, intéressons-nous aux dernières lignes de code:

: redOn  ( -- )     LED_RED ledOn  ; 
: redOff ( -- )     LED_RED ledOff ; 
: yellowOn  ( -- )  LED_YELLOW ledOn  ; 
: yellowOff ( -- )  LED_YELLOW ledOff ; 
: greenOn  ( -- )   LED_GREEN ledOn  ; 
: greenOff ( -- )   LED_GREEN ledOff ; 

Ces six lignes, en code FORTH, permettent d'allumer ou éteindre ces trois LEDs:

Contrôle de la couche applicative

Sur notre carte étiquetée SLAVE1, nous avons monté trois LEDs. Pour tester ces trois LEDs, il faut charger le contenu du fichier ledsCommand.fs dans l'espace /spiffs/ de la carte ESP32. Puis on exécute include /spiffs/ledsCommand.fs.

Pour prendre en compte automatiquement le contenu du fichier ledsCommand.fs, on modifie cette partie de code dans main.fs:

myMac 6 SLAVE1 6 str= [IF] 
    needs /spiffs/ledsCommand.fs    initLeds 
    needs /spiffs/tests-SLAVE1.fs 
[THEN] 

La grande question est donc: "comment on contrôle cette couche applicative depuis ESP-NOW?".

Dans ESP32forth, nous disposons du mot evaluate. Ce mot prend une chaîne de caractères et tente d'en interpréter le contenu. Exemple:

s" redOn" evaluate 

Dans les paramètres traités par callback en réception d'un message via ESP-NOW, nous avons l'adresse et la longueur du message transmis vers notre carte SLAVE1.

Voici comment on réalise l'interfaçe entre ESP-NOW et notre partie applicative:

\ interpret ESP-NOW transmitted string 
: evaluate-cb-espnow  { len dataAddr macAddr -- } 
    dataAddr len evaluate 
  ; 
\ register this callback 
' evaluate-cb-espnow espnowRegisterRecv 

Sauf que... Ca ne fonctionne pas!

Ca ne fonctionne pas, pour une raison très simple, il y a une collision entre le tampon d'interprétation Forth et notre mot evaluate-cb-espnow qui est exécuté dans une interruption ESP-NOW.

Pour remédier à ce dysfonctionnement, il faut transférer les données traitées par l'interruption ESP-NOW. Pour ce faire, on exploitera le traitement de chaînes de caractères dispobible dans le fichier strings.fs disponible ici:
  github.com/MPETREMANN11/ESP32forth/blob/main/espnow/strings.fs

On commence par définir deux variables chaines de caractères:

also espnow 
\ define two strings 
ESP_NOW_ETH_ALEN     string RecvMacAddr 
ESP_NOW_MAX_DATA_LEN string RecvDataStr 

Rôle de chaque chaîne de caractères:

On définit ensuite un nouveau mot pour le callback ESP-NOW:

\ interpret ESP-NOW transmitted string 
: store-cb-espnow  { len dataAddr macAddr -- } 
    macAddr ESP_NOW_ETH_ALEN RecvMacAddr  $! 
    dataAddr len RecvDataStr $! 
  ; 
only FORTH 
 
\ register this callback 
' store-cb-espnow espnowRegisterRecv 

Maintenant, à chaque réception d'une transmission ESP-NOW, le message sera stocké dans la chaine de caractères RecvDataStr. Il reste à traiter le contenu de cette chaîne:

: espnow-loop ( -- ) 
    begin 
        RecvDataStr nip ?dup if 
            RecvDataStr evaluate 
            RecvDataStr 0$! 
        then         
    again 
  ; 
 
espnow-loop 

Le mot espnow-loop est une boucle fermée. Dans cette boucle, on teste si la chaîne RecvDataStr n'est pas de longueur nulle. Si c'est le cas, on interprète son contenu. Puis on remet la longueur de cette chaîne à zéro avec la séquence RecvDataStr 0$!.

Les avantages et inconvénients de cette méthode de contrôle

Commençons par les inconvénients:

Puis voici les avantages:

Ici, la couche applicative, coté carte SLAVE1, consiste simplement à allumer trois LEDs distinctes. Coté carte MASTER, il suffit de clôner ces commandes d'allumage et extinction de cette manière, ici pour la LED rouge:

: redOn ( -- ) 
  SLAVE1 s" redOn " espnowSend 
  ; 
: redOff ( -- ) 
  SLAVE1 s" redOff " espnowSend 
  ; 

Sur la carte MASTER, le fait de saisir et exécuter redOn va allumer la LED rouge sur la carte SLAVE1.

Ceci fait remonter une autre question: "comment être certain que la carte SLAVE1 a bien reçu et exécuter la commande transmise par MASTER via ESP-NOW?"

Le seul moyen d'être certain de la bonne exécution est d'établir un protocole bi-directionnel entre les cartes émettrices et réceptrices. Mais nous sortons du cadre de cet article.

Le principal avantage, en exécutant des mots FORTH à la réception d'une transmission ESP-NOW, c'est de simplifier l'interfaçage entre une application et la transmission ESP-NOW. Le code décrit plus haut, dans cet article, restera inchangé quelque soit la partie applicative à gérer. Sur ce point, le langage FORTH s'avère bien plus souple que le langage C.

Pour clore cet article, voici comment, coté carte SLAVE1, on lance automatiquement la réception ESP-NOW et la partie applicative:

RECORDFILE /spiffs/autoexec.fs 
 
main 
 
<EOF> 

Ceci enregistre le fichier /spiffs/autoexec.fs. A la mise sous tension, ESP32forth vérifie si le fichier autoexec.fs est présent. Si c'est le cas, ESP32forth charge automatiquement le contenu de ce fichier. Ici, il ne contient que le mot main qui va charger l'ensemble du projet contenu dans le fichier /spiffs/main.fs.

Du coté de la carte MASTER, elle reste connectée au PC via le terminal. Mais rien n'interdit de faire évoler son interface, par exemple en gérant des contacteurs, dont la gestion transmettra les trames vers SLAVE1.

Dans notre projet, nous n'avons programmé que deux cartes. Dans la réalité, vous pouvez programmer jusqu'à 20 cartes cibles pour une carte maîtresse.

Il est également possible d'exploiter une adresse MAC cible broadcast: FF:FF:FF:FF:FF:FF. Avec le protocole adéquat, par exemple en réservant les deux ou trois premiers octets en début de message, vous pourriez adresser un nombre beaucoup plus élevé de cartes cibles.

En résumé, la maîtrise du réseau ESP-NOW ouvre des perspectives très intéressantes pour toute application IoT (Internet of Things) ou domotique.

Démonstration en vidéo

Dans cette vidéo, la carte SLAVE1 a été placée à 15 mètres de la carte MASTER. Elle est alimentée par un bloc autonome via une batterie lithium. A la mise sous tension, les trois LEDs s'allument rapidement pour confirmer l'initialisation du programme.

Toutes les commandes d'allumage des LEDs sont tranmises par la carte MASTER, en incrustation dans la vidéo.

La communication ESP-NOW est gérée en peer-to-peer, c'est à dire sans l'aide d'aucun routeur WiFi.


Legal: site web personnel sans commerce / personal site without seling