I am working on a project where my ESP32 sender reads temperature, humidity, and battery voltage, then packs these values into a struct and transmits it to a receiver ESP32 using ESP-NOW. While the sender’s serial monitor shows the correct sensor values and reports the expected struct size (for example, 48 bytes), the receiver consistently reports receiving only 32 bytes instead of the full struct size. This mismatch causes the receiver to print invalid or garbage data for temperature, humidity, and voltage. The problem appears because the sender and receiver must have exactly matching struct definitions, use the __attribute__((packed)) directive to prevent compiler padding, and ensure the sizeof() used in esp_now_send exactly matches the structure’s true size. If the struct size or alignment does not match, ESP-NOW’s raw binary transfer will decode incorrectly. Despite having the correct data on the sender side, I am still getting corrupted or incomplete data on the receiver because the length mismatch breaks the parsing. This misalignment makes it impossible to reliably display the sensor data on the receiver’s serial monitor, and I need to fix the struct packing, sending size, and callback checks so the full sensor message arrives and prints correctly.
So the receiver never gets messages that are the right size? If you put some magic numbers like 0xDECAFBAD at the beginning of the struct, do those come through? Aside from your struct, if you send a char array with all the letters, uppercase and lowercase, does the receiver get 52 bytes?
One not-obvious aspect of ESP-Now is that receivers can easily get broadcast messages (sent to the all-FF "peer" MAC) that are not intended for them. Suppose your next-door neighbor has the same idea as you, but swapped temperature and humidity in their struct. So even the size is not sufficient to identify which messages are meant for you.
If you know the MAC of expected senders, that could be checked. Otherwise, you need some kind of signature or checksum in the message to distinguish those intended for you from random bytes flying through the air.
BTW on ESP32,
class MacAddress : public Printable
so it can be printed with
#include <MacAddress.h>
MacAddress mac {recv_info->src_addr};
Serial.println(mac);
Usually ESP now has no problem with sending binary data from a structure.
At least it is working in my example.
ESP NOW Data Transmission ESP8266 & ESP32 (with Arduino IDE)
I transmit this message/packet:
// the structure defines what data should be send/received
struct Message {
uint16_t id = 0; // you might send an identifier for the board or an indicator for the mode of operation
uint16_t index = 0; // current index of pattern (actual pattern)
};
Message messageData;
Show us the code. You probably have an error in the send or receive side.
here is a simple example using ESP-NOW to transmit and receive a structure
transmitter code
// ESP-NOW transmit a structure
/*
Rui Santos
Complete project details at https://RandomNerdTutorials.com/esp-now-esp32-arduino-ide/
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files.
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
*/
#include <esp_now.h>
#include <WiFi.h>
// REPLACE WITH YOUR RECEIVER MAC Address
uint8_t broadcastAddress[] = {0x24,0x62,0xAB,0xE0,0x64,0x54}; //{ 0x84, 0xCC, 0xA8, 0x7A, 0x56, 0x6C }; //{0x24,0x62,0xAB,0xE0,0x64,0x54};
esp_now_peer_info_t peerInfo;
// test structure
struct __attribute__((packed)) Data {
int16_t seq; // sequence number
int32_t distance;
float voltage;
char text[50];
} data = { 0, 56, 3.14159, "hello test" }; // sample data
// callback when data is sent
void OnDataSent(const uint8_t *mac_addr, esp_now_send_status_t status) {
Serial.print("Last Packet Send Status:\t");
Serial.println(status == ESP_NOW_SEND_SUCCESS ? "Delivery Success" : "Delivery Fail");
}
void setup() {
// Init Serial Monitor
Serial.begin(115200);
Serial.println("ESP-NOW transmitting a structure");
// Set device as a Wi-Fi Station
WiFi.mode(WIFI_STA);
Serial.print("ESP32 Board MAC Address: ");
Serial.println(WiFi.macAddress());
// Init ESP-NOW
if (esp_now_init() != ESP_OK) {
Serial.println("Error initializing ESP-NOW");
return;
}
// Once ESPNow is successfully Init, we will register for Send CB to
// get the status of Trasnmitted packet
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() {
// Send data structure via ESP-NOW
Serial.printf("seq %d distaance %ld voltage %f text '%s'\n",
(int)data.seq, (long)data.distance, data.voltage, data.text);
esp_now_send(broadcastAddress, (uint8_t *)&data, sizeof(data));
delay(1000);
data.seq++; // update data ready for next transmission
data.distance += 10;
data.voltage += 2.5;
data.text[9]++;
}
receiver code
// ESP-NOW receive a structure
/*
Rui Santos
Complete project details at https://RandomNerdTutorials.com/esp-now-esp32-arduino-ide/
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files.
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
*/
#include <esp_now.h>
#include <WiFi.h>
// test structure
struct __attribute__((packed)) Data {
int16_t seq; // sequence number
int32_t distance;
float voltage;
char text[50];
} data;
// callback function that will be executed when data is received
void OnDataRecv(const uint8_t *mac, const uint8_t *incomingData, int len) {
static int16_t seqExpected = 0, errors=0;
Serial.printf("Bytes received: %d ", len);
if (len == sizeof(data)) {
memcpy((void *)&data, (void *)incomingData, len);
Serial.printf("seq %d distaance %ld voltage %f text '%s' errors %d\n",
(int)data.seq, (long)data.distance, data.voltage, data.text, errors);
if (data.seq != seqExpected) // check sequence number received
Serial.printf("Error! seq expected %d received %d errors %d\n", seqExpected, data.seq, ++errors);
seqExpected = data.seq; // set sequence number ready for next data
seqExpected++;
} else
Serial.printf("ERROR! packek size expected %d receive %d errors %d\n", sizeof(data), len, ++errors);
}
void setup() {
// Initialize Serial Monitor
Serial.begin(115200);
Serial.println("ESP-NOW receive a structure");
// Set device as a Wi-Fi Station
WiFi.mode(WIFI_STA);
Serial.print("ESP32 Board MAC Address: ");
Serial.println(WiFi.macAddress());
// Init ESP-NOW
if (esp_now_init() != ESP_OK) {
Serial.println("Error initializing ESP-NOW");
return;
}
// Once ESPNow is successfully Init, we will register for recv CB to
// get recv packer info
esp_now_register_recv_cb(OnDataRecv);
}
void loop() {
}
if the transmitter and receiver are the same type of microcontroller or you are careful with packing and object boundaries it is more efficient to remove the attribute((packed))
some serial output
ESP-NOW transmitter
ESP-NOW transmitting a structure
ESP32 Board MAC Address: 08:3A:F2:B7:F8:F4
seq 0 distaance 56 voltage 3.141590 text 'hello test'
Last Packet Send Status: Delivery Fail
seq 1 distaance 66 voltage 5.641590 text 'hello tesu'
Last Packet Send Status: Delivery Fail
seq 2 distaance 76 voltage 8.141590 text 'hello tesv'
Last Packet Send Status: Delivery Success
seq 3 distaance 86 voltage 10.641590 text 'hello tesw'
Last Packet Send Status: Delivery Success
seq 4 distaance 96 voltage 13.141590 text 'hello tesx'
Last Packet Send Status: Delivery Success
seq 5 distaance 106 voltage 15.641590 text 'hello tesy'
Last Packet Send Status: Delivery Success
receiver
ESP-NOW receive a structure
ESP32 Board MAC Address: 84:CC:A8:7A:56:6C
Bytes received: 60 seq 2 distaance 76 voltage 8.141590 text 'hello tesv'
Error! seq expected 0 received 2
Bytes received: 60 seq 3 distaance 86 voltage 10.641590 text 'hello tesw'
Bytes received: 60 seq 4 distaance 96 voltage 13.141590 text 'hello tesx'
Bytes received: 60 seq 5 distaance 106 voltage 15.641590 text 'hello tesy'
Bytes received: 60 seq 6 distaance 116 voltage 18.141590 text 'hello tesz'
Bytes received: 60 seq 7 distaance 126 voltage 20.641590 text 'hello tes{'
worked OK at 5 to 6 metres thru a foil backed plasterboard wall
failed at 6/7 metres thru two foil backed pasterbaord walls
Bytes received: 60 seq 8 distaance 136 voltage 23.141590 text 'hello tes|' errors 3
Bytes received: 60 seq 9 distaance 146 voltage 25.641590 text 'hello tes}' errors 3
Bytes received: 60 seq 10 distaance 156 voltage 28.141590 text 'hello tes~' errors 3
Bytes received: 60 seq 12 distaance 176 voltage 33.141590 text 'hello tes�' errors 3
Error! seq expected 11 received 12 errors 4
Bytes received: 60 seq 13 distaance 186 voltage 35.641590 text 'hello tes�' errors 4
Bytes received: 60 seq 14 distaance 196 voltage 38.141590 text 'hello tes�' errors 4
Bytes received: 60 seq 15 distaance 206 voltage 40.641590 text 'hello tes�' errors 4
Bytes received: 60 seq 16 distaance 216 voltage 43.141590 text 'hello tes�' errors 4
reception quality depends on distance between nodes and environment, e.g. walls, furniture, plants, etc
if using multiple nodes look at ESP-MESH
The error is in code you forgot to post.