invalid conversion from 'void (*)(const uint8_t*, const uint8_t*, int, uint8_t*)

Hello,

I am trying to use an example and trying to add to it for a project I am working on and It involves the ESP32 and LoRa with a GPS module. I am getting an error that says

“invalid conversion from ‘void ()(const uint8_t, const uint8_t*, int, uint8_t*) {aka void ()(const unsigned char, const unsigned char*, int, unsigned char*)}’ to ‘esp_now_recv_cb_t {aka void ()(const unsigned char, const unsigned char*, int)}’ [-fpermissive]”

I was wondering if someone can help me figure out what the error means. It works without me adding the ‘const uint8_t *LoRa’ which I have added to send another message to the node LoRa device.

Attach will be the two codes I am working on and the one with the error is called slave1.0

Slave1.0.ino (1.77 KB)

Master1.0.ino (11.3 KB)

If you had read and used the locked posts at the top of this forum, you would have posted correctly and perhaps I could have helped you.

You posted ino files. My mobile device - and many other mobile devices - cannot view ino files.

Sender code:

#include <esp_now.h>
#include <WiFi.h>
#include <SparkFun_I2C_GPS_Arduino_Library.h>
I2CGPS myI2CGPS;
#include <TinyGPS++.h>
TinyGPSPlus gps;

esp_now_peer_info_t slave;
#define CHANNEL 3
#define PRINTSCANRESULTS 0
#define DELETEBEFOREPAIR 0

