ESP-NOW broadcast: ESP32-S3 receives nothing from ESP32-C3, but ESP32-C3 receives from ESP32-S3
Hi everyone,
I am having a strange ESP-NOW issue when mixing an ESP32-S3 and an ESP32-C3.
The communication only works in one direction:
ESP32-S3 -> ESP32-C3: works
ESP32-C3 -> ESP32-S3: does not work
I simplified the test as much as possible. I am now using the same broadcast sketch on both boards. Both boards send a broadcast packet every 2 seconds, and both boards register a receive callback.
The result is:
ESP32-C3 receives the broadcast packets sent by the ESP32-S3.
ESP32-S3 never receives the broadcast packets sent by the ESP32-C3.
The ESP32-C3 receives this:
TX id=51 result=0
TX callback: OK
---- RX ----
Len: 84
From: AC:A7:04:F4:8A:EC
To: FF:FF:FF:FF:FF:FF
Received id=36 text=ping from AC:A7:04:F4:8A:EC
------------
But the ESP32-S3 only shows its own TX messages. It never enters the receive callback:
TX id=35 result=0
TX callback: OK
TX id=36 result=0
TX callback: OK
TX id=37 result=0
TX callback: OK
...
I am using Arduino IDE with esp32 by Espressif Systems 3.3.10. I also tried 4.0.0-alpha1, and the behavior was the same.
The boards are very close to each other, so it does not look like a distance/RSSI problem.
Exact boards model:
- ESP32-S3-WROOM-1-N16R8 DevKit (board used in Arduino: ESP32S3 Dev Module)
- ESP32-C3 Super Mini development board (board userd in Arduino: ESP32C3 Dev module)
Here is the current simplified broadcast test sketch. I flash exactly the same sketch to both boards:
#include <Arduino.h>
#include <WiFi.h>
#include <esp_now.h>
#include <esp_wifi.h>
#include <esp_mac.h>
#define ESPNOW_WIFI_CHANNEL 1
uint8_t broadcastMac[] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
struct __attribute__((packed)) Message {
uint32_t id;
char text[80];
};
uint32_t nextId = 1;
unsigned long lastSend = 0;
void printMac(const char* title, const uint8_t* mac) {
Serial.printf("%s %02X:%02X:%02X:%02X:%02X:%02X\n",
title,
mac[0], mac[1], mac[2],
mac[3], mac[4], mac[5]);
}
void printRadioState() {
uint8_t staMac[6] = {0};
uint8_t baseMac[6] = {0};
esp_wifi_get_mac(WIFI_IF_STA, staMac);
esp_read_mac(baseMac, ESP_MAC_WIFI_STA);
uint8_t primary = 0;
wifi_second_chan_t second = WIFI_SECOND_CHAN_NONE;
esp_wifi_get_channel(&primary, &second);
printMac("STA MAC esp_wifi_get_mac:", staMac);
printMac("STA MAC esp_read_mac: ", baseMac);
Serial.print("Real channel esp_wifi_get_channel: ");
Serial.println(primary);
Serial.print("WiFi.channel(): ");
Serial.println(WiFi.channel());
}
void OnDataRecv(const esp_now_recv_info_t *info, const uint8_t *incomingData, int len) {
Serial.println("---- RX ----");
Serial.print("Len: ");
Serial.println(len);
if (info != nullptr) {
Serial.printf("From: %02X:%02X:%02X:%02X:%02X:%02X\n",
info->src_addr[0], info->src_addr[1], info->src_addr[2],
info->src_addr[3], info->src_addr[4], info->src_addr[5]);
Serial.printf("To: %02X:%02X:%02X:%02X:%02X:%02X\n",
info->des_addr[0], info->des_addr[1], info->des_addr[2],
info->des_addr[3], info->des_addr[4], info->des_addr[5]);
}
if (len == sizeof(Message)) {
Message msg;
memcpy(&msg, incomingData, sizeof(msg));
msg.text[sizeof(msg.text) - 1] = 0;
Serial.print("Received id=");
Serial.print(msg.id);
Serial.print(" text=");
Serial.println(msg.text);
} else {
Serial.println("Unexpected packet size");
}
Serial.println("------------");
}
void OnDataSent(const wifi_tx_info_t *tx_info, esp_now_send_status_t status) {
Serial.print("TX callback: ");
Serial.println(status == ESP_NOW_SEND_SUCCESS ? "OK" : "FAIL");
}
void sendBroadcast() {
Message msg;
msg.id = nextId++;
memset(msg.text, 0, sizeof(msg.text));
snprintf(msg.text, sizeof(msg.text), "ping from %s", WiFi.macAddress().c_str());
esp_err_t result = esp_now_send(broadcastMac, (uint8_t*)&msg, sizeof(msg));
Serial.print("TX id=");
Serial.print(msg.id);
Serial.print(" result=");
Serial.println(result);
}
void setup() {
Serial.begin(115200);
delay(1500);
Serial.println();
Serial.println("Starting ESP-NOW broadcast test...");
WiFi.mode(WIFI_STA);
WiFi.STA.begin();
WiFi.setSleep(false);
unsigned long t0 = millis();
while (!WiFi.STA.started()) {
if (millis() - t0 > 3000) {
Serial.println("Timeout waiting for WIFI_STA");
break;
}
delay(10);
}
esp_wifi_set_ps(WIFI_PS_NONE);
esp_err_t chResult = esp_wifi_set_channel(ESPNOW_WIFI_CHANNEL, WIFI_SECOND_CHAN_NONE);
Serial.print("esp_wifi_set_channel result=");
Serial.println(chResult);
esp_err_t pwrResult = esp_wifi_set_max_tx_power(84);
Serial.print("esp_wifi_set_max_tx_power result=");
Serial.println(pwrResult);
int8_t txPower = 0;
esp_wifi_get_max_tx_power(&txPower);
Serial.print("TX power actual=");
Serial.print(txPower);
Serial.println(" units of 0.25 dBm");
esp_err_t protoResult = esp_wifi_set_protocol(WIFI_IF_STA, WIFI_PROTOCOL_11B);
Serial.print("esp_wifi_set_protocol result=");
Serial.println(protoResult);
printRadioState();
if (esp_now_init() != ESP_OK) {
Serial.println("Error initializing ESP-NOW");
return;
}
uint32_t espnowVersion = 0;
esp_err_t verResult = esp_now_get_version(&espnowVersion);
Serial.print("esp_now_get_version result=");
Serial.println(verResult);
Serial.print("ESP-NOW version raw=");
Serial.println(espnowVersion);
Serial.print("ESP-NOW version major=");
Serial.println(espnowVersion >> 16);
Serial.print("ESP-NOW version minor=");
Serial.println(espnowVersion & 0xFFFF);
esp_err_t rateResult = esp_wifi_config_espnow_rate(WIFI_IF_STA, WIFI_PHY_RATE_1M_L);
Serial.print("esp_wifi_config_espnow_rate result=");
Serial.println(rateResult);
esp_err_t recvCbResult = esp_now_register_recv_cb(OnDataRecv);
Serial.print("esp_now_register_recv_cb result=");
Serial.println(recvCbResult);
esp_err_t sendCbResult = esp_now_register_send_cb(OnDataSent);
Serial.print("esp_now_register_send_cb result=");
Serial.println(sendCbResult);
esp_now_peer_info_t peerInfo = {};
memcpy(peerInfo.peer_addr, broadcastMac, 6);
peerInfo.channel = ESPNOW_WIFI_CHANNEL;
peerInfo.encrypt = false;
peerInfo.ifidx = WIFI_IF_STA;
esp_err_t addResult = esp_now_add_peer(&peerInfo);
Serial.print("esp_now_add_peer broadcast result=");
Serial.println(addResult);
esp_now_rate_config_t rate_config = {};
rate_config.phymode = WIFI_PHY_MODE_11B;
rate_config.rate = WIFI_PHY_RATE_1M_L;
rate_config.ersu = false;
rate_config.dcm = false;
esp_err_t peerRateResult = esp_now_set_peer_rate_config(broadcastMac, &rate_config);
Serial.print("esp_now_set_peer_rate_config result=");
Serial.println(peerRateResult);
Serial.println("Ready. Both boards send broadcast every 2 seconds.");
}
void loop() {
if (millis() - lastSend >= 2000) {
lastSend = millis();
sendBroadcast();
}
}
Things I have already tried:
-
I first tested unicast communication with fixed peer MAC addresses.
-
When sending from ESP32-S3 to ESP32-C3, the message arrives.
-
When sending from ESP32-C3 to ESP32-S3, the message does not arrive.
-
I verified that the peer MAC was changed correctly when swapping the transmitter board.
-
Then I changed the test to broadcast to remove MAC-address mistakes from the equation.
-
With broadcast and the same sketch on both boards, the ESP32-C3 receives the ESP32-S3 packets, but the ESP32-S3 never receives the ESP32-C3 packets.
-
I tried Arduino-ESP32 core 4.0.0-alpha1 and 3.3.10.
-
I tried putting both boards very close to each other.
-
I disabled WiFi power saving with
esp_wifi_set_ps(WIFI_PS_NONE). -
I set the channel explicitly with
esp_wifi_set_channel(...). -
I forced max TX power with
esp_wifi_set_max_tx_power(84). -
I forced 802.11b only with
esp_wifi_set_protocol(WIFI_IF_STA, WIFI_PROTOCOL_11B). -
I forced ESP-NOW rate to 1 Mbps with
esp_wifi_config_espnow_rate(WIFI_IF_STA, WIFI_PHY_RATE_1M_L). -
I also tried
WiFi.STA.begin()before initializing ESP-NOW. -
The payload is only 84 bytes, so it is below the 250-byte ESP-NOW v1 limit.
Is there any known issue or special setting when receiving ESP-NOW packets on an ESP32-S3 from an ESP32-C3?
Could this be related to PHY mode, board selection, antenna configuration, ESP-NOW version, or some ESP32-C3 / ESP32-S3 interoperability issue?
Any ideas on what else I should check would be appreciated.
COMPLETE C3 DEBUG:
Starting ESP-NOW broadcast test...
esp_wifi_set_channel result=0
esp_wifi_set_max_tx_power result=0
TX power actual=80 units of 0.25 dBm
esp_wifi_set_protocol result=0
STA MAC esp_wifi_get_mac: 20:6E:F1:70:D9:50
STA MAC esp_read_mac: 20:6E:F1:70:D9:50
Real channel esp_wifi_get_channel: 1
WiFi.channel(): 1
esp_now_get_version result=0
ESP-NOW version raw=2
ESP-NOW version major=0
ESP-NOW version minor=2
esp_wifi_config_espnow_rate result=0
esp_now_register_recv_cb result=0
esp_now_register_send_cb result=0
esp_now_add_peer broadcast result=0
esp_now_set_peer_rate_config result=0
Ready. Both boards send broadcast every 2 seconds.
TX id=1 result=0
TX callback: OK
---- RX ----
Len: 84
From: AC:A7:04:F4:8A:EC
To: FF:FF:FF:FF:FF:FF
Received id=96 text=ping from AC:A7:04:F4:8A:EC
TX id=2 result=0
TX callback: OK
---- RX ----
Len: 84
From: AC:A7:04:F4:8A:EC
To: FF:FF:FF:FF:FF:FF
Received id=97 text=ping from AC:A7:04:F4:8A:EC
COMPLETE S3 DEBUG:
Starting ESP-NOW broadcast test...
esp_wifi_set_channel result=0
esp_wifi_set_max_tx_power result=0
TX power actual=80 units of 0.25 dBm
esp_wifi_set_protocol result=0
STA MAC esp_wifi_get_mac: AC:A7:04:F4:8A:EC
STA MAC esp_read_mac: AC:A7:04:F4:8A:EC
Real channel esp_wifi_get_channel: 1
WiFi.channel(): 1
esp_now_get_version result=0
ESP-NOW version raw=2
ESP-NOW version major=0
ESP-NOW version minor=2
esp_wifi_config_espnow_rate result=0
esp_now_register_recv_cb result=0
esp_now_register_send_cb result=0
esp_now_add_peer broadcast result=0
esp_now_set_peer_rate_config result=0
Ready. Both boards send broadcast every 2 seconds.
TX id=1 result=0
TX callback: OK
TX id=2 result=0
TX callback: OK
TX id=3 result=0
TX callback: OK










