Skip to content

Week 11 - Network and Communication

Group Assignment :

Send a message between two projects

For this week’s group assignment, Ashish and Ancy communicated with their projects using ESP-NOW.

In the group assignment, two separate projects were successfully connected using ESP-NOW communication. Ashish’s board was equipped with an RFID reader and programmed to detect two different RFID tags. When the first tag was scanned, the board sent a message via ESP-NOW to Ancy’s first board, which responded by lighting up a NeoPixel LED in red. When the second tag was scanned, a different message was sent to Ancy’s second board, triggering its NeoPixel to light up in green. This communication was made possible by using the unique MAC addresses of the receiver boards, allowing Ashish’s board to send specific messages to each target.

Ancy’s project involved communication using ESP-NOW as a communication protocol to communicate between her boards, which used local input of VL53L0X Time of Flight Sensor and Push Button. Communication Protocol - ESP_NOW

Ashish’s Project involved communication using ESP-NOW from Inputs: Button and a RFID Module.. Communication Protocol - ESP-NOW & RFID

espnow_mqtt.jpg

The Time of Flight Sensor detects the distance and if the distance is equal to 15 cm it sends a MQTT message to the broker and the MQTT subscribers can get the Morse code all over the network. And also whenever the distance goes lower, the ESP-NOW network communciates to light up a led in it’s network. ESP-NOW and MQTT work in parallel.

Sender Board Overview

The sender board is a XIAO ESP32 equipped with an MFRC522 RFID reader. Its main job is to detect RFID cards and send messages over ESP-NOW to the appropriate receiver nodes. Each RFID card is mapped to a specific receiver, so when a card is tapped, the board reads its UID, identifies the target node, and sends a small message containing the target ID. This allows the sender to trigger actions on multiple nodes in a mesh network without relying on Wi-Fi or other infrastructure.

The code for Ashish’s Board which has a RFID Scanner is a given below

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

#define RST_PIN 22
#define SS_PIN 21

MFRC522 rfid(SS_PIN, RST_PIN);

// MACs of Node 1 and Node 2
uint8_t mac_node1[] = {0x8C, 0xBF, 0xEA, 0xCB, 0x7E, 0xC8};  // Node 1
uint8_t mac_node2[] = {0x7C, 0x2C, 0x67, 0x64, 0xBA, 0xF8};  // Node 2

typedef struct struct_message {
  char target_id[10];
} struct_message;

struct_message msg;

void sendTo(uint8_t *mac, const char *target) {
  strcpy(msg.target_id, target);
  esp_now_send(mac, (uint8_t *)&msg, sizeof(msg));
  Serial.print("Sent to ");
  Serial.println(target);
}

void setup() {
  Serial.begin(115200);
  SPI.begin();
  rfid.PCD_Init();

  WiFi.mode(WIFI_STA);
  WiFi.disconnect();

  if (esp_now_init() != ESP_OK) {
    Serial.println("ESP-NOW init failed");
    return;
  }

  esp_now_peer_info_t peerInfo = {};
  peerInfo.channel = 0;
  peerInfo.encrypt = false;

  memcpy(peerInfo.peer_addr, mac_node1, 6);
  esp_now_add_peer(&peerInfo);

  memcpy(peerInfo.peer_addr, mac_node2, 6);
  esp_now_add_peer(&peerInfo);
}

void loop() {
  if (rfid.PICC_IsNewCardPresent() && rfid.PICC_ReadCardSerial()) {
    Serial.print("UID: ");
    String uid = "";
    for (byte i = 0; i < rfid.uid.size; i++) {
      uid += String(rfid.uid.uidByte[i] < 0x10 ? "0" : "");
      uid += String(rfid.uid.uidByte[i], HEX);
    }
    uid.toUpperCase();
    Serial.println(uid);

    // Example logic: send based on specific UID
    if (uid == "AB12CD34") {
      sendTo(mac_node1, "node1");
    } else if (uid == "EF56AB78") {
      sendTo(mac_node2, "node2");
    }

    rfid.PICC_HaltA();
    rfid.PCD_StopCrypto1();
    delay(1000);  // Debounce
  }
}

How the Code Works

Hardware Setup

  • SPI.begin() starts SPI communication, which is needed for the MFRC522 RFID module.
  • rfid.PCD_Init() initializes the RFID reader so it’s ready to scan cards.

ESP-NOW Setup

  • The ESP32 is switched into station mode (WIFI_STA).
  • ESP-NOW is initialized, and two peers (Node 1 and Node 2) are added using their MAC addresses.

Main Loop

  • The board continuously checks for new RFID cards.
  • When a card is detected, its UID is read and converted into a hex string.
  • If the UID matches AB12CD34, the code sends a message to Node 1.
  • If the UID matches EF56AB78, the message is sent to Node 2.
  • The message itself is packed into a small struct (msg) which currently only holds a string called target_id.

Receiver Board Overview

The receiver board is a XIAO ESP32 that listens for ESP-NOW messages from the RFID reader node. Each board has a unique ID (my_id) to identify which messages are meant for it. When a message matching its ID arrives, the board provides a visual cue by lighting up a NeoPixel LED. This setup allows multiple nodes to react independently to different RFID tags, making it easy to coordinate actions in a small mesh network.

The code for Ancy’s Board

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

#define LED_PIN 18
Adafruit_NeoPixel pixel(1, LED_PIN, NEO_GRB + NEO_KHZ800);

// Receiver ID — change this per board
char my_id[] = "node1";  // Or "node2" for second node

typedef struct struct_message {
  char target_id[10];
} struct_message;

struct_message msg;

void OnDataRecv(const esp_now_recv_info_t *info, const uint8_t *incomingData, int len) {
  memcpy(&msg, incomingData, sizeof(msg));
  Serial.print("Received for target: ");
  Serial.println(msg.target_id);

  if (strcmp(msg.target_id, my_id) == 0) {
    // Light up if message is for this node
    pixel.setPixelColor(0, pixel.Color(0, 255, 0));  // Red
    pixel.show();
    delay(1000);
    pixel.clear();
    pixel.show();
  }
}

void setup() {
  Serial.begin(115200);
  pixel.begin();
  pixel.clear();
  pixel.show();

  WiFi.mode(WIFI_STA);
  WiFi.disconnect();

  if (esp_now_init() != ESP_OK) {
    Serial.println("ESP-NOW init failed");
    return;
  }

  esp_now_register_recv_cb(OnDataRecv);
}

void loop() {
  // Nothing needed
}

How the Receiver Code Works

Hardware Setup

  • Uses a NeoPixel LED (connected to pin 18).
  • Each board is assigned an ID with my_id (e.g., "node1" or "node2").
  • The LED will light up only when a message intended for that specific node is received.

ESP-NOW Setup

  • The ESP32 is set to station mode (WIFI_STA) and disconnected from Wi-Fi.
  • ESP-NOW is initialized, and a callback function (OnDataRecv) is registered to handle incoming messages.

Receiving Messages

  • When a message arrives, the data is copied into the msg struct.
  • The code checks if msg.target_id matches the board’s own ID (my_id).
  • If it matches, the NeoPixel LED briefly lights up green as an indicator, then turns off again.
  • If the ID doesn’t match, nothing happens (the message is ignored).

Conclusion

This project demonstrates a simple, low-power mesh network using XIAO ESP32 boards with ESP-NOW. The sender board reads RFID tags and sends targeted messages to designated receiver nodes, which respond by lighting up a NeoPixel LED. This setup highlights how ESP-NOW enables fast, reliable, and infrastructure-free communication between multiple devices.


Last update: August 27, 2025