void InitESPNow() {
  WiFi.disconnect();
  if (esp_now_init() == ESP_OK) {
    Serial.println("ESPNow Init Success");
  }
  else {
    Serial.println("ESPNow Init Failed");
    // Retry InitESPNow, add a counte and then restart?
    // InitESPNow();
    // or Simply Restart
    ESP.restart();
  }
}
void displayInfo()
{
  //We have new GPS data to deal with!
  Serial.println();

  if (gps.time.isValid())
  {
    Serial.print(F("Date: "));
    Serial.print(gps.date.month());
    Serial.print(F("/"));
    Serial.print(gps.date.day());
    Serial.print(F("/"));
    Serial.print(gps.date.year());

    Serial.print((" Time: "));
    if (gps.time.hour() < 10) Serial.print(F("0"));
    Serial.print(gps.time.hour());
    Serial.print(F(":"));
    if (gps.time.minute() < 10) Serial.print(F("0"));
    Serial.print(gps.time.minute());
    Serial.print(F(":"));
    if (gps.time.second() < 10) Serial.print(F("0"));
    Serial.print(gps.time.second());

    Serial.println(); //Done printing time
  }
  else
  {
    Serial.println(F("Time not yet valid"));
  }

  if (gps.location.isValid())
  {
    Serial.print("Location: ");
    Serial.print(gps.location.lat(), 6);
    Serial.print(F(", "));
    Serial.print(gps.location.lng(), 6);
    Serial.println();
  }
  else
  {
    Serial.println(F("Location not yet valid"));
  }
}
// Scan for slaves in AP mode
void ScanForSlave() {
  int8_t scanResults = WiFi.scanNetworks();
  // reset on each scan
  bool slaveFound = 0;
  memset(&slave, 0, sizeof(slave));

  Serial.println("");
  if (scanResults == 0) {
    Serial.println("No WiFi devices in AP Mode found");
  } else {
    Serial.print("Found "); Serial.print(scanResults); Serial.println(" devices ");
    for (int i = 0; i < scanResults; ++i) {
      // Print SSID and RSSI for each device found
      String SSID = WiFi.SSID(i);
      int32_t RSSI = WiFi.RSSI(i);
      String BSSIDstr = WiFi.BSSIDstr(i);

      if (PRINTSCANRESULTS) {
        Serial.print(i + 1);
        Serial.print(": ");
        Serial.print(SSID);
        Serial.print(" (");
        Serial.print(RSSI);
        Serial.print(")");
        Serial.println("");
      }
      delay(10);
      // Check if the current device starts with `Slave`
      if (SSID.indexOf("Slave") == 0) {
        // SSID of interest
        Serial.println("Found a Slave.");
        Serial.print(i + 1); Serial.print(": "); Serial.print(SSID); Serial.print(" ["); Serial.print(BSSIDstr); Serial.print("]"); Serial.print(" ("); Serial.print(RSSI); Serial.print(")"); Serial.println("");
        // Get BSSID => Mac Address of the Slave
        int mac[6];
        if ( 6 == sscanf(BSSIDstr.c_str(), "%x:%x:%x:%x:%x:%x%c",  &mac[0], &mac[1], &mac[2], &mac[3], &mac[4], &mac[5] ) ) {
          for (int ii = 0; ii < 6; ++ii ) {
            slave.peer_addr[ii] = (uint8_t) mac[ii];
          }
        }

        slave.channel = CHANNEL; // pick a channel
        slave.encrypt = 0; // no encryption

        slaveFound = 1;
        break;
      }
    }
  }

  if (slaveFound) {
    Serial.println("Slave Found, processing..");
  } else {
    Serial.println("Slave Not Found, trying again.");
  }

  // clean up ram
  WiFi.scanDelete();
}
bool manageSlave() {
  if (slave.channel == CHANNEL) {
    if (DELETEBEFOREPAIR) {
      deletePeer();
    }

    Serial.print("Slave Status: ");
    const esp_now_peer_info_t *peer = &slave;
    const uint8_t *peer_addr = slave.peer_addr;
   bool exists = esp_now_is_peer_exist(peer_addr);
    if ( exists) {
      // Slave already paired.
      Serial.println("Already Paired");
      return true;
    } else {
      // Slave not paired, attempt pair
      esp_err_t addStatus = esp_now_add_peer(peer);
      if (addStatus == ESP_OK) {
        // Pair success
        Serial.println("Pair success");
        return true;
      } else if (addStatus == ESP_ERR_ESPNOW_NOT_INIT) {
        // How did we get so far!!
        Serial.println("ESPNOW Not Init");
        return false;
      } else if (addStatus == ESP_ERR_ESPNOW_ARG) {
        Serial.println("Invalid Argument");
        return false;
      } else if (addStatus == ESP_ERR_ESPNOW_FULL) {
        Serial.println("Peer list full");
        return false;
      } else if (addStatus == ESP_ERR_ESPNOW_NO_MEM) {
        Serial.println("Out of memory");
        return false;
      } else if (addStatus == ESP_ERR_ESPNOW_EXIST) {
        Serial.println("Peer Exists");
        return true;
      } else {
        Serial.println("Not sure what happened");
        return false;
      }
    }
  } else {
    // No slave found to process
    Serial.println("No Slave found to process");
    return false;
  }
}

void deletePeer() {
  const esp_now_peer_info_t *peer = &slave;
  const uint8_t *peer_addr = slave.peer_addr;
  esp_err_t delStatus = esp_now_del_peer(peer_addr);
  Serial.print("Slave Delete Status: ");
  if (delStatus == ESP_OK) {
    // Delete success
    Serial.println("Success");
  } else if (delStatus == ESP_ERR_ESPNOW_NOT_INIT) {
    // How did we get so far!!
    Serial.println("ESPNOW Not Init");
  } else if (delStatus == ESP_ERR_ESPNOW_ARG) {
    Serial.println("Invalid Argument");
  } else if (delStatus == ESP_ERR_ESPNOW_NOT_FOUND) {
    Serial.println("Peer not found.");
  } else {
    Serial.println("Not sure what happened");
  }
}

