giovedì 13 novembre 2025

test ESPNow con IDF

Ho provato Espnow, un protocollo per inviare brevi messaggi tra Esp32 e simili senza l'appoggio di un accesspoint 

 ho usato Idf 5.3.1 ed il programma di esempio

idf.py create-project-from-example "espressif/esp-now:get-started"

idf.py menuconfig

Example configuration 

CONFIG_ESPNOW_CHANNEL → e.g. 1

 CONFIG_ESPNOW_SEND_LEN → e.g. 200

 CONFIG_ESPNOW_SEND_COUNT → e.g. 100

 CONFIG_ESPNOW_SEND_DELAY → e.g. 1000 (ms)

se non si vuole un progetto di esempio si aggiunge il componente
idf.py add-dependency "espressif/esp-now" 

 l'esempio si puo' usare in assenza di wifi e si carica lo stesso firmware di esempio su entrambi i dispositivi. A seconda di send_param->magic=esp_random() viene scelto quale tra i due dispositivi e' il sender e quale e' il receiver 

se si vuole forzare il ruolo si 

#define FORCE_SENDER 1 // 1 = always sender, 0 = always receiver 

sender.c (a seconda delle impostazione di peer mac la comunicazione puo' essere broadcast, specificando come Mac Address FF:FF:FF:FF:FF:FF od indirizzata specificatamente ad un dispositivo)

==================================== 

#include "esp_wifi.h"
#include "esp_now.h"
#include "esp_log.h"
#include "nvs_flash.h"

#include "string.h"

static const char *TAG = "ESPNOW_SENDER";

// 👉 Replace this with your receiver’s MAC address (check via `esp_read_mac`)
uint8_t peer_mac[] = {0x24, 0x6F, 0x28, 0xAA, 0xBB, 0xCC};

static void send_cb(const uint8_t *mac_addr, esp_now_send_status_t status) {
    ESP_LOGI(TAG, "Send to %02X:%02X:%02X:%02X:%02X:%02X  status: %s",
             mac_addr[0], mac_addr[1], mac_addr[2],
             mac_addr[3], mac_addr[4], mac_addr[5],
             status == ESP_NOW_SEND_SUCCESS ? "OK" : "FAIL");
}

void app_main(void) {
    ESP_ERROR_CHECK(nvs_flash_init());
    ESP_ERROR_CHECK(esp_netif_init());
    ESP_ERROR_CHECK(esp_event_loop_create_default());
    ESP_ERROR_CHECK(esp_wifi_init(&(wifi_init_config_t)WIFI_INIT_CONFIG_DEFAULT()));
    ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA));
    ESP_ERROR_CHECK(esp_wifi_start());
    ESP_ERROR_CHECK(esp_wifi_set_channel(1, WIFI_SECOND_CHAN_NONE));

    ESP_ERROR_CHECK(esp_now_init());
    ESP_ERROR_CHECK(esp_now_register_send_cb(send_cb));

    esp_now_peer_info_t peer = {0};
    memcpy(peer.peer_addr, peer_mac, 6);
    peer.channel = 1;
    peer.encrypt = false;
    ESP_ERROR_CHECK(esp_now_add_peer(&peer));

    const char *msg = "Hello ESPNOW";
    while (1) {
        esp_err_t res = esp_now_send(peer_mac, (uint8_t *)msg, strlen(msg));
        if (res == ESP_OK) ESP_LOGI(TAG, "Message sent: %s", msg);
        else ESP_LOGE(TAG, "Send error: %s", esp_err_to_name(res));
        vTaskDelay(pdMS_TO_TICKS(1000));
    }
}

================================ 

receiver.c

============================= 

#include "esp_wifi.h"
#include "esp_now.h"
#include "esp_log.h"
#include "nvs_flash.h"

static const char *TAG = "ESPNOW_RECEIVER";

static void recv_cb(const esp_now_recv_info_t *info, const uint8_t *data, int len) {
    ESP_LOGI(TAG, "From %02X:%02X:%02X:%02X:%02X:%02X | Len: %d | Data: %.*s",
             info->src_addr[0], info->src_addr[1], info->src_addr[2],
             info->src_addr[3], info->src_addr[4], info->src_addr[5],
             len, len, data);
}

void app_main(void) {
    ESP_ERROR_CHECK(nvs_flash_init());
    ESP_ERROR_CHECK(esp_netif_init());
    ESP_ERROR_CHECK(esp_event_loop_create_default());
    ESP_ERROR_CHECK(esp_wifi_init(&(wifi_init_config_t)WIFI_INIT_CONFIG_DEFAULT()));
    ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA));
    ESP_ERROR_CHECK(esp_wifi_start());
    ESP_ERROR_CHECK(esp_wifi_set_channel(1, WIFI_SECOND_CHAN_NONE));

    ESP_ERROR_CHECK(esp_now_init());
    ESP_ERROR_CHECK(esp_now_register_recv_cb(recv_cb));

    ESP_LOGI(TAG, "Receiver ready");
}

