Communication unidirectionnelle entre esp32 via ESP-NOW
Description :
Ce projet présente un montage simple et ultra-rapide permettant de faire communiquer deux cartes ESP32 sans routeur ni connexion Wi-Fi externe, en utilisant le protocole propriétaire ESP-NOW d’Espressif.
L’objectif est de contrôler à distance une LED (sur le récepteur) à l’aide d’un simple bouton poussoir (sur l’émetteur).
Prérequis :
- 2x ESP32
- 1 x LED
- 1 x Résistance 220Ω
- 1 x Bouton
- 2 x Breadboard
Version IDE :
- Arduino IDE 2.3.7
Vidéo de démonstration :
Schéma de câblage :


Code Émetteur (Sender) :
#include <esp_now.h>
#include <WiFi.h>
// Remplacez par l'adresse MAC de votre ESP32 récepteur
uint8_t broadcastAddress[] = {0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF};
const int BUTTON_PIN = 4; // Broche du bouton poussoir
// Structure des données à envoyer
typedef struct struct_message {
bool buttonState;
} struct_message;
struct_message myData;
// Variables pour l'anti-rebond
bool lastButtonState = HIGH;
unsigned long lastDebounceTime = 0;
const unsigned long debounceDelay = 50;
// Callback de confirmation d'envoi
void OnDataSent(const wifi_tx_info_t *info, esp_now_send_status_t status) {
if (status == ESP_NOW_SEND_SUCCESS) {
Serial.println("Ordre transmis avec succès");
} else {
Serial.println("Échec de la transmission");
}
}
void setup() {
Serial.begin(115200);
// Configuration de la broche du bouton (avec résistance de tirage interne PULLUP)
pinMode(BUTTON_PIN, INPUT_PULLUP);
// Mode Station Wi-Fi et initialisation d'ESP-NOW
WiFi.mode(WIFI_STA);
if (esp_now_init() != ESP_OK) {
Serial.println("Erreur d'initialisation ESP-NOW");
return;
}
esp_now_register_send_cb(OnDataSent);
// Ajout du récepteur en tant que pair (peer)
esp_now_peer_info_t peerInfo;
memset(&peerInfo, 0, sizeof(peerInfo));
memcpy(peerInfo.peer_addr, broadcastAddress, 6);
peerInfo.channel = 0;
peerInfo.encrypt = false;
if (esp_now_add_peer(&peerInfo) != ESP_OK) {
Serial.println("Échec de l'ajout du pair");
return;
}
}
void loop() {
int reading = digitalRead(BUTTON_PIN);
// Gestion de l'anti-rebond
if (reading != lastButtonState) {
lastDebounceTime = millis();
}
if ((millis() - lastDebounceTime) > debounceDelay) {
static bool currentState = HIGH;
if (reading != currentState) {
currentState = reading;
// Envoi 'true' si pressé (LOW), 'false' si relâché (HIGH)
if (currentState == LOW) {
myData.buttonState = true; // Le bouton est pressé
} else {
myData.buttonState = false; // Le bouton est relâché
}
esp_err_t result = esp_now_send(broadcastAddress, (uint8_t *)&myData, sizeof(myData));
if (result == ESP_OK) {
Serial.print("Bouton envoyé : ");
Serial.println(myData.buttonState ? "PRESSÉ" : "RELÂCHÉ");
} else {
Serial.println("Erreur d'envoi");
}
}
}
lastButtonState = reading;
}
Code Récepteur (Receiver) :
#include <esp_now.h>
#include <WiFi.h>
const int LED_PIN = 2; // Broche de la LED (GPIO 2 par défaut)
// Structure des données (doit être identique à l'émetteur)
typedef struct struct_message {
bool buttonState;
} struct_message;
struct_message myData;
// Callback de réception des données (Signature mise à jour pour core ESP32 v3.x)
void OnDataRecv(const esp_now_recv_info *info, const uint8_t *incomingData, int len) {
// Récupération de l'adresse MAC de l'émetteur
char macStr[18];
snprintf(macStr, sizeof(macStr), "%02x:%02x:%02x:%02x:%02x:%02x",
info->src_addr[0], info->src_addr[1], info->src_addr[2],
info->src_addr[3], info->src_addr[4], info->src_addr[5]);
// Copie des données reçues dans la structure
memcpy(&myData, incomingData, sizeof(myData));
// Piloter la LED en fonction de l'état du bouton reçu
digitalWrite(LED_PIN, myData.buttonState ? HIGH : LOW);
Serial.print("Reçu de [");
Serial.print(macStr);
Serial.print("] -> LED : ");
Serial.println(myData.buttonState ? "ALLUMÉE" : "ÉTEINTE");
}
void setup() {
Serial.begin(115200);
delay(1000); // Petite pause pour laisser le temps au port série de s'ouvrir
// Mode Station Wi-Fi requis pour ESP-NOW
WiFi.mode(WIFI_STA);
delay(100); // Laisser un court instant au contrôleur Wi-Fi pour s'initialiser
// --- AFFICHAGE DE L'ADRESSE MAC DU RÉCEPTEUR ---
Serial.println();
Serial.print("Adresse MAC de ce récepteur : ");
Serial.println(WiFi.macAddress());
// ----------------------------------------------
// Configuration de la broche de la LED en sortie
pinMode(LED_PIN, OUTPUT);
digitalWrite(LED_PIN, LOW); // Éteinte au démarrage
// Initialisation d'ESP-NOW
if (esp_now_init() != ESP_OK) {
Serial.println("Erreur d'initialisation ESP-NOW");
return;
}
// Enregistrement du callback de réception
esp_now_register_recv_cb(OnDataRecv);
Serial.println("Récepteur ESP-NOW prêt, en attente d'ordres...");
}
void loop() {
// Rien à mettre ici, tout est géré en arrière-plan par le callback de réception.
}