uint8_t data = 0;
// send data
void sendData() {
  data= gps.location.lat();
  const uint8_t *peer_addr = slave.peer_addr;
  Serial.print("Sending: "); Serial.println(data);
  esp_err_t result = esp_now_send(peer_addr, &data, sizeof(data));
  Serial.print("Send Status: ");
  if (result == ESP_OK) {
    Serial.println("Success");
  } else if (result == ESP_ERR_ESPNOW_NOT_INIT) {////////////////////////////////////////////////////////////////////////
    // How did we get so far!!
    Serial.println("ESPNOW not Init.");
  } else if (result == ESP_ERR_ESPNOW_ARG) {
    Serial.println("Invalid Argument");
  } else if (result == ESP_ERR_ESPNOW_INTERNAL) {
    Serial.println("Internal Error");
  } else if (result == ESP_ERR_ESPNOW_NO_MEM) {
    Serial.println("ESP_ERR_ESPNOW_NO_MEM");
  } else if (result == ESP_ERR_ESPNOW_NOT_FOUND) {
    Serial.println("Peer not found.");
  } else {
    Serial.println("Not sure what happened");
  }
}
  void sendLoRa()
  {
const uint8_t LoRa = gps.location.lng();
    const uint8_t *peer_addr = slave.peer_addr;
    Serial.print("Sending: "); Serial.println(LoRa);
    esp_err_t result = esp_now_send(peer_addr, &LoRa, sizeof(LoRa));

}

// callback when data is sent from Master to Slave
void OnDataSent(const uint8_t *mac_addr, esp_now_send_status_t status) {
  char macStr[18];
  snprintf(macStr, sizeof(macStr), "%02x:%02x:%02x:%02x:%02x:%02x",
           mac_addr[0], mac_addr[1], mac_addr[2], mac_addr[3], mac_addr[4], mac_addr[5]);
  Serial.print("Last Packet Sent to: "); Serial.println(macStr);
  Serial.print("Last Packet Send Status: "); Serial.println(status == ESP_NOW_SEND_SUCCESS ? "Delivery Success" : "Delivery Fail");
}

void setup() {
  Serial.begin(115200);
  WiFi.mode(WIFI_STA);
  Serial.println("ESPNow/Basic/Master Example");
  // This is the mac address of the Master in Station Mode
  Serial.print("STA MAC: "); Serial.println(WiFi.macAddress());
   Serial.println("GTOP Read Example");

  if (myI2CGPS.begin() == false)
  {
    Serial.println("Module failed to respond. Please check wiring.");
    while (1);
  }
  Serial.println("GPS module found!");
  InitESPNow();
  esp_now_register_send_cb(OnDataSent);
}

void loop() {
  // In the loop we scan for slave
  
    while (myI2CGPS.available()) 
  {
    gps.encode(myI2CGPS.read()); 
  }

  if (gps.time.isUpdated()) //Check to see if new GPS info is available
  {
    displayInfo();
  }
  ScanForSlave();
     if (slave.channel == CHANNEL) {
    bool isPaired = manageSlave();
    if (isPaired) {
      sendData();
     sendLoRa();
    } else {
      // slave pair failed
      Serial.println("Slave pair failed!");
    }
  }
  else {
  }
  delay(1000);
}

I kind of fixed it a bit but i still am having trouble with sending the two different coordinates. When they display on the receiver screen, they show up as a whole number and not the exact coordinates.
Receiver Code:

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

#define CHANNEL 1

// Init ESP Now with fallback
void InitESPNow() {
  WiFi.disconnect();
  if (esp_now_init() == ESP_OK) {
    Serial.println("ESPNow Init Success");
  }
  else {
    Serial.println("ESPNow Init Failed");
    ESP.restart();
  }
}

// config AP SSID
void configDeviceAP() {
  char* SSID = "Slave_1";
  bool result = WiFi.softAP(SSID, "Slave_1_Password", CHANNEL, 0);
  if (!result) {
    Serial.println("AP Config failed.");
  } else {
    Serial.println("AP Config Success. Broadcasting with AP: " + String(SSID));
  }
}

void setup() {
  Serial.begin(115200);
  Serial.println("ESPNow/Basic/Slave Example");
  //Set device in AP mode to begin with
  WiFi.mode(WIFI_AP);
  // configure device AP mode
  configDeviceAP();
  // This is the mac address of the Slave in AP Mode
  Serial.print("AP MAC: "); Serial.println(WiFi.softAPmacAddress());
  // Init ESPNow with a fallback logic
  InitESPNow();
  // Once ESPNow is successfully Init, we will register for recv CB to
  // get recv packer info.
  esp_now_register_recv_cb(OnDataRecv);
}

