c++arduino-esp32esp-now

ESP now on receive callback has wrong MAC address


I have two ESP32 devices and I use ESP Now to send data between them.

This is my onMessageReceived function on both ESP32s:

typedef struct {
  uint8_t type;
  uint8_t data[MAX_PAYLOAD_SIZE];
} Message;

void onDataReceived(const uint8_t* macAddr, const uint8_t* data, int len) {
  Message msg;
  memcpy(&msg, data, sizeof(Message));

  Serial.print("Received message of type: ");
  Serial.print(msg.type);
  Serial.print(" from: ");
  Serial.printf("%02x:%02x:%02x:%02x:%02x:%02x\n",
                macAddr[0], macAddr[1], macAddr[2],
                macAddr[3], macAddr[4], macAddr[5]);
}

And I register it like so esp_now_register_recv_cb(esp_now_recv_cb_t(onDataReceived));

And for both ESPs I get this output in the serial monitor when I send a message: Received message of type: 1 from: 46:f3:fa:3f:40:f3.

This is not the MAC address of neither of the ESPs, and I am not sure where it is coming from...

This is the setup code for the first ESP that will act as a web server:

void setup() {
  Serial.begin(115200);

  WiFi.mode(WIFI_AP);
  WiFi.begin("SSID", "PASSWORD");
  Serial.println("\nConnecting");

  while (WiFi.status() != WL_CONNECTED) {
    Serial.print(".");
    delay(100);
  }

  Serial.println("\nConnected to the WiFi network");
  Serial.print("Local ESP32 IP: ");
  Serial.println(WiFi.localIP());
  Serial.print("ESP32 channel: ");
  Serial.println(WiFi.channel());

  if (esp_now_init() != ESP_OK) {
    Serial.println("Error initializing ESP-NOW");
    return;
  }

  // Register callback function for receiving data
  esp_now_register_recv_cb(esp_now_recv_cb_t(onDataReceived));

  // Add broadcast peer (optional, depending on your needs)
  uint8_t broadcastAddress[] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
  Serial.println(addEspNowPeer(broadcastAddress));
}

And for the second ESP:

int32_t getWiFiChannel() {
  // Source: https://randomnerdtutorials.com/esp32-esp-now-wi-fi-web-server/
  int16_t numNetworks = WiFi.scanNetworks();
  for (uint16_t i = 0; i < numNetworks; i++) {
    if (WiFi.SSID(i).equals(WIFI_SSID)) {
      return WiFi.channel(i);
    }
  }
  return -1;
}

void setup() {
  Serial.begin(115200);
  WiFi.mode(WIFI_STA);

  esp_wifi_set_promiscuous(true);
  esp_wifi_set_channel(getWiFiChannel(), WIFI_SECOND_CHAN_NONE);
  esp_wifi_set_promiscuous(false);

  if (esp_now_init() != ESP_OK) {
    Serial.println("Error initializing ESP-NOW");
    return;
  }

  // Register callback function for receiving data
  esp_now_register_recv_cb(esp_now_recv_cb_t(onDataReceived));

  // Add broadcast peer (optional, depending on your needs)
  uint8_t broadcastAddress[] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
  addEspNowPeer(broadcastAddress);

  // Send a Discovery Request
  Message request;
  request.type = SERVER_SEARCH_REQUEST;
  esp_now_send(broadcastAddress, (uint8_t*)&request, sizeof(Message));
  Serial.println("Message sent.");
}

So, why am I getting this unknown MAC address, and what can I do? I mostly follow codes from various blogs, so I am not sure where it gets wrong...


Solution

  • Well, after more digging around I found this forum post which clearly explained that the method signature I use is from an older version of the API.

    The problem was this line esp_now_register_recv_cb(esp_now_recv_cb_t(onDataReceived));, and more specifically this "conversion" type esp_now_recv_cb_t.

    Once I removed this conversion and updated the callback function it all worked.

    This is the updated function signature:

    void onDataReceived(const esp_now_recv_info_t* messageInfo, const uint8_t* data, int len)

    And to register it esp_now_register_recv_cb(onDataReceived);