ESP-NOW struct_message

I have been trying to get ESP-NOW working and as long as I directly copy example codes everything is fine. It all falls apart when I want to change the data type I am sending/receiving. The first example code put the data at the sending level in a struct_message variable, the one I'm using now doesn't do that but does define a struct_message at the receiving side. The code is

typedef struct struct_message {
  char a[32];
} struct_message;

Works like a charm when I am sending data provided in the example code, but I want to receive the array the sender is transmitting and I feel like I have tried everything but I can't get it to work nor can I find the solution. The other example used a couple different data types;

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

but apparently I can't just delete the variables I don't need on both sides. I only need a integer array with 3 members. What am I doing wrong?

Sending code, which works just fine

#include <ESP8266WiFi.h>
#include <espnow.h>

// MAC address to broadcast data to
uint8_t broadcastAddress[] = {0x84, 0xF3, 0xEB, 0xCA, 0xF8, 0xD3};

// Message to send
int msg[3] = {0,0,0};

// Callback function to handle data send status
void OnDataSent(uint8_t *mac_addr, uint8_t sendStatus) {
  Serial.print("\r\nDelivery Status: ");
  Serial.println(sendStatus == 0 ? "Delivered Successfully" : "Delivery Fail");
}
 
void setup() {
  Serial.begin(115200);

  // Set WiFi mode to Station mode
  WiFi.mode(WIFI_STA);
 
  // Initialize ESP-NOW
  if (esp_now_init() != 0) {
    Serial.println("Error initializing ESP-NOW");
    return;
  }

  // Set the role of this device as a controller
  esp_now_set_self_role(ESP_NOW_ROLE_CONTROLLER);
 
  // Register callback for data send status
  esp_now_register_send_cb(OnDataSent);
 
  // Add a peer (slave) with the specified broadcast address
  esp_now_add_peer(broadcastAddress, ESP_NOW_ROLE_SLAVE, 1, NULL, 0);
}
 
void loop() {
  // Send the message to the specified broadcast address
  esp_now_send(broadcastAddress, (uint8_t *) &msg, sizeof(msg));
 
  // Delay for 2 seconds before sending the next message
  delay(2000);
}

Receiving code, which is now expecting to receive a char but should be modified to receive the int array that is being sent (which I can't get working):

#include <ESP8266WiFi.h>
#include <espnow.h>

// Structure to hold the received message
typedef struct struct_message {
    char a[32];
} struct_message;

// Create an instance of the struct_message
struct_message myData;

// Callback function to handle received data
void OnDataRecv(uint8_t * mac, uint8_t *incomingData, uint8_t len) {
  // Copy the incoming data to the myData structure
  memcpy(&myData, incomingData, sizeof(myData));
 
  // Print the received message
  Serial.println(myData.a);
}

void setup() {
  //Initialize the serial monitor
  Serial.begin(115200);

  // Set WiFi mode to Station mode
  WiFi.mode(WIFI_STA);
 
  // Initialize ESP-NOW
  if (esp_now_init() != 0) {
    Serial.println("Error initializing ESP-NOW");
    return;
  }

  // Set the role of this device as a slave
  esp_now_set_self_role(ESP_NOW_ROLE_SLAVE);
 
  // Register callback for received data
  esp_now_register_recv_cb(OnDataRecv);
}
 
void loop() {}

A couple more hours of googling and just stupidly trying stuff. I can't figure it out. Can't find any resource, have not found the solution by accident.

except that int is 32 bits [4 bytes] for an esp

So if I've got 3 int variables coming across, that's 6 bytes. You receive it in a char buffer 6 bytes wide.

So I don't have to change this part starting at line 5 in the receiver code?

typedef struct struct_message {
    char a[32];
} struct_message;

So you can simply declare an int array in your receiving code and use it in memcpy just like you do now.

I'm probably super dumb but I have no idea how or where. What I thought I understood is that it's put it in a struct_message, and said that struct_message consists of a 32 bit (byte?) char. Have I been trying to change something there but should I have been changing it up somewhere else?

I deleted the whole struct section, simply pasted in int myData[3]; and that literally was all. No clue why the example code would bother with all those structs and (expletive deleted). Thanks a lot for the help, I finally got it working

because it lets you send data of various types.. but the structure has to be the same on both sides...

here in the sender you have

and on the receiver you were using

it just does not make any sense.

I am very aware. Which is why I introduced the receiving code with

Receiving code, which is now expecting to receive a char but should be modified to receive the int array that is being sent (which I can't get working):

I had and have no clue how to change the structure so it expects the int array that is being sent. The solution for now ended up being getting rid of the structure all together but I still do not understand the concept structures in arduino.

Once you do, you will appreciate them.

See that as a way to group together multiple elements of various types.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.