// callback when data is recv from Master
void OnDataRecv(const uint8_t *mac_addr,const uint8_t *data, int data_len) {
  char macStr[18];
  snprintf(macStr, sizeof(macStr), "%02x:%02x:%02x:%02x:%02x:%02x",
           mac_addr[0], mac_addr[1], mac_addr[2], mac_addr[3], mac_addr[4], mac_addr[5]);
  Serial.print("Last Packet Recv from: "); Serial.println(macStr);
  Serial.print("Latitude: "); Serial.println(*data);
  Serial.println("Longitude: "); Serial.println(*data);
}

void loop() {

}

The two Serial monitors come out to the attachments below. As you can see that the COM 3 is the sender and it is sending 41 and 168 and that is the coordinates but the input coordinates have more decimal places and the 168 is suppose to be around -88. And Capture1 is the Receiver, My goal is to have the Lat and the Long together but its not sending it out like that.

void OnDataRecv(const uint8_t *mac_addr,const uint8_t *data, int data_len) {
<snip>
  Serial.print("Latitude: "); Serial.println(*data);
  Serial.println("Longitude: "); Serial.println(*data);

You are printing the same integral value for both latitude AND longitude. Surely, that can’t be right. What triggers this callback? If the data passed to this method is 8 bytes that represent a 2 element float array, you need to recreate the float array. That might be as simple as casting data to a float pointer, and then printing the [0] and [1] elements of the array.

Never mind. I found the answer. The sender code is rubbish. data is supposed to be a pointer, and is supposed to point to an array of floats. You are truncating the float to an integral value, and forcing it into a byte. Then, you send the address of the byte.

uint8_t data = 0;
// send data
void sendData() {
  data= gps.location.lat();
  const uint8_t *peer_addr = slave.peer_addr;
  Serial.print("Sending: "); Serial.println(data);
  esp_err_t result = esp_now_send(peer_addr, &data, sizeof(data));

You need to create a 2 element float array, store the lat() and lon() return data in the array, and send the array.

Okay, thank you. So replace

uint8_t data = 0;
// send data
void sendData() {
  data= gps.location.lat();
  const uint8_t *peer_addr = slave.peer_addr;
  Serial.print("Sending: "); Serial.println(data);
  esp_err_t result = esp_now_send(peer_addr, &data, sizeof(data));

with a 2 element float array. Also would anything on the receiving end change?

So replace ... with a 2 element float array.

You need to replace SOME of that code with a two element float array, not ALL of it.

Also would anything on the receiving end change?

Of course. You would need to cast the byte pointer, data, to a float pointer, and use data[ 0 ] and data[ 1 ], not data and data.

I made some adjustments but im getting a cannot convert uint8_t (aka unsigned char*} to float in initialization.

float data[2];
// send data
void sendData() {
  data[0]= gps.location.lat();
float  *peer_addr = slave.peer_addr;
  Serial.print("Sending: "); Serial.println(data[0]);
  esp_err_t result = esp_now_send(peer_addr, &data[0], sizeof(data[0]));
    data[1]=gps.location.lng();
    Serial.print("Sending: "); Serial.println(data[1]);

I highlighted part is 'float *peer_addr = slave.peer_addr;'
I am sorry for these questions, relatively new to this!

I highlighted part is 'float *peer_addr = slave.peer_addr;'

It seems unlikely that the peer_addr member of whatever class slave is a member of is a float array.

Why do you need to point to it? What type is it?

Why are you sending the float array one element at a time?

I was trying to sending the array two at a time because I couldn’t figure out how to send it together.

In the code, it only shows that the const uint8_t *peer_addr = slave.peer_addr;

I’m unsure why it’s like this but every time I change it I get an error. Any suggestions?

I'm unsure why it's like this but every time I change it I get an error. Any suggestions?

You don't need the pointer, so stop creating one.

Use slave.peer_addr in the call to esp_send_now().

I was trying to sending the array two at a time because I couldn't figure out how to send it together.

I presume you mean one at a time.

Send the data all at once:

  esp_err_t result = esp_now_send(peer_addr, data, sizeof(data));
void sendData() {
  float data[2];
  data[0]= gps.location.lat();
  data[1]=gps.location.lng();
//peer_addr = slave.peer_addr;
  Serial.print("Sending: "); Serial.println(data[0]);
  esp_err_t result = esp_now_send(slave.peer_addr, data, sizeof(data));

I am still a bit confused because it is giving me the "cannot convert 'float*' to 'const uint8_t* {aka const unsigned char*}' for argument '2' to 'esp_err_t esp_now_send(const uint8_t*, const uint8_t*, size_t)'"
error.

Well, how should the compiler convert the pointer to an array of floats to a pointer that points to an array of chars? You have to explicitly tell it to reinterpret the pointer as if it were a pointer to a char array.

esp_err_t result = esp_now_send(slave.peer_addr, reinterpret_cast<uint8_t*>(data), sizeof(data));

The ESP32 has a wonk, in the Arduino IDE, about passing uint8_t's and uint16_t's as function parameter arguments.

This function:

int myMPU9250::setAccelRange( int range )
{
  SPI_Err = 0;
  if ( ACCEL_RANGE_2G == range )
  {
    // setting the accel range to 2G
    SPI_Err = _spi.fWriteSPIdata8bits( ACCEL_CONFIG, ACCEL_FS_SEL_2G );
    _accelScale = G * 2.0f / 32767.5f; // setting the accel scale to 2G
    return SPI_Err;
  }

works great. range is a uint8_t.
When the function was written:

int myMPU9250::setAccelRange( uint8_t range )
{
  SPI_Err = 0;
  if ( ACCEL_RANGE_2G == range )
  {
    // setting the accel range to 2G
    SPI_Err = _spi.fWriteSPIdata8bits( ACCEL_CONFIG, ACCEL_FS_SEL_2G );
    _accelScale = G * 2.0f / 32767.5f; // setting the accel scale to 2G
    return SPI_Err;
  }

it would not compile in the Arduino IDE.

This function call _spi.fWriteSPIdata8bits( ACCEL_CONFIG, ACCEL_FS_SEL_2G ); is using the SPI_API. The SPI API uses uint8_t and uint16_t but the Arduino IDE will not compile if the _spi.fWriteSPIdata8bits( ACCEL_CONFIG, ACCEL_FS_SEL_2G ); was written:

int ESP32_SPI_API::fWriteSPIdata8bits( uint8_t _address, uint8_t _DataToSend)
{
  uint8_t txData[2] = { (uint8_t)_address, (uint8_t)_DataToSend };
  spi_transaction_t trans_desc;
  trans_desc = { };
  trans_desc.addr = 0;
  trans_desc.cmd = 0;
  trans_desc.flags  = 0;
  trans_desc.length = 8 * 2; // total data bits
  trans_desc.tx_buffer = txData;
  return spi_device_transmit( _h, &trans_desc);
} // void fSendSPI( uint8_t count, uint8_t address, uint8_t DataToSend)

But works fine when written

int ESP32_SPI_API::fWriteSPIdata8bits( int _address, int _DataToSend)
{
  uint8_t txData[2] = { (uint8_t)_address, (uint8_t)_DataToSend };
  spi_transaction_t trans_desc;
  trans_desc = { };
  trans_desc.addr = 0;
  trans_desc.cmd = 0;
  trans_desc.flags  = 0;
  trans_desc.length = 8 * 2; // total data bits
  trans_desc.tx_buffer = txData;
  return spi_device_transmit( _h, &trans_desc);
} // void fSendSPI( uint8_t count, uint8_t address, uint8_t DataToSend)

Just be aware the ESP32 with the Arduino IDE has a wonk about uint8_t and uint16_t.

Pass an int up is fine, no worries, but passing an int down one should be aware of the info one may lose.

Passing up :

int u = 1;
uint8_t d = u;

Passing down:

int u = 8265;
uint8_t d = u; You'll not get an error but you will lose info.

LightuC:
Well, how should the compiler convert the pointer to an array of floats to a pointer that points to an array of chars? You have to explicitly tell it to reinterpret the pointer as if it were a pointer to a char array.

esp_err_t result = esp_now_send(slave.peer_addr, reinterpret_cast<uint8_t*>(data), sizeof(data));

That code seemed to work for the sender. Thank you, how would you fix it on the receiving end?

 esp_now_register_recv_cb(OnDataRecv);
}

// callback when data is recv from Master
void OnDataRecv(const uint8_t *mac_addr,const uint8_t *data[2], int data_len) {
  char macStr[18];
  snprintf(macStr, sizeof(macStr), "%02x:%02x:%02x:%02x:%02x:%02x",
           mac_addr[0], mac_addr[1], mac_addr[2], mac_addr[3], mac_addr[4], mac_addr[5]);
  Serial.print("Last Packet Recv from: "); Serial.println(macStr);
  Serial.print("Latitude: "); Serial.println(*data[0]);
  Serial.println("Longitude: "); Serial.println(*data[1]);
}

I am getting like the same error and am unsure how to fix it.
The error is “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 unsigned char, const unsigned char*, int)}’ [-fpermissive]”

It seems you got a bit confused about pointers and arrays. The esp_now_register_recv_cb expects a function, whose signature is:

void name(const unsigned char*, const unsigned char*, int)

Look closely at your function signature: The second parameter is of type const unsigned char* [2], which is the same as const unsigned char**. You need to change this to const unsigned char[2] or const unsigned char*. When you use the data parameter in your function you either dereference the pointer (*(data+0)) or use it like an array (data[0]), but not both.

Code:

// callback when data is recv from Master
void OnDataRecv(const uint8_t *mac_addr,const uint8_t* data, int data_len) {
  char macStr[18];
  snprintf(macStr, sizeof(macStr), "%02x:%02x:%02x:%02x:%02x:%02x",
           mac_addr[0], mac_addr[1], mac_addr[2], mac_addr[3], mac_addr[4], mac_addr[5]);
  Serial.print("Last Packet Recv from: "); Serial.println(macStr);
  Serial.print("Latitude: "); Serial.println(data[0]);
  Serial.println("Longitude: "); Serial.println(data[1]);
}

mwk21096:
That code seemed to work for the sender. Thank you, how would you fix it on the receiving end?

void OnDataRecv(const uint8_t *mac_addr,const uint8_t *data[2], int data_len) {

}




I am getting like the same error and am unsure how to fix it.
The error is "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 unsigned char*, const unsigned char*, int)}' [-fpermissive]"

I guess you did not read post 14 of this thread?

Idahowalker:
I guess you did not read post 14 of this thread?

I can't see any relation between post #14 and the error related to the callback function signature.

Its letting me upload the code with no issues but now the issue is that when it tries sending the message over to the receiver im getting a Invalid arguement.

void sendData() {
 char data[2];
  data[0]= gps.location.lat();
    data[1]=gps.location.lng();
//peer_addr = slave.peer_addr;
  Serial.print("Sending: "); Serial.println(data[0]);
esp_err_t result = esp_now_send(slave.peer_addr, reinterpret_cast<uint8_t*>(data[2]), sizeof(data[2]));
  
  if (result == ESP_OK) {
    Serial.println("Success");
  } else if (result == ESP_ERR_ESPNOW_NOT_INIT) {////////////////////////////////////////////////////////////////////////
    // How did we get so far!!
    Serial.println("ESPNOW not Init.");
  } else if (result == ESP_ERR_ESPNOW_ARG) {
    Serial.println("Invalid Argument");
  } else if (result == ESP_ERR_ESPNOW_INTERNAL) {
    Serial.println("Internal Error");
  } else if (result == ESP_ERR_ESPNOW_NO_MEM) {
    Serial.println("ESP_ERR_ESPNOW_NO_MEM");
  
  }

The serial monitor says “Slave Status: Already Paired
Sending: E (186655) ESPNOW: Invalid argument!
Invalid Argument”