I'm trying to make a very simple ESP-NOW program to help understand the basics. All of the information I've found online to date is very poor and unhelpful for newcomers trying to get the hang of this stuff.
I am just trying to make a program that tells the ESP32 to transmit a single variable via an ESP-NOW broadcast (that is, to FF:FF:FF:FF:FF:FF), and I also want the same code to be able to receive such a broadcast so other ESP32 chips could participate in this as a form of two-way communication. I don't want to pick any specific ESP-32 and I don't want any master/slave stuff or identifying devices if at all possible. I'd rather take care of that through my own code.
So far, what little information I can find about ESP-NOW makes it seems like it requires a struct to transmit data. And for some reason or another, the callback functions for receiving and sending seem to require pointers.
I also have no clue what esp_now_recv_info means in the context of the parameter for the receiver callback. Documentation says it's a struct with three members, but doesn't go into any further detail. It's unclear what is even supposed to be sent in that parameter. There's also an 8-bit data parameter which is a pointer and I don't really get what that means.
Here's the simplest code I've found that is closest to what I'm looking for so far:
Code: Select all
#include <Arduino.h>
#include <WiFi.h>
#include <esp_now.h>
// FF:FF:FF:FF:FF:FF is the broadcast address
uint8_t broadcastAddr[] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
esp_now_peer_info_t broadcastPeer;
typedef struct
{
int a;
float b;
char c;
} mymsg;
void OnDataRecv(const uint8_t* mac, const uint8_t* data, int len)
{
// Check message length
if (len != sizeof(mymsg))
{
Serial.println("Received invalid msg");
return; // return if invalid
}
// Get mac string from uint array
char macstr[32];
snprintf(macstr, 31, "%02X:%02X:%02X:%02X:%02X:%02X", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
// Cast data to mymsg* and print it's values
mymsg* msg = (mymsg*)data;
Serial.printf("[%s] Received: %d, %f, %c\n", macstr, msg->a, msg->b, msg->c);
}
void OnDataSent(const uint8_t* mac, esp_now_send_status_t stat)
{
// Get mac string from uint array (destination)
char macstr[32];
snprintf(macstr, 31, "%02X:%02X:%02X:%02X:%02X:%02X", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
// Log status
Serial.printf("[%s] Last Packet Sent: %s\n", macstr, stat == ESP_NOW_SEND_SUCCESS ? "Success" : "Fail");
}
void setup()
{
// init serial
Serial.begin(115200);
// init wifi
WiFi.mode(WIFI_STA);
// init espnow
if (esp_now_init() != ESP_OK)
{
Serial.println("Can't start espnow, rebooting");
vTaskDelay(5000 / portTICK_PERIOD_MS);
ESP.restart();
}
// populate peer info
broadcastPeer.channel = 0; // 0 = any
broadcastPeer.encrypt = false; // can't encrypt when broadcasting
memcpy(broadcastPeer.peer_addr, broadcastAddr, 6); // copy broadcast address
// register peer
if (esp_now_add_peer(&broadcastPeer) != ESP_OK)
{
Serial.println("Can't register espnow broadcast peer, rebooting");
vTaskDelay(5000 / portTICK_PERIOD_MS);
ESP.restart();
}
esp_now_register_send_cb(OnDataSent);
esp_now_register_recv_cb(OnDataRecv);
}
void loop()
{
// wait 5secs
vTaskDelay(5000 / portTICK_PERIOD_MS);
// populate message with random number
mymsg msg;
msg.a = random(10, 100);
msg.b = msg.a / 10.0;
msg.c = (msg.a % 26) + 'a';
// send message
esp_now_send(broadcastAddr, (uint8_t*)&msg, sizeof(msg));
}
Can anyone help me figure out how to make the most bare-bones ESP-NOW program possible that is two-way and uses indiscriminate broadcasting? Can you explain what the parameters do on the callbacks? Can I send individual variables rather than structs? Thanks.