ESP-NOW between ESP32-S3 and ESP32-C3 works only one way

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


ESP-now two way communication between a ESP32-S3 and ESP32-C3

transmitter starts the conversation 9 receiver MAC required

// ESP32 Transmitter - two way communication using ESP_NOW
// NOTE: updated to use ESP32 core V3.x
//  note- no sensors so test data structure transmitted

// original code from
/*
  Rui Santos
  Complete project details at https://RandomNerdTutorials.com/esp-now-two-way-communication-esp32/
  
  Permission is hereby granted, free of charge, to any person obtaining a copy
  of this software and associated documentation files.
  
  The above copyright notice and this permission notice shall be included in all
  copies or substantial portions of the Software.
*/

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

//#include <Wire.h>
//#include <Adafruit_Sensor.h>
//#include <Adafruit_BME280.h>


//Adafruit_BME280 bme;

// initially test with broadcast address - sends to all receivers
//uint8_t broadcastAddress[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};  // ESP-NOW broadcast address
// REPLACE WITH THE MAC Address of your receiver
//uint8_t broadcastAddress[] = { 0x68, 0xB6, 0xB3, 0x2C, 0x16, 0x08};
uint8_t broadcastAddress[] = { 0x10, 0x91, 0xA8, 0x02, 0x00, 0xE8};

// Define variables to store BME280 readings to be sent
float temperature = 3.14159;
float humidity = 90.0;
float pressure = 10.0;

// Define variables to store incoming readings
float incomingTemp;
float incomingHum;
float incomingPres;

// Variable to store if sending data was successful
String success;

//Structure example to send data
//Must match the receiver structure
typedef struct struct_message {
  float temp;
  float hum;
  float pres;
} struct_message;

// Create a struct_message called BME280Readings to hold sensor readings
struct_message BME280Readings;

// Create a struct_message to hold incoming sensor readings
struct_message incomingReadings;
bool incomingReadingsOK = false;

esp_now_peer_info_t peerInfo;

// Callback when data is sent
void OnDataSent(const esp_now_send_info_t* mac_addr, esp_now_send_status_t status) {
  Serial.print("Last Packet Send Status:\t");
  Serial.println(status == ESP_NOW_SEND_SUCCESS ? "Delivery Success" : "Delivery Fail");
  if (status == 0) success = "Delivery Success :)";
  else success = "Delivery Fail :(";
}

// Callback when data is received
void OnDataRecv(const esp_now_recv_info_t* mac, const unsigned char* incomingData, int len) {
  memcpy(&incomingReadings, incomingData, sizeof(incomingReadings));
  Serial.printf("From %02X:%02X:%02X:%02X:%02X:%02X",
                mac->src_addr[0], mac->src_addr[1], mac->src_addr[2], mac->src_addr[3], mac->src_addr[4], mac->src_addr[5]);
  Serial.printf(" Bytes received: %d\n", len);
  incomingTemp = incomingReadings.temp;
  incomingHum = incomingReadings.hum;
  incomingPres = incomingReadings.pres;
  incomingReadingsOK = true;
}

