ESP-NOW gestion de la couche applicative
publication: 3 janvier 2026 / mis à jour 5 janvier 2026
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:
RecvMacAddr: reçoit les 6 octets qui identifient l'adresse MAC de l'émetteur de la transmission ESP-NOW;RecvDataStr: reçoit la chaine texte transmise par l'émetteur ESP-NOW.
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:
- transmission de commandes FORTH exclusivement. Ceci peut être contourné en élaborant un traitement plus fin des données transmises;
- transmission de texte exclusivement. Même réponse que ci-dessus.
Puis voici les avantages:
- transmission de commandes forth en rapport avec la couche applicative. La couche applicative peut être testée intensivement et de manière détaillée avant l'interfaçage avec la transmission ESP-NOW
- interfaçage simplifié à l'extrême. La couche applicative ignore totalement la transmission ESP-NOW, car les commandes applicatives passent par l'interpréteur FORTH.
- Une intégration applicative très simplifiée coté carte émettrice.
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
