Communication Bidirectionnelle entre esp32 via ESP-NOW
Description :
Dans ce projet, nous mettons en place une communication bidirectionnelle sans fil entre deux microcontrôleurs ESP32 en utilisant le protocole propriétaire ESP-NOW d’Espressif.
Chaque carte dispose de son propre bouton poussoir et de sa propre LED. Lorsqu’on appuie sur le bouton de la première carte, l’état de la LED sur la seconde carte s’inverse instantanément (mode toggle), et inversement.
Prérequis :
- 2x ESP32
- 2 x LED
- 2 x Résistance 220Ω
- 2 x Bouton
- 2 x Breadboard
Version IDE :
- Arduino IDE 2.3.7
Vidéo de démonstration :
NA
Schéma de câblage :


Code Émetteur / Récepteur :
#include <esp_now.h>
#include <WiFi.h>
// --- CONFIGURATION DES BROCHES ---
const int BUTTON_PIN = 5; // Broche du bouton poussoir (avec résistance de tirage interne PULLUP)
const int LED_PIN = 2; // Broche de la LED
// --- ADRESSE MAC DE L'AUTRE ESP32 ---
// Remplacez cette adresse par l'adresse MAC de l'autre carte ESP32
uint8_t peerAddress[] = {0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF};
// Structure des données échangées
typedef struct struct_message {
bool buttonState; // Indique un ordre de changement d'état
} struct_message;
struct_message myData;
// Variables pour l'anti-rebond du bouton
bool lastButtonState = HIGH;
unsigned long lastDebounceTime = 0;
const unsigned long debounceDelay = 50;
// --- CALLBACK DE RÉCEPTION (Quand l'autre ESP32 nous envoie un ordre) ---
void OnDataRecv(const esp_now_recv_info *info, const uint8_t *incomingData, int len) {
struct_message receivedData;
memcpy(&receivedData, incomingData, sizeof(receivedData));
// Inverser l'état actuel de notre propre LED à chaque appui distant
int currentLedState = digitalRead(LED_PIN);
digitalWrite(LED_PIN, !currentLedState);
Serial.print("Ordre reçu ! Nouvelle LED : ");
Serial.println(!currentLedState ? "ALLUMÉE" : "ÉTEINTE");
}
// --- CALLBACK D'ENVOI (Confirmation de transmission) ---
void OnDataSent(const wifi_tx_info_t *info, esp_now_send_status_t status) {
if (status == ESP_NOW_SEND_SUCCESS) {
Serial.println("Message transmis avec succès à l'autre ESP32");
} else {
Serial.println("Échec de la transmission");
}
}
void setup() {
Serial.begin(115200);
delay(1000);
pinMode(BUTTON_PIN, INPUT_PULLUP);
pinMode(LED_PIN, OUTPUT);
digitalWrite(LED_PIN, LOW); // LED éteinte au démarrage
// 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 notre propre adresse MAC (utile pour configurer l'autre carte)
Serial.println();
Serial.print("Adresse MAC de cet ESP32 : ");
Serial.println(WiFi.macAddress());
// Initialisation d'ESP-NOW
if (esp_now_init() != ESP_OK) {
Serial.println("Erreur d'initialisation ESP-NOW");
return;
}
// Enregistrement des callbacks
esp_now_register_recv_cb(OnDataRecv);
esp_now_register_send_cb(OnDataSent);
// Enregistrement de l'autre ESP32 en tant que pair (peer)
esp_now_peer_info_t peerInfo;
memset(&peerInfo, 0, sizeof(peerInfo));
memcpy(peerInfo.peer_addr, peerAddress, 6);
peerInfo.channel = 0;
peerInfo.encrypt = false;
if (esp_now_add_peer(&peerInfo) != ESP_OK) {
Serial.println("Échec de l'ajout du pair (peer)");
return;
}
Serial.println("Système bidirectionnel prêt !");
}
void loop() {
int reading = digitalRead(BUTTON_PIN);
// Gestion de l'anti-rebond du bouton local
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é
}
// Envoi du message à l'autre ESP32
esp_err_t result = esp_now_send(peerAddress, (uint8_t *)&myData, sizeof(myData));
if (result == ESP_OK) {
Serial.println("Bouton pressé : ordre d'inversion envoyé.");
} else {
Serial.println("Erreur lors de l'envoi.");
}
}
}
lastButtonState = reading;
}
