Gooday Ladies & Gentleman of the Jury,
I seem to have an issue with the data encoding used by the ESP-Now framework, specifically around the actual bytes returned.
I've now gone sofar as to create a test message typedef that looks like this:
(Exhibit A)
typedef struct msg_test
{
uint8_t a;
uint8_t b;
uint8_t c;
uint8_t d;
uint8_t e;
uint16_t f;
uint32_t g;
uint8_t tx_mac[6];
} msg_test_t;
This is referenced on both esp-32 dev modules.
When I setup the message with the following data:
(Exhibit B)
msg_test_t test_message;
test_message.a = 50;
test_message.b = 146;
test_message.c = 11;
test_message.d = 104;
test_message.e = 0;
test_message.f = 710;
test_message.g = 1717413152;
memcpy(test_message.tx_mac, comms.mac_address, 6);
esp_err_t result = esp_now_send(comms.upstream_mac_addr, (uint8_t *)&test_message, sizeof(msg_timesync_req));
if (result == ESP_OK) {
debugln("Sent OK.");
}
I expect to see the following bytes:
(Exhibit C)

However the data received is:
(Exhibit D)

The bytes are captured in the receiving module with this code:
(Exhibit E)
void on_data_recv(const esp_now_recv_info_t* esp_now_info, const uint8_t* data, int data_len) {
Serial.printf("Msg Type %u: %u bytes\n", msg_type, data_len);
Serial.println("+++++++++++++ DATA STREAM BEGIN +++++++++++++");
for (int i = 0; i < data_len; i++) {
Serial.printf("0x%02X\n", data[i]);
}
Serial.println("+++++++++++++ DATA STREAM END +++++++++++++");
}
(Guilty as charged, for now. I know the above code is not best practice
)
I'm lost as to where the addition 3 bytes (highlighted on second image) are inserted.
I tried to find the actual encoding used on the Expressif Github; both under their esp-idf and esp-now repositories. As well as searched through the ESP-IDF documentation...
Side note:
ESP IDF Version : 5.1.4 (As reported by the ESP-32)
Back the matter at hand...
The message does decode correctly, so that portion works as advertised. ![]()
All the messages start with the exact same fields (except for the test message):
(Exhibit F)
uint8_t msg_type_id; /**< Msg Type Id > */
uint32_t mesh_id; /**< Mesh Id > */
uint8_t tx_mac[6]; /**< Sender Mac Address > */
I can identify the message type by looking at the first byte of data sent:
(Exhibit G)
uint8_t msg_type = data[0];
however i cannot query the mesh id, or the tx mac field, by simply coping the data:
(Exhibit H)
uint32_t mesh_id;
memcpy(mesh_id, data+1, sizeof(mesh_id));
As the data returns as follow:
(Exhibit I)
typedef for this message:
(Exhibit J)
typedef struct msg_pairing
{
uint8_t msg_type_id; /**< Msg Type Id > */
uint32_t mesh_id; /**< Mesh Id > */
uint8_t tx_mac[6]; /**< Sender Mac Address > */
uint8_t rx_mac[6]; /**< Reciever Mac Address > */
uint8_t channel;
uint8_t mod_type;
} msg_pairing_t;
(uint8_t as 4 bytes?!
)
Interestingly the data length seems to always be in multiples of 4.
If anyone knows how they get to this encoding; or can point me to the algorithm used, I would appreciate it.
Ladies & Gentleman of the Jury, this now concludes my opening statement.
Thank you,
PS. If I've missed something obvious, please do not have me drawn and quartered...
