For this week's assignment, I simply had an ESP32-C3 communicate with an ESP32-S3 sense. Additionally, I committed a cardinal sin of HTMAA and forgot to take photos. For this I enlisted the help of Gert who connected the S3 to his computer and I connected the C3 to my computer. I used the ESP-NOW protocol (the ESP’s wifi) to have the two microcontrollers communicate with each other and used chat-gpt to write and debug the code. At first we ran the below code to get the MAC addresses for the receiver (S3):
#include
#include "esp_wifi.h"
void setup() {
Serial.begin(115200);
while (!Serial) {}
WiFi.mode(WIFI_STA);
delay(500);
uint8_t mac[6];
esp_wifi_get_mac(WIFI_IF_STA, mac);
Serial.print("STA MAC: ");
for (int i = 0; i < 6; i++) {
if (i) Serial.print(":");
Serial.printf("%02X", mac[i]);
}
Serial.println();
}
void loop() {}
We used the MAC address in the Sender code below, that I am censoring out. Below is the sender and receiver code we used.
// Sender – XIAO ESP32-C3 (ESP-NOW)
#include
#include
// Packet structure – must match the S3 receiver
#pragma pack(push, 1)
typedef struct {
int32_t id;
float value;
char text[32];
} Packet;
#pragma pack(pop)
// S3's STA MAC: XX:XX:XX:XX:X:XX
uint8_t receiverMAC[] = {0xXX, 0xXX, 0xXX, 0xXX, 0xXX, 0xXX};
// NEW-style send callback: first arg is wifi_tx_info_t*,
// and on this core the destination MAC is in info->des_addr.
void onSent(const wifi_tx_info_t *info, esp_now_send_status_t status) {
Serial.print("Send status: ");
Serial.println(status == ESP_NOW_SEND_SUCCESS ? "Success" : "Fail");
Serial.print("To MAC: ");
for (int i = 0; i < 6; i++) {
if (i) Serial.print(":");
Serial.printf("%02X", info->des_addr[i]);
}
Serial.println();
}
void setup() {
Serial.begin(115200);
while (!Serial) {}
Serial.println();
Serial.println("ESP-NOW Sender (C3) starting...");
WiFi.mode(WIFI_STA); // required for ESP-NOW
// Optional: print this board's MAC
Serial.print("C3 STA MAC: ");
Serial.println(WiFi.macAddress());
// Init ESP-NOW
if (esp_now_init() != ESP_OK) {
Serial.println("ESP-NOW init failed");
return;
}
// Register send callback (new signature)
esp_now_register_send_cb(onSent);
// Add S3 as peer
esp_now_peer_info_t peerInfo = {};
memcpy(peerInfo.peer_addr, receiverMAC, 6);
peerInfo.channel = 0; // 0 = current WiFi channel
peerInfo.encrypt = false;
if (esp_now_add_peer(&peerInfo) != ESP_OK) {
Serial.println("Failed to add peer");
return;
}
Serial.println("Sender ready.");
}
void loop() {
static uint32_t counter = 0;
Packet pkt;
pkt.id = counter++;
pkt.value = 123.45f;
strncpy(pkt.text, "hello from C3", sizeof(pkt.text));
pkt.text[sizeof(pkt.text) - 1] = '\0'; // ensure null-terminated
esp_err_t res = esp_now_send(receiverMAC, (uint8_t*)&pkt, sizeof(pkt));
if (res != ESP_OK) {
Serial.print("Send error: ");
Serial.println(res);
}
delay(1000); // send once per second
}
// Receiver – XIAO ESP32-S3 (ESP-NOW)
#include
#include
#include "esp_wifi.h" // for esp_wifi_get_mac
// Packet structure (must match sender)
#pragma pack(push, 1)
typedef struct {
int32_t id;
float value;
char text[32];
} Packet;
#pragma pack(pop)
// New-style ESP-NOW receive callback (for ESP32 core 3.x+)
void onReceive(const esp_now_recv_info_t *info,
const uint8_t *incomingData,
int len) {
Packet pkt;
if (len != sizeof(Packet)) {
Serial.print("Unexpected length: ");
Serial.println(len);
return;
}
memcpy(&pkt, incomingData, sizeof(pkt));
// Sender MAC is now in info->src_addr
const uint8_t *mac = info->src_addr;
Serial.print("From MAC: ");
for (int i = 0; i < 6; i++) {
if (i) Serial.print(":");
Serial.printf("%02X", mac[i]);
}
Serial.println();
Serial.print("id=");
Serial.print(pkt.id);
Serial.print(" value=");
Serial.print(pkt.value);
Serial.print(" text=");
Serial.println(pkt.text);
}
void setup() {
Serial.begin(115200);
while (!Serial) {}
Serial.println();
Serial.println("ESP-NOW Receiver (S3) starting...");
// Put radio in station mode (required for ESP-NOW)
WiFi.mode(WIFI_STA);
// Print this board's real STA MAC using esp_wifi_get_mac
uint8_t mac[6];
esp_wifi_get_mac(WIFI_IF_STA, mac);
Serial.print("S3 STA MAC: ");
for (int i = 0; i < 6; i++) {
if (i) Serial.print(":");
Serial.printf("%02X", mac[i]);
}
Serial.println();
// Init ESP-NOW
if (esp_now_init() != ESP_OK) {
Serial.println("ESP-NOW init failed");
return;
}
// Register receive callback (new signature)
esp_now_register_recv_cb(onReceive);
Serial.println("Receiver ready.");
}
void loop() {
// Nothing here; everything happens in onReceive()
}
When the code worked, I changed the phrase that the C3 sent and we observed how long it took for the receiver code to change. It took a couple seconds which was longer than we expected. Below are screenshots of our computer screens showing the code working.