ESP NOW Sender Callback Failure

GR56756467
Posts: 5
Joined: Mon May 19, 2025 6:53 pm

ESP NOW Sender Callback Failure

Postby GR56756467 » Mon May 19, 2025 7:09 pm

Hi; I have a simple one-way peer-to-peer app between 2 ESP32-S3s. I am only sending a few bytes and everything is working fine.

The sender sends a message every 10 seconds and the receiver gets it within a few milliseconds.

However, the sender callback always reports ESP_NOW_SEND_FAIL in the status argument. I am tempted to just disable the callback, but I'd like to understand what's going on.

Any ideas?

Sprite
Espressif staff
Espressif staff
Posts: 10599
Joined: Thu Nov 26, 2015 4:08 am

Re: ESP NOW Sender Callback Failure

Postby Sprite » Wed May 21, 2025 5:35 am

Can you post code to reproduce that?

GR56756467
Posts: 5
Joined: Mon May 19, 2025 6:53 pm

Re: ESP NOW Sender Callback Failure

Postby GR56756467 » Wed May 21, 2025 1:53 pm

It's very strange; when I plugged both in yesterday morning, without having made any changes, it worked fine for a while, but later reverted to the strange behavior (I may have reset one or both before it started to fail).

However, I then added a second S3 receiver, running the identical code and that one works fine; the sender is sending to both explicitly, not broadcasting.

This morning; both are fine and I can no longer get it to fail. The code is pretty much the same as every example on the internet and I am explicitly setting a channel; I'll keep an eye on it and if it starts failing again, I'll post it.

Thanks.

GR56756467
Posts: 5
Joined: Mon May 19, 2025 6:53 pm

Re: ESP NOW Sender Callback Failure

Postby GR56756467 » Wed May 21, 2025 3:10 pm

It's failing again...

Code: Select all

10:59:48.402 -> Sent OK
10:59:48.402 -> Sent OK
10:59:48.434 -> Send status: failed
10:59:48.434 -> Send status: success

Code: Select all

10:59:48.861 -> Incoming lat: x.xx long: -y.yy mph: 0 sats: 8
10:59:48.861 -> From: 94:a9:90:1b:90:14

Code: Select all

10:59:48.019 -> Incoming lat: x.xx long: -y.yy mph: 0 sats: 8
10:59:48.019 -> From: 94:a9:90:1b:90:14
(The second receiver is on a different host and the clocks are a bit off).

Code: Select all

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

#include <TinyGPSPlus.h>

HardwareSerial gpsSerial(1);

#define TXD 17
#define RXD 18
#define ESPNOW_WIFI_CHANNEL 4

TinyGPSPlus gps;

typedef struct gpsData {
  float lat;
  float lng;
  int speed_mph;
  int satellites;
} gpsData;

gpsData data;
uint8_t recvAddr1[] = { 0x30, 0xED, 0xA0, 0xA8, 0xCC, 0xF0 };
uint8_t recvAddr2[] = { 0xCC, 0xBA, 0x97, 0x05, 0x5B, 0xF8 };
esp_now_peer_info pInfo1;
esp_now_peer_info pInfo2;

int in;
int count;

void onDataSent(const uint8_t *mac_addr, esp_now_send_status_t status) {
  Serial.print("Send status: ");
  Serial.println(status == ESP_NOW_SEND_SUCCESS ? "success" : "failed");
}

void setup() {
  Serial.begin(115200);
  gpsSerial.begin(9600, SERIAL_8N1, RXD, TXD);
  
  WiFi.mode(WIFI_STA);
  WiFi.setChannel(ESPNOW_WIFI_CHANNEL);
  while (!WiFi.STA.started()) {
    delay(100);
  }

  Serial.println("Wi-Fi parameters:");
  Serial.println("  Mode: STA");
  Serial.println("  MAC Address: " + WiFi.macAddress());
  Serial.printf("  Channel: %d\n", ESPNOW_WIFI_CHANNEL);

  if (esp_now_init() != ESP_OK) {
    Serial.println("Failed to init now");
    return;
  }

  memcpy(pInfo1.peer_addr, recvAddr1, 6);
  pInfo1.channel = ESPNOW_WIFI_CHANNEL;
  pInfo1.encrypt = false;
  memcpy(pInfo2.peer_addr, recvAddr2, 6);
  pInfo2.channel = ESPNOW_WIFI_CHANNEL;
  pInfo2.encrypt = false;

  esp_err_t rslt = esp_now_register_send_cb(onDataSent);
  if (rslt != ESP_OK) {
    Serial.print("Failed to register callback: ");
    Serial.println(esp_err_to_name(rslt));
    return;
  }
  else {
    Serial.println("CB registered");
  }

  if (esp_now_add_peer(&pInfo1) != ESP_OK) {
    Serial.println("Failed to add peer");
    return;
  }
  else {
    Serial.println("Peer registered");
  }
  if (esp_now_add_peer(&pInfo2) != ESP_OK) {
    Serial.println("Failed to add peer");
    return;
  }
  else {
    Serial.println("Peer registered");
  }
}

