Group Assignment on Networking and communications
Group members
- Stanley Amaechi
- Lauri Hallman
- Shahmeer Adnan Rana
📡 Week 11 - Networking and communications (Group Work)
In this week’s group work, our task was to send a message between two projects. We chose to try wireless ESP-NOW communication between two ESP32-C3 boards using the help of this tutorial: https://randomnerdtutorials.com/esp-now-esp32-arduino-ide/. ESP-NOW is a fast, connectionless communication protocol developed by Espressif. It allows ESP32 boards to exchange small messages (up to 250 bytes) without using Wi-Fi or internet.
🔍 Getting MAC Addresses
To communicate via ESP-NOW, we need to know the MAC address of the receiving ESP32. We used the following code (from the tutorial) to get each board’s MAC address:
#include <WiFi.h>
#include <esp_wifi.h>
void readMacAddress() {
uint8_t baseMac[6];
esp_err_t ret = esp_wifi_get_mac(WIFI_IF_STA, baseMac);
if (ret == ESP_OK) {
Serial.printf("%02x:%02x:%02x:%02x:%02x:%02x\n",
baseMac[0], baseMac[1], baseMac[2],
baseMac[3], baseMac[4], baseMac[5]);
} else {
Serial.println("Failed to read MAC address");
}
}
void setup() {
Serial.begin(115200);
WiFi.mode(WIFI_STA);
// WiFi.STA.begin(); ← ❌ invalid in ESP32
Serial.print("[DEFAULT] ESP32 Board MAC Address: ");
readMacAddress();
}
void loop() {}
On one computer, we encountered this error: "Compilation error: 'class WiFiClass' has no member named 'STA'"
We fixed this with ChatGPT’s help. The line WiFi.STA.begin(); is invalid in the ESP32 Arduino framework — WiFi.STA does not exist. Simply commenting it out solved the issue and we got the MAC addresses of the ESP32-C3 boards.
ESP32-C3 board #1: 34:85:18:05:a4:20
ESP32-C3 board #2: 34:85:18:05:b8:48
📤 Transmitting Code (Board #1 → Board #2)
We used the following codes on boards #1 and #2. In the former code we modified the line: "uint8_t broadcastAddress[] = {0x34, 0x85, 0x18, 0x05, 0xb8, 0x48}; // board #2 MAC".
#include <esp_now.h>
#include <WiFi.h>
uint8_t broadcastAddress[] = {0x34, 0x85, 0x18, 0x05, 0xb8, 0x48};
typedef struct struct_message {
char a[32];
int b;
float c;
bool d;
} struct_message;
struct_message myData;
esp_now_peer_info_t peerInfo;
void OnDataSent(const uint8_t *mac_addr, esp_now_send_status_t status) {
Serial.print("\r\nLast Packet Send Status:\t");
Serial.println(status == ESP_NOW_SEND_SUCCESS ? "Delivery Success" : "Delivery Fail");
}
void setup() {
Serial.begin(115200);
WiFi.mode(WIFI_STA);
if (esp_now_init() != ESP_OK) {
Serial.println("Error initializing ESP-NOW");
return;
}
esp_now_register_send_cb(OnDataSent);
memcpy(peerInfo.peer_addr, broadcastAddress, 6);
peerInfo.channel = 0;
peerInfo.encrypt = false;
if (esp_now_add_peer(&peerInfo) != ESP_OK) {
Serial.println("Failed to add peer");
return;
}
}
void loop() {
strcpy(myData.a, "HELLO SHAHMEER😃 Random data:");
myData.b = random(1, 20);
myData.c = 1.2;
myData.d = false;
esp_err_t result = esp_now_send(broadcastAddress, (uint8_t *) &myData, sizeof(myData));
if (result == ESP_OK) {
Serial.println("Sent with success");
} else {
Serial.println("Error sending the data");
}
delay(2000);
}
📥 Receiver Code (Board #2)
#include <esp_now.h>
#include <WiFi.h>
typedef struct struct_message {
char a[32];
int b;
float c;
bool d;
} struct_message;
struct_message myData;
void OnDataRecv(const uint8_t * mac, const uint8_t *incomingData, int len) {
memcpy(&myData, incomingData, sizeof(myData));
Serial.print("Bytes received: ");
Serial.println(len);
Serial.print("Char: ");
Serial.println(myData.a);
Serial.print("Int: ");
Serial.println(myData.b);
Serial.print("Float: ");
Serial.println(myData.c);
Serial.print("Bool: ");
Serial.println(myData.d);
Serial.println();
}
void setup() {
Serial.begin(115200);
WiFi.mode(WIFI_STA);
if (esp_now_init() != ESP_OK) {
Serial.println("Error initializing ESP-NOW");
return;
}
esp_now_register_recv_cb(OnDataRecv);
}
void loop() {}
The communication was successful, and interestingly, even the UTF-8 smiley was sent correctly.
📶 Range Test
- The ESP32-C3 on board #1 was missing its mini antenna, but ESP-NOW communication still worked at a range of ~2–3 meters.
- With both antennas attached, ESP-NOW communication has achieved a range of over 200 meters in open space: https://youtu.be/qxwXwNS3Avw?t=257.
🔁 Communication in other direction + OLED Display
We tested communication in the other direction as well by:
- Uploading the transmitter code to board #2
- Updating the MAC address in the transmitter code to board #1’s
- Using an OLED screen to display the received message. We used OLED code from a Wokwi OLED demo code.
At first, the OLED didn’t show anything. There was a simple mistake ChatGPT helped to troubleshoot using the prompt "This code is not showing the transmitted data on the oled." We had placed the line oled.println(myData.a); too early in setup(), before any data had been received. Moving oled.println(myData.a); inside the OnDataRecv() callback resolved the issue.
Here’s the working receiver code with ESP-NOW + OLED:
#include <esp_now.h>
#include <WiFi.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
Adafruit_SSD1306 oled(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);
typedef struct struct_message {
char a[32];
int b;
float c;
bool d;
} struct_message;
struct_message myData;
void OnDataRecv(const uint8_t * mac, const uint8_t *incomingData, int len) {
memcpy(&myData, incomingData, sizeof(myData));
Serial.print("Bytes received: ");
Serial.println(len);
Serial.print("Char: ");
Serial.println(myData.a);
Serial.print("Int: ");
Serial.println(myData.b);
Serial.print("Float: ");
Serial.println(myData.c);
Serial.print("Bool: ");
Serial.println(myData.d);
// Update OLED display
oled.clearDisplay();
oled.setTextSize(1);
oled.setTextColor(WHITE);
oled.setCursor(0, 0);
oled.println("Received:");
oled.print("Text: "); oled.println(myData.a);
oled.print("Int: "); oled.println(myData.b);
oled.print("Float: "); oled.println(myData.c);
oled.print("Bool: "); oled.println(myData.d ? "true" : "false");
oled.display();
}
void setup() {
Serial.begin(115200);
if (!oled.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
Serial.println(F("OLED init failed"));
while (1);
}
oled.clearDisplay();
oled.setTextSize(1);
oled.setTextColor(WHITE);
oled.setCursor(0, 0);
oled.println("Waiting for data...");
oled.display();
WiFi.mode(WIFI_STA);
if (esp_now_init() != ESP_OK) {
Serial.println("ESP-NOW init failed");
return;
}
esp_now_register_recv_cb(OnDataRecv);
}
void loop() {}
The received message was successfully displayed on the OLED screen (although part of it is not visible in the photo due to the camera’s fast exposure time relative to the OLED’s refresh rate), confirming that ESP-NOW communication worked as expected.
🎯 Summary
- ESP-NOW presents a very convenient method for short message communication between ESP32 microcontrollers.