void setup() {
  // Init Serial Monitor
  Serial.begin(115200);
  delay(3000);
  Serial.println("\n\n **** ESP-NOW transmitter *****");
  // Init BME280 sensor
  /*bool status = bme.begin(0x76);  
  if (!status) {
    Serial.println("Could not find a valid BME280 sensor, check wiring!");
   // while (1);
  }*/

  // Set device as a Wi-Fi Station
  WiFi.mode(WIFI_STA);
  delay(100);  // short delay for initialisation
  Serial.print("WiFi MAC address ");
  Serial.println(WiFi.macAddress());
  // Init ESP-NOW
  if (esp_now_init() != ESP_OK) {
    Serial.println("Error initializing ESP-NOW");
    return;
  }
  delay(100);  // short delay for initialisation
  byte mac[6];
  WiFi.macAddress(mac);
  Serial.printf("ESP-NOW initialised MAC address %02X:%02X:%02X:%02X:%02X:%02X\n",
                mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
  // Once ESPNow is successfully Init, we will register for Send CB to
  // get the status of Trasnmitted packet
  esp_now_register_send_cb(OnDataSent);

  // Register peer
  memcpy(peerInfo.peer_addr, broadcastAddress, 6);
  peerInfo.channel = 0;
  peerInfo.encrypt = false;

  // Add peer
  if (esp_now_add_peer(&peerInfo) != ESP_OK) {
    Serial.println("Failed to add peer");
    return;
  }
  // Register for a callback function that will be called when data is received
  esp_now_register_recv_cb(OnDataRecv);
}

void loop() {
  getReadings();
  // Set values to send
  BME280Readings.temp = temperature;
  BME280Readings.hum = humidity;
  BME280Readings.pres = pressure;
  // Send message via ESP-NOW
  esp_err_t result = esp_now_send(broadcastAddress, (uint8_t*)&BME280Readings, sizeof(BME280Readings));
  if (result == ESP_OK) Serial.println("esp_now_send() returns ESP_OK");
  else                  Serial.println("esp_now_send() returns Error");
  updateDisplay();
  delay(10000);
}

void getReadings() {
  static int x = 1;
  temperature = 23.5 + x;  //bme.readTemperature();
  humidity = 78 + x;       //bme.readHumidity();
  pressure = 21 + x;       //(bme.readPressure() / 100.0F);
  x++;
}

void updateDisplay() {
  if (!incomingReadingsOK) return;
  // Display Readings in Serial Monitor
  Serial.println("INCOMING READINGS");
  Serial.print("Temperature: ");
  Serial.print(incomingReadings.temp);
  Serial.println(" ºC");
  Serial.print("Humidity: ");
  Serial.print(incomingReadings.hum);
  Serial.println(" %");
  Serial.print("Pressure: ");
  Serial.print(incomingReadings.pres);
  Serial.println(" hPa");
  Serial.println();
}

receiver receives a packet over ESP-NOW and replies

// ESP32 Receiver - two way communication using ESP_NOW
//  NOTE: updated to use ESP32 core V3.x
//  waits to receive packet from transmitter then transmits data back
//  note- no sensors so test data structure transmitted

// original code from
/*
  Rui Santos
  Complete project details at https://RandomNerdTutorials.com/esp-now-two-way-communication-esp32/
  
  Permission is hereby granted, free of charge, to any person obtaining a copy
  of this software and associated documentation files.
  
  The above copyright notice and this permission notice shall be included in all
  copies or substantial portions of the Software.
*/

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

//#include <Wire.h>
//#include <Adafruit_Sensor.h>
//#include <Adafruit_BME280.h>
//Adafruit_BME280 bme;

// this will be setup when a packet is received with transmitter MAC adddress
uint8_t broadcastAddress[] = { 0, 0, 0, 0, 0, 0 };  //{ 0xEC, 0x64, 0xC9, 0x82, 0x7D, 0x34 };  //{0x84, 0xCC, 0xA8, 0x7A, 0x56, 0x6C};

// Define variables to store BME280 readings to be sent
float temperature;
float humidity;
float pressure;

// Define variables to store incoming readings
float incomingTemp;
float incomingHum;
float incomingPres;

// Variable to store if sending data was successful
String success;

//Structure example to send data
//Must match the receiver structure
typedef struct struct_message {
  float temp;
  float hum;
  float pres;
} struct_message;

// Create a struct_message called BME280Readings to hold sensor readings
struct_message BME280Readings;

// Create a struct_message to hold incoming sensor readings
struct_message incomingReadings;

esp_now_peer_info_t peerInfo;

// Callback when data is sent
void OnDataSent(const esp_now_send_info_t* mac_addr, esp_now_send_status_t status) {
  Serial.print("Last Packet Send Status:\t");
  Serial.println(status == ESP_NOW_SEND_SUCCESS ? "Delivery Success" : "Delivery Fail");
  if (status == 0) success = "Delivery Success :)";
  else success = "Delivery Fail :(";
}

// Callback when data is received
void OnDataRecv(const esp_now_recv_info_t* mac, const unsigned char* incomingData, int len) {
  memcpy(&incomingReadings, incomingData, sizeof(incomingReadings));
  // if no broadcast address set it up to transmitter MAC
  if (broadcastAddress[0] == 0) {
    memcpy(broadcastAddress, mac->src_addr, 6);       // set broadcasrAddress to received MAC address
    memcpy(peerInfo.peer_addr, broadcastAddress, 6);  // Register peer
    peerInfo.channel = 0;
    peerInfo.encrypt = false;
    // Add peer
    if (esp_now_add_peer(&peerInfo) != ESP_OK) {
      Serial.println("Failed to add peer");
      return;
    }
  }
  // display transmitter MAC address and copy data
  Serial.printf("From %02X:%02X:%02X:%02X:%02X:%02X",
                mac->src_addr[0], mac->src_addr[1], mac->src_addr[2], mac->src_addr[3], mac->src_addr[4], mac->src_addr[5]);
  Serial.printf(" Bytes received: %d\n", len);
  incomingTemp = incomingReadings.temp;
  incomingHum = incomingReadings.hum;
  incomingPres = incomingReadings.pres;
}

void setup() {
  // Init Serial Monitor
  Serial.begin(115200);
  delay(3000);
  // Init BME280 sensor
  //bool status = bme.begin(0x76);
  //if (!status) {
  //  Serial.println("Could not find a valid BME280 sensor, check wiring!");
  // while (1);
  //}
  Serial.println("\n\n **** ESP-NOW receiver *****");
  // Set device as a Wi-Fi Station
  WiFi.mode(WIFI_STA);
  delay(100);  // short delay for initialisation
  Serial.print("WiFi MAC address ");
  Serial.println(WiFi.macAddress());
  // Init ESP-NOW
  if (esp_now_init() != ESP_OK) {
    Serial.println("Error initializing ESP-NOW");
    return;
  }
  Serial.print("ESP-NOW initialised");
  // Once ESPNow is successfully Init, we will register for Send CB to
  // get the status of Trasnmitted packet
  esp_now_register_send_cb(OnDataSent);
  // Register for a callback function that will be called when data is received
  esp_now_register_recv_cb(OnDataRecv);
}

void loop() {
  delay(10000);
  getReadings();
  // Set values to send
  BME280Readings.temp = temperature;
  BME280Readings.hum = humidity;
  BME280Readings.pres = pressure;
  // Send message via ESP-NOW
  if (broadcastAddress[0] == 0)
    Serial.println("no MAC address to transmit too");
  else {
    esp_err_t result = esp_now_send(broadcastAddress, (uint8_t*)&BME280Readings, sizeof(BME280Readings));
    Serial.printf("Send too %02X:%02X:%02X:%02X:%02X:%02X ",
                  broadcastAddress[0], broadcastAddress[1], broadcastAddress[2], broadcastAddress[3], broadcastAddress[4], broadcastAddress[5]);
   if (result == ESP_OK) Serial.println("esp_now_send() returns ESP_OK");
  else                  Serial.println("esp_now_send() returns Error");
    updateDisplay();
  }
}
void getReadings() {
  static int x = 1;
  temperature = 33.5 + x;  //bme.readTemperature();
  humidity = 88 + x;       //bme.readHumidity();
  pressure = 212 + x;      //(bme.readPressure() / 100.0F);
  x++;
}

void updateDisplay() {
  // Display Readings in Serial Monitor
  Serial.println("INCOMING READINGS");
  Serial.print("Temperature: ");
  Serial.print(incomingReadings.temp);
  Serial.println(" ºC");
  Serial.print("Humidity: ");
  Serial.print(incomingReadings.hum);
  Serial.println(" %");
  Serial.print("Pressure: ");
  Serial.print(incomingReadings.pres);
  Serial.println(" hPa");
  Serial.println();
}

transmitter serial monitor output

**** ESP-NOW transmitter *****
WiFi MAC address 68:B6:B3:2C:16:08
ESP-NOW initialised MAC address 68:B6:B3:2C:16:08
esp_now_send() returns ESP_OK
Last Packet Send Status:	Delivery Success
From 10:91:A8:02:00:E8 Bytes received: 12
esp_now_send() returns ESP_OK
INCOMING READINGS
Temperature: 34.50 ºC
Humidity: 89.00 %
Pressure: 213.00 hPa

Last Packet Send Status:	Delivery Success
From 10:91:A8:02:00:E8 Bytes received: 12
esp_now_send() returns ESP_OK
INCOMING READINGS
Temperature: 35.50 ºC
Humidity: 90.00 %
Pressure: 214.00 hPa

Last Packet Send Status:	Delivery Success
From 10:91:A8:02:00:E8 Bytes received: 12
esp_now_send() returns ESP_OK
INCOMING READINGS
Temperature: 36.50 ºC
Humidity: 91.00 %
Pressure: 215.00 hPa

Last Packet Send Status:	Delivery Success
From 10:91:A8:02:00:E8 Bytes received: 12
esp_now_send() returns ESP_OK
INCOMING READINGS
Temperature: 37.50 ºC
Humidity: 92.00 %
Pressure: 216.00 hPa

Last Packet Send Status:	Delivery Success
From 10:91:A8:02:00:E8 Bytes received: 12
esp_now_send() returns ESP_OK
INCOMING READINGS
Temperature: 38.50 ºC
Humidity: 93.00 %
Pressure: 217.00 hPa


receiver

 **** ESP-NOW receiver *****
WiFi MAC address 10:91:A8:02:00:E8
ESP-NOW initialisedFrom 68:B6:B3:2C:16:08 Bytes received: 12
Send too 68:B6:B3:2C:16:08 esp_now_send() returns ESP_OK
INCOMING READINGS
Temperature: 24.50 ºC
Humidity: 79.00 %
Pressure: 22.Last Packet Send Status:	Delivery Success
00 hPa

From 68:B6:B3:2C:16:08 Bytes received: 12
Send too 68:B6:B3:2C:16:08 esp_now_send() returns ESP_OK
INCOMING READINGS
Temperature: 25.50 ºC
Humidity: 80.00 %
Pressure: 23.Last Packet Send Status:	Delivery Success
00 hPa

From 68:B6:B3:2C:16:08 Bytes received: 12
Send too 68:B6:B3:2C:16:08 esp_now_send() returns ESP_OK
INCOMING READINGS
Temperature: 26.50 ºC
Humidity: 81.00 %
Pressure: 24.Last Packet Send Status:	Delivery Success
00 hPa

From 68:B6:B3:2C:16:08 Bytes received: 12
Send too 68:B6:B3:2C:16:08 esp_now_send() returns ESP_OK
INCOMING READINGS
Temperature: 27.50 ºC
Humidity: 82.00 %
Pressure: 25.Last Packet Send Status:	Delivery Success
00 hPa

From 68:B6:B3:2C:16:08 Bytes received: 12
Send too 68:B6:B3:2C:16:08 esp_now_send() returns ESP_OK
INCOMING READINGS
Temperature: 28.50 ºC
Humidity: 83.00 %
Pressure: 26.Last Packet Send Status:	Delivery Success

will try your code and see if it works

ran code from post 1

ESP32-S3-DevKitC-1 output

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: 68:B6:B3:2C:16:08
STA MAC esp_read_mac:     68:B6:B3:2C:16:08
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
TX id=4 result=0
TX callback: OK
TX id=5 result=0
TX callback: OK
TX id=6 result=0
TX callback: OK
---- RX ----
Len: 84
From: 10:91:A8:02:00:E8
To: FF:FF:FF:FF:FF:FF
Received id=1 text=ping from 10:91:A8:02:00:E8
------------
TX id=7 result=0
TX callback: OK
---- RX ----
Len: 84
From: 10:91:A8:02:00:E8
To: FF:FF:FF:FF:FF:FF
Received id=2 text=ping from 10:91:A8:02:00:E8
------------
TX id=8 result=0
TX callback: OK
---- RX ----
Len: 84
From: 10:91:A8:02:00:E8
To: FF:FF:FF:FF:FF:FF
Received id=3 text=ping from 10:91:A8:02:00:E8
------------
TX id=9 result=0
TX callback: OK
---- RX ----
Len: 84
From: 10:91:A8:02:00:E8
To: FF:FF:FF:FF:FF:FF
Received id=4 text=ping from 10:91:A8:02:00:E8
------------
TX id=10 result=0
TX callback: OK
---- RX ----
Len: 84
From: 10:91:A8:02:00:E8
To: FF:FF:FF:FF:FF:FF
Received id=5 text=ping from 10:91:A8:02:00:E8
------------
TX id=11 result=0
TX callback: OK
---- RX ----
Len: 84
From: 10:91:A8:02:00:E8
To: FF:FF:FF:FF:FF:FF
Received id=6 text=ping from 10:91:A8:02:00:E8
------------
TX id=12 result=0
TX callback: OK

ESP32-C3-MINI-1 output

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: 10:91:A8:02:00:E8
STA MAC esp_read_mac:     10:91:A8:02:00:E8
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.
---- RX ----
Len: 84
From: 68:B6:B3:2C:16:08
To: FF:FF:FF:FF:FF:FF
Received id=6 text=ping from 68:B6:B3:2C:16:08
------------
TX id=1 result=0
TX callback: OK
---- RX ----
Len: 84
From: 68:B6:B3:2C:16:08
To: FF:FF:FF:FF:FF:FF
Received id=7 text=ping from 68:B6:B3:2C:16:08
------------
TX id=2 result=0
TX callback: OK
---- RX ----
Len: 84
From: 68:B6:B3:2C:16:08
To: FF:FF:FF:FF:FF:FF
Received id=8 text=ping from 68:B6:B3:2C:16:08
------------
TX id=3 result=0
TX callback: OK
---- RX ----
Len: 84
From: 68:B6:B3:2C:16:08
To: FF:FF:FF:FF:FF:FF
Received id=9 text=ping from 68:B6:B3:2C:16:08
------------
TX id=4 result=0
TX callback: OK
---- RX ----
Len: 84
From: 68:B6:B3:2C:16:08
To: FF:FF:FF:FF:FF:FF
Received id=10 text=ping from 68:B6:B3:2C:16:08
------------
TX id=5 result=0
TX callback: OK
---- RX ----
Len: 84
From: 68:B6:B3:2C:16:08
To: FF:FF:FF:FF:FF:FF
Received id=11 text=ping from 68:B6:B3:2C:16:08
------------
TX id=6 result=0
TX callback: OK
---- RX ----
Len: 84
From: 68:B6:B3:2C:16:08
To: FF:FF:FF:FF:FF:FF
Received id=12 text=ping from 68:B6:B3:2C:16:08
------------
TX id=7 result=0
TX callback: OK
---- RX ----
Len: 84
From: 68:B6:B3:2C:16:08
To: FF:FF:FF:FF:FF:FF
Received id=13 text=ping from 68:B6:B3:2C:16:08
------------
TX id=8 result=0
TX callback: OK
---- RX ----
Len: 84
From: 68:B6:B3:2C:16:08
To: FF:FF:FF:FF:FF:FF
Received id=14 text=ping from 68:B6:B3:2C:16:08
------------
TX id=9 result=0
TX callback: OK
---- RX ----

test setup

what specific ESP32-S3 and ESP32-C3 modules are you using? give links or photos?

Thanks for testing my exact code.

That is very useful information. Since your ESP32-S3-DevKitC-1 and ESP32-C3-MINI-1 work in both directions with the same sketch, it looks like my issue may be related to my specific boards, antenna, or board selection rather than the ESP-NOW code itself.

My boards are:

  1. ESP32-S3-N16R8 development board

    • dual USB-C
    • PCB antenna
    • selected in Arduino IDE as "ESP32S3 Dev Module"
    • I am not sure about the exact board manufacturer
  2. ESP32-C3 Super Mini style board

    • USB-C
    • onboard ceramic antenna
    • selected in Arduino IDE as "ESP32C3 Dev Module"
    • I am not sure about the exact board manufacturer

If you notice anything wrong or unusual in my board selection, configuration, or in the boards themselves, please let me know.

Tanks in advance.

I am attaching photos of both boards.

Many of those C3 mini boards have a serious design flaw which affects their WiFi performance and presumably their ESP-NOW performance also. Something to do with the proximity of the antenna to the crystal, if I remember.

But they are not all the same and don't all suffer from that problem, watch may explain why your hardware gets the problem but @horace 's does not.

tested code of post 2 using a ESP32-S3-DevKitC-1 and a ESP32-C3 Super Mini

ESP32-S3-DevKitC-1 output

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: 68:B6:B3:2C:16:08
STA MAC esp_read_mac:     68:B6:B3:2C:16:08
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: 48:31:B7:57:89:48
To: FF:FF:FF:FF:FF:FF
Received id=10 text=ping from 48:31:B7:57:89:48
------------
TX id=2 result=0
TX callback: OK
---- RX ----
Len: 84
From: 48:31:B7:57:89:48
To: FF:FF:FF:FF:FF:FF
Received id=11 text=ping from 48:31:B7:57:89:48
------------
TX id=3 result=0
TX callback: OK
---- RX ----
Len: 84
From: 48:31:B7:57:89:48
To: FF:FF:FF:FF:FF:FF
Received id=12 text=ping from 48:31:B7:57:89:48
------------
TX id=4 result=0
TX callback: OK
---- RX ----
Len: 84
From: 48:31:B7:57:89:48
To: FF:FF:FF:FF:FF:FF
Received id=13 text=ping from 48:31:B7:57:89:48
------------
TX id=5 result=0
TX callback: OK
---- RX ----
Len: 84
From: 48:31:B7:57:89:48
To: FF:FF:FF:FF:FF:FF
Received id=14 text=ping from 48:31:B7:57:89:48
------------
TX id=6 result=0
TX callback: OK
---- RX ----
Len: 84
From: 48:31:B7:57:89:48
To: FF:FF:FF:FF:FF:FF
Received id=15 text=ping from 48:31:B7:57:89:48
------------
TX id=7 result=0
TX callback: OK
---- RX ----
Len: 84
From: 48:31:B7:57:89:48
To: FF:FF:FF:FF:FF:FF
Received id=16 text=ping from 48:31:B7:57:89:48

ESP32-C3 supermini output

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: 48:31:B7:57:89:48
STA MAC esp_read_mac:     48:31:B7:57:89:48
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
TX id=4 result=0
TX callback: OK
TX id=5 result=0
TX callback: OK
TX id=6 result=0
TX callback: OK
TX id=7 result=0
TX callback: OK
TX id=8 result=0
TX callback: OK
TX id=9 result=0
TX callback: OK
---- RX ----
Len: 84
From: 68:B6:B3:2C:16:08
To: FF:FF:FF:FF:FF:FF
Received id=1 text=ping from 68:B6:B3:2C:16:08
------------
TX id=10 result=0
TX callback: OK
---- RX ----
Len: 84
From: 68:B6:B3:2C:16:08
To: FF:FF:FF:FF:FF:FF
Received id=2 text=ping from 68:B6:B3:2C:16:08
------------
TX id=11 result=0
TX callback: OK
---- RX ----
Len: 84
From: 68:B6:B3:2C:16:08
To: FF:FF:FF:FF:FF:FF
Received id=3 text=ping from 68:B6:B3:2C:16:08
------------
TX id=12 result=0
TX callback: OK
---- RX ----
Len: 84
From: 68:B6:B3:2C:16:08
To: FF:FF:FF:FF:FF:FF
Received id=4 text=ping from 68:B6:B3:2C:16:08
------------
TX id=13 result=0
TX callback: OK
---- RX ----
Len: 84
From: 68:B6:B3:2C:16:08
To: FF:FF:FF:FF:FF:FF
Received id=5 text=ping from 68:B6:B3:2C:16:08
------------
TX id=14 result=0
TX callback: OK
---- RX ----
Len: 84
From: 68:B6:B3:2C:16:08
To: FF:FF:FF:FF:FF:FF
Received id=6 text=ping from 68:B6:B3:2C:16:08
------------
TX id=15 result=0
TX callback: OK
---- RX ----
Len: 84
From: 68:B6:B3:2C:16:08
To: FF:FF:FF:FF:FF:FF
Received id=7 text=ping from 68:B6:B3:2C:16:08
------------
TX id=16 result=0
TX callback: OK
---- RX ----
Len: 84
From: 68:B6:B3:2C:16:08
To: FF:FF:FF:FF:FF:FF
Received id=8 text=ping from 68:B6:B3:2C:16:08
------------
TX id=17 result=0
TX callback: OK
---- RX ----
Len: 84
From: 68:B6:B3:2C:16:08
To: FF:FF:FF:FF:FF:FF
Received id=9 text=ping from 68:B6:B3:2C:16:08

my ESP32-C3 supermini appears to work OK with the ESP32-S3

however, as @PaulRB mentioned, there have been reports of problems with the antenna of the ESP32-C3 supermini - have a look at post no-wifi-connect-with-esp32-c3-super-mini

Thanks PaulRB and horace for your help.

It looks like the issue was indeed related to the ESP32-C3 Super Mini antenna / RF design.

After lowering the WiFi TX power, as suggested in the other thread, I was finally able to make it work. With the original maximum power setting, the ESP32-C3 could receive packets from the ESP32-S3, but the ESP32-S3 would not receive anything from the ESP32-C3. After reducing the TX power, ESP-NOW started working in both directions.

I will keep investigating to see if there is a proper way to fix or improve the antenna problem on this board.

Once I have a more definitive solution, I will post the results here in case it helps someone else.

Thanks again for pointing me in the right direction.

Hi everyone,

Quick update: I bought a different ESP32-C3 Super Mini, the Waveshare version, and it works perfectly.

The difference seems to be the board layout. In this version the antenna and the crystal are well separated, while on the previous module they were very close together.

Using the same code and setup, ESP-NOW is now working reliably. So it looks like the problem was not my code, but the RF/antenna layout of the previous ESP32-C3 Super Mini board.

I’m attaching some pictures of the new module so you can compare the layout.

Thanks again to PaulRB and Horace for the help and suggestions.