void printGPS() {
// ...
}

void loop() {
  while (gpsSerial.available()) {
    in = gpsSerial.read();
    gps.encode(in);
  }

  if (count++ % 20 == 0) {
    printGPS();
    data.lat = (float) gps.location.lat();
    data.lng = (float) gps.location.lng();
    data.speed_mph = (int) gps.speed.mph();
    data.satellites = (int) gps.satellites.value();
    if (esp_now_send(recvAddr1, (uint8_t*) &data, sizeof(data)) == ESP_OK) {
      Serial.println("Sent OK");
    }
    if (esp_now_send(recvAddr2, (uint8_t*) &data, sizeof(data)) == ESP_OK) {
      Serial.println("Sent OK");
    }
  }

  delay(500);

}

Code: Select all

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

#define ESPNOW_WIFI_CHANNEL 4
#define LED 4

typedef struct gpsData {
  float lat;
  float lng;
  int speed_mph;
  int satellites;
} gpsData;

gpsData data;

volatile bool received = false;
uint8_t macs[6];

void onDataRecv(const esp_now_recv_info_t *recvInfo, const uint8_t *incoming, int len) {
  memcpy(&data, incoming, sizeof(data));
  uint8_t *mac = recvInfo->src_addr;
  memcpy(&macs, mac, 6);
  received = true;  
}

void setup() {
  Serial.begin(115200);
  WiFi.mode(WIFI_STA);
  WiFi.setChannel(ESPNOW_WIFI_CHANNEL);
  while (!WiFi.STA.started()) {
    delay(100);
  }

  Serial.println("Wi-Fi parameters:");
  Serial.println("  Mode: STA");
  Serial.println("  MAC Address: " + WiFi.macAddress());
  Serial.printf("  Channel: %d\n", ESPNOW_WIFI_CHANNEL);

  if (esp_now_init() != ESP_OK) {
    Serial.println("Failed to init now");
    return;
  }

  esp_now_register_recv_cb(onDataRecv);

  pinMode(LED, OUTPUT);
}

void loop() {
  if (received) {
    Serial.printf("Incoming lat: %f long: %f mph: %d sats: %d\nFrom: ", data.lat, data.lng, data.speed_mph, data.satellites);
    for (int i = 0; i < 6; i++) {
      Serial.printf("%02x", macs[i]);
      if (i != 5) {
        Serial.print(":");
      }
    }
    Serial.println();
    received =false;
    if (data.lat != 0) {
      digitalWrite(LED, HIGH);
    }
  }
  delay(500);
  digitalWrite(LED, LOW);
}
Any ideas?

MicroController
Posts: 2663
Joined: Mon Oct 17, 2022 7:38 pm
Location: Europe, Germany

Re: ESP NOW Sender Callback Failure

Postby MicroController » Thu May 22, 2025 8:08 am

ESP-NOW unicast messages are automatically acknowledged by the receiver. If the message gets to the receiver but the acknowledgement is lost in transmission, the sender's callback will also indicate "fail".
This may happen if, for example, the sender experiences stronger RF interference (is closer to another RF source) than the receiver.

GR56756467
Posts: 5
Joined: Mon May 19, 2025 6:53 pm

Re: ESP NOW Sender Callback Failure

Postby GR56756467 » Thu May 22, 2025 12:13 pm

Thanks; my understanding is that the sender will automatically retry failures a couple of times; I don't see any duplicates on the receiver, so I assume he is smart enough to realize he has already seen that message and just drops it.

Who is online

Users browsing this forum: Applebot, meta-externalagent and 3 guests