================================= 

se si vuole mandare variabili di tipo differente nel pacchetto queste devono essere incluse in una struttura. La lunghezza dei pacchetti e' 250 bytes

================================= 

#include "esp_wifi.h"
#include "esp_now.h"
#include "esp_log.h"
#include "nvs_flash.h"
#include <string.h>

static const char *TAG = "ESPNOW_SENDER";

uint8_t peer_mac[] = {0x24, 0x6F, 0x28, 0xAA, 0xBB, 0xCC};

// Define your custom data structure
typedef struct {
    uint32_t id;
    float temperature;
    float humidity;
    int status;
    char label[16];
} sensor_packet_t;

static void send_cb(const uint8_t *mac_addr, esp_now_send_status_t status) {
    ESP_LOGI(TAG, "Send to %02X:%02X:%02X:%02X:%02X:%02X  status: %s",
             mac_addr[0], mac_addr[1], mac_addr[2],
             mac_addr[3], mac_addr[4], mac_addr[5],
             status == ESP_NOW_SEND_SUCCESS ? "OK" : "FAIL");
}

void app_main(void) {
    ESP_ERROR_CHECK(nvs_flash_init());
    ESP_ERROR_CHECK(esp_netif_init());
    ESP_ERROR_CHECK(esp_event_loop_create_default());
    ESP_ERROR_CHECK(esp_wifi_init(&(wifi_init_config_t)WIFI_INIT_CONFIG_DEFAULT()));
    ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA));
    ESP_ERROR_CHECK(esp_wifi_start());
    ESP_ERROR_CHECK(esp_wifi_set_channel(1, WIFI_SECOND_CHAN_NONE));

    ESP_ERROR_CHECK(esp_now_init());
    ESP_ERROR_CHECK(esp_now_register_send_cb(send_cb));

    esp_now_peer_info_t peer = {0};
    memcpy(peer.peer_addr, peer_mac, 6);
    peer.channel = 1;
    peer.encrypt = false;
    ESP_ERROR_CHECK(esp_now_add_peer(&peer));

    sensor_packet_t pkt = {0};
    pkt.id = 1;

    while (1) {
        pkt.temperature = 22.5 + (esp_random() % 100) / 10.0;
        pkt.humidity = 60.0 + (esp_random() % 100) / 10.0;
        pkt.status = esp_random() % 2;
        strcpy(pkt.label, "Node_A");

        esp_err_t res = esp_now_send(peer_mac, (uint8_t *)&pkt, sizeof(pkt));
        if (res == ESP_OK)
            ESP_LOGI(TAG, "Sent packet: id=%lu T=%.1f H=%.1f status=%d",
                     pkt.id, pkt.temperature, pkt.humidity, pkt.status);
        else
            ESP_LOGE(TAG, "Send error: %s", esp_err_to_name(res));

        pkt.id++;
        vTaskDelay(pdMS_TO_TICKS(1000));
    }
}

==================== 

#include "esp_wifi.h"
#include "esp_now.h"
#include "esp_log.h"
#include "nvs_flash.h"
#include <string.h>

static const char *TAG = "ESPNOW_RECEIVER";

typedef struct {
    uint32_t id;
    float temperature;
    float humidity;
    int status;
    char label[16];
} sensor_packet_t;

static void recv_cb(const esp_now_recv_info_t *info, const uint8_t *data, int len) {
    if (len != sizeof(sensor_packet_t)) {
        ESP_LOGW(TAG, "Invalid packet size: %d", len);
        return;
    }

    sensor_packet_t pkt;
    memcpy(&pkt, data, sizeof(pkt));

    ESP_LOGI(TAG, "From %02X:%02X:%02X:%02X:%02X:%02X | id=%lu | T=%.1f | H=%.1f | status=%d | label=%s",
             info->src_addr[0], info->src_addr[1], info->src_addr[2],
             info->src_addr[3], info->src_addr[4], info->src_addr[5],
             pkt.id, pkt.temperature, pkt.humidity, pkt.status, pkt.label);
}

void app_main(void) {
    ESP_ERROR_CHECK(nvs_flash_init());
    ESP_ERROR_CHECK(esp_netif_init());
    ESP_ERROR_CHECK(esp_event_loop_create_default());
    ESP_ERROR_CHECK(esp_wifi_init(&(wifi_init_config_t)WIFI_INIT_CONFIG_DEFAULT()));
    ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA));
    ESP_ERROR_CHECK(esp_wifi_start());
    ESP_ERROR_CHECK(esp_wifi_set_channel(1, WIFI_SECOND_CHAN_NONE));

    ESP_ERROR_CHECK(esp_now_init());
    ESP_ERROR_CHECK(esp_now_register_recv_cb(recv_cb));

    ESP_LOGI(TAG, "Receiver ready");
}
 

 

 

Nessun commento:

Posta un commento

Algoritmo Reed Solomon

 Sto progettando una trasmissione radio di immagini ed uno dei vincoli e' che non e' garantita la perfetta qualita' della trasmi...