Page 1 of 1

Helping making simplest ESP-NOW broadcast program (two way)

Posted: Fri Oct 25, 2024 1:31 am
by EP2003
Hello,

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));
}
Note that the receiver callback here receives an 8-bit value in the first parameter rather than a receiver info value. This gave me an error when I tried compiling it. In loop(), you can also see where the broadcastAddr (an 8-bit array) is sent. Strangely, the compiler gave me no errors when I fixed the receiver parameter even through I didn't change the arguments given to esp_now_send. Keep in mind that this program, which said it's for ESP32 ESP-NOW, was posted just a few months ago this year. So it shouldn't even be out of date or anything. Not sure if they made a mistake or what.

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.

Re: Helping making simplest ESP-NOW broadcast program (two way)

Posted: Tue Oct 29, 2024 10:14 pm
by MicroController
Maybe check the examples for Arduino.