How to Control 8 LEDs with 8 Buttons & ESP-NOW on ESP32 diagram

How to Control 8 LEDs with 8 Buttons & ESP-NOW on ESP32
 

Hello everyone, to our loyal subscribers and new visitors! We hope you're all doing well. In this video, we present an educational project aimed at explaining the basics of wireless control using the ESP32. The system is a practical model consisting of a transmitter with 8 buttons to control 8 LEDs remotely via the fast ESP-NOW protocol. The corresponding LED lights up on button press and turns off on release, making it ideal for learning communication principles between microcontrollers.
 
 Learn how to build a wireless control system with ESP32! In this video, we demonstrate how to use ESP-NOW protocol to communicate between two ESP32 modules. We'll connect 8 buttons on the transmitter side and 8 LEDs on the receiver side, allowing you to control each LED individually completely wirelessly. This step-by-step tutorial covers the wiring, code, and setup, so you can get your multi-button controller running quickly. Great for home automation or robotics!, making it perfect for your next IoT project.

components you'll need: 
1. Two ESP32 development boards. 
2. 8 push buttons. 
3. 9 LEDs. 
4. Resistors (typically 220-330 ohms for the LEDs). 
5. Breadboards. 
6. Jumper wires. 
7. A power source for each ESP32. 

Sender side: 
1. Take your first ESP32. 
2. Connect one pin of your first button to GPIO pin 13, for example, and the other side to a Ground pin. 
3. Repeat this for the next button on pin 12 and so on, each going to a different pin and Ground. 
Receiver side: 
1. Take your second ESP32. 
2. Connect one lead of your first LED to pin 12, connected to a 220-ohm resistor, and the other side to Ground. Repeat that for each LED with a resistor on its own pin and Ground

Diagram : 

Transmitter 




Receiver


Code :

Transmitter

// - Lien vidéo: https://youtu.be/98bRYcEl5ko

#include <esp_now.h>
#include <WiFi.h>

// REPLACE WITH YOUR RECEIVER MAC Address
uint8_t RxMACaddress[] = {0x24, 0x37, 0xB8, 0xAE, 0xEF, 0x79}; //ESP32
esp_now_peer_info_t peerInfo; // Variables to manage state changes

// Define button pins
const int buttonPins[] = {T4, T5, T6, T7, T8, T9, T2, T3};

volatile int pressedButtonID = 0;
volatile int idtouch = 0;
const int numButtons = 8;
const int ledPin = 23;

const uint8_t comand[numButtons] = {0xB1, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7, 0xB8};
const uint8_t Datacomd[numButtons] = {0x9F, 0x9E, 0xBC, 0xAD, 0xFD, 0xA4, 0x3F, 0x94};
const uint8_t Endcomd[numButtons] = {0xF9, 0xE9, 0xCB, 0xDA, 0xDF, 0x4A, 0xF3, 0x49};
volatile bool TouchPressed[numButtons];
volatile bool TouchReleased[numButtons];
volatile bool TouchLower[numButtons];

// Structure to send data (must match receiver)
typedef struct struct_message {
  uint8_t Datacom;
  uint8_t idcomd;
  bool statled;
  uint8_t Endcom;
} struct_message;
struct_message myData;

// Interrupt Service Routine (ISR)
// Declared IRAM_ATTR to run from RAM for speed
void IRAM_ATTR handleButtonPressUp(void* arg) {
  int id = (int)arg;
  if (TouchPressed[id] != TouchLower[id]) {
    TouchPressed[id] = true;
    pressedButtonID++;
  }
}
void IRAM_ATTR handleButtonPressDn(void* arg) {
  int id = (int)arg;
  if (TouchReleased[id] == TouchLower[id]) {
    TouchReleased[id] = true;
    pressedButtonID++;
  }
}

// Init ESP Now with fallback
void InitESPNow() {
  WiFi.disconnect();
  if (esp_now_init() == ESP_OK) {
    Serial.println("ESPNow Init Success");
  } else {
    Serial.println("ESPNow Init Failed");
  }
}

//Register peer
void Registerpeer() {
  memcpy(peerInfo.peer_addr, RxMACaddress, 6);
  peerInfo.channel = 0;
  peerInfo.encrypt = false;
  if (esp_now_add_peer(&peerInfo) == ESP_OK) {
    Serial.println("Add peer Success");
  } else {
    Serial.println("Failed to add peer");
  }
}

// Callback when data is sent
void OnDataSent(const uint8_t *mac_addr, esp_now_send_status_t status) {
  Serial.print("Touch ");
  Serial.print(idtouch);
  (myData.statled) ? Serial.print(" was Pressed") : Serial.print(" was Released");
  Serial.print("\t Status: ");
  if (status == ESP_NOW_SEND_SUCCESS) {
    // char macStr[18];
    // snprintf(macStr, sizeof(macStr), "%02x:%02x:%02x:%02x:%02x:%02x", mac_addr[0], mac_addr[1], mac_addr[2], mac_addr[3], mac_addr[4], mac_addr[5]);
    Serial.println("Delivery Success");
    // Serial.print("\t Last Packet Sent to: ");
    // Serial.println(macStr);
  } else {
    Serial.println("Delivery Fail");
  }
}

void setup() {
  Serial.begin(115200);
  WiFi.mode(WIFI_STA);
  InitESPNow(); // Init ESP-NOW
  esp_now_register_send_cb(OnDataSent);
  Registerpeer(); // Register peer
  // Set up button pins and attach interrupts
  for (int i = 0; i < numButtons; i++) {
    TouchPressed[i] = false;
    TouchReleased[i] = false;
    TouchLower[i] = true;
    pinMode(buttonPins[i], INPUT_PULLUP);
    attachInterruptArg(digitalPinToInterrupt(buttonPins[i]), handleButtonPressUp, (void*)i, FALLING);
  }
  pinMode(ledPin, OUTPUT);
  digitalWrite(ledPin,LOW);
}

void loop() {
  if (pressedButtonID > 0) {
    for (int i = 0; i < numButtons; i++) {
      if (TouchPressed[i] != TouchReleased[i]) {
        myData.Datacom = Datacomd[i];
        myData.idcomd = comand[i];
        myData.Endcom = Endcomd[i];
        idtouch = i + 1;
        if (TouchLower[i]) {
          attachInterruptArg(digitalPinToInterrupt(buttonPins[i]), handleButtonPressDn, (void*)i, RISING);
          digitalWrite(ledPin,HIGH);
          myData.statled = true;
          esp_now_send(RxMACaddress, (uint8_t *) &myData, sizeof(myData));
          delay(30);
          TouchPressed[i] = false;
          TouchLower[i] = false;
        } else {
          attachInterruptArg(digitalPinToInterrupt(buttonPins[i]), handleButtonPressUp, (void*)i, FALLING);
          myData.statled = false;
          esp_now_send(RxMACaddress, (uint8_t *) &myData, sizeof(myData));
          pressedButtonID -= 2;
          if (pressedButtonID <= 0) digitalWrite(ledPin,LOW);
          delay(30);
          TouchReleased[i] = false;
          TouchLower[i] = true;
        }
      }
    }
  }
}

Receiver

// - Lien vidéo: https://youtu.be/98bRYcEl5ko

#include <esp_now.h>
#include <WiFi.h>


#define numtouch 8
const uint8_t Led_pin[numtouch] = {13, 12, 14, 27, 26, 25, 33, 32};
const uint8_t comand[numtouch] = {0xB1, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7, 0xB8};
const uint8_t Datacomd[numtouch] = {0x9F, 0x9E, 0xBC, 0xAD, 0xFD, 0xA4, 0x3F, 0x94};
const uint8_t Endcomd[numtouch] = {0xF9, 0xE9, 0xCB, 0xDA, 0xDF, 0x4A, 0xF3, 0x49};
bool Led_state[numtouch];

// Structure to send data (must match receiver)
typedef struct struct_message {
  uint8_t Datacom;
  uint8_t idcomd;
  bool statled;
  uint8_t Endcom;
} struct_message;
struct_message myData;

// Init ESP Now with fallback
void InitESPNow() {
  WiFi.disconnect();
  if (esp_now_init() == ESP_OK) {
    Serial.println("ESPNow Init Success");
  }
  else {
    Serial.println("ESPNow Init Failed");
    // Retry InitESPNow, add a counte and then restart?
    // InitESPNow();
    // or Simply Restart
    // ESP.restart();
  }
}
void SetCommand(int i) {
  if (myData.Datacom != Datacomd[i] || myData.Endcom != Endcomd[i])
    return;
  digitalWrite(Led_pin[i], myData.statled);
  Serial.print("Led ");
  Serial.print(i+1);
  (myData.statled) ? Serial.println(" On") : Serial.println(" Off");
}

// callback when data is recv from Master
void OnDataRecv(const uint8_t *mac_addr, const uint8_t *data, int data_len) {
  memcpy((uint8_t *)&myData, data, sizeof(data));
  int comd = (int)(myData.idcomd - 0xB1);
  if (myData.idcomd == comand[comd])
    SetCommand(comd);
}

void setup() {
  Serial.begin(115200);
  delay(2500); // give me time to bring up serial monitor
  for ( int j=0; j<numtouch;j++) {
    pinMode(Led_pin[j], OUTPUT);
    digitalWrite(Led_pin[j], LOW);
    Led_state[j] = false;
  }
  WiFi.mode(WIFI_STA);
  InitESPNow();
  esp_now_register_recv_cb(OnDataRecv);
  Serial.println();
  Serial.print("STA MAC: "); Serial.println(WiFi.macAddress());
  Serial.print("STA CHANNEL "); Serial.println(WiFi.channel());
}

void loop() {
  // greatprojects
}


 

Lien vidéo:

       https://youtu.be/98bRYcEl5ko