ESPNOW Coversion Problem

Hello guys,

In todays problem I have issues with the ESP NOW protocol especially with receiver end with of coding. The code that has the problem is this:

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

// Define a data structure
typedef struct struct_message {
  char a[32];
  int b;
  float c;
  bool d;
} struct_message;

// Create a structured object
struct_message myData;


// Callback function executed when data is received
void OnDataRecv(const uint8_t * mac, const uint8_t *incomingData, int len) {
  memcpy(&myData, incomingData, sizeof(myData));
  Serial.print("Data received: ");
  Serial.println(len);
  Serial.print("Character Value: ");
  Serial.println(myData.a);
  Serial.print("Integer Value: ");
  Serial.println(myData.b);
  Serial.print("Float Value: ");
  Serial.println(myData.c);
  Serial.print("Boolean Value: ");
  Serial.println(myData.d);
  Serial.println();
}

void setup() {
  // Set up Serial Monitor
  Serial.begin(115200);
  
  // Set ESP32 as a Wi-Fi Station
  WiFi.mode(WIFI_STA);

  // Initilize ESP-NOW
  if (esp_now_init() != ESP_OK) {
    Serial.println("Error initializing ESP-NOW");
    return;
  }
  
  // Register callback function
  esp_now_register_recv_cb(OnDataRecv);
}
 
void loop() {

}

And the error code for this sketch is this:

C:\Users\name\OneDrive\Desktop\Arduino_codes\ReceiverCode\ReceiverCode.ino: In function 'void setup()':
C:\Users\name\OneDrive\Desktop\Arduino_codes\ReceiverCode\ReceiverCode.ino:56:28: error: invalid conversion from 'void (*)(const uint8_t*, const uint8_t*, int)' {aka 'void (*)(const unsigned char*, const unsigned char*, int)'} to 'esp_now_recv_cb_t' {aka 'void (*)(const esp_now_recv_info*, const unsigned char*, int)'} [-fpermissive]
   56 |   esp_now_register_recv_cb(OnDataRecv);
      |                            ^~~~~~~~~~
      |                            |
      |                            void (*)(const uint8_t*, const uint8_t*, int) {aka void (*)(const unsigned char*, const unsigned char*, int)}
In file included from C:\Users\name\OneDrive\Desktop\Arduino_codes\ReceiverCode\ReceiverCode.ino:11:
C:\Users\name\AppData\Local\Arduino15\packages\esp32\tools\esp32-arduino-libs\idf-release_v5.1-3662303f31/esp32c3/include/esp_wifi/include/esp_now.h:156:54: note:   initializing argument 1 of 'esp_err_t esp_now_register_recv_cb(esp_now_recv_cb_t)'
  156 | esp_err_t esp_now_register_recv_cb(esp_now_recv_cb_t cb);
      |                                    ~~~~~~~~~~~~~~~~~~^~

exit status 1

Compilation error: invalid conversion from 'void (*)(const uint8_t*, const uint8_t*, int)' {aka 'void (*)(const unsigned char*, const unsigned char*, int)'} to 'esp_now_recv_cb_t' {aka 'void (*)(const esp_now_recv_info*, const unsigned char*, int)'} [-fpermissive]

Here is the transmitter code if you believe the problem is linked with this even if it works properly:

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

// Variables for test data
int int_value;
float float_value;
bool bool_value = true;

// MAC Address of responder - edit as required
uint8_t broadcastAddress[] = {0x24, 0x6F, 0x28, 0x7A, 0xAE, 0x7C};

// Define a data structure
typedef struct struct_message {
  char a[32];
  int b;
  float c;
  bool d;
} struct_message;

// Create a structured object
struct_message myData;

// Peer info
esp_now_peer_info_t peerInfo;

// Callback function called when data is sent
void OnDataSent(const uint8_t *mac_addr, esp_now_send_status_t status) {
  Serial.print("\r\nLast Packet Send Status:\t");
  Serial.println(status == ESP_NOW_SEND_SUCCESS ? "Delivery Success" : "Delivery Fail");
}

void setup() {
  
  // Set up Serial Monitor
  Serial.begin(115200);
 
  // Set ESP32 as a Wi-Fi Station
  WiFi.mode(WIFI_STA);

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

  // Register the send callback
  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;
  }
}

void loop() {

  // Create test data

  // Generate a random integer
  int_value = random(1,20);

  // Use integer to make a new float
  float_value = 1.3 * int_value;

  // Invert the boolean value
  bool_value = !bool_value;
  
  // Format structured data
  strcpy(myData.a, "Welcome to the Workshop!");
  myData.b = int_value;
  myData.c = float_value;
  myData.d = bool_value;
  
  // Send message via ESP-NOW
  esp_err_t result = esp_now_send(broadcastAddress, (uint8_t *) &myData, sizeof(myData));
   
  if (result == ESP_OK) {
    Serial.println("Sending confirmed");
  }
  else {
    Serial.println("Sending error");
  }
  delay(2000);
}

Few things to note however is this is a direct copy (other than the MAC Address) from Dronebot Workshops demo so basically I am a complete newbie. The ideal scenario was that the tutorial's code would work perfectly fine in my computer which is not the case right now.

If you have questions please reply, Thank you

Post a link to that demo code, or better, post the demo code in your next post, using code tags. The error message is telling you that the call arguments don't match expectations.

Compiler error messages must also be posted as code, since the details contain characters like * which sometimes disappears and turns text italic -- as can be seen in your message -- making them hard to read.

The receive callback signature

is appropriate for ESP-IDF v4

typedef void (*esp_now_recv_cb_t)(const uint8_t *mac_addr,
  const uint8_t *data, int data_len)

but your board uses version 5.1 (esp32-arduino-libs\idf-release_v5.1-3662303f31)

typedef void (*esp_now_recv_cb_t)(const esp_now_recv_info_t *esp_now_info,
  const uint8_t *data, int data_len)

The first argument used to be a const uint8_t *, but has been changed to const esp_now_recv_info_t *, a pointer to

typedef struct esp_now_recv_info esp_now_recv_info_t

which in turn is

struct esp_now_recv_info {
    uint8_t *src_addr;
    uint8_t *des_addr;
    wifi_pkt_rx_ctrl_t *rx_ctrl;
};

Previously, there was just the source mac_addr, which is now the src_addr in the struct; and two new fields.

The callback implementation ignores the first argument anyway, so you can just change the signature to match.

1 Like

So what changes are you suggesting?

1 Like

I have this same issue, wondering how the suggestion for fixing the signature to match is done? :slight_smile:

Thanks!