ESPNow - receiving wrong data

Rocket2022
Posts: 3
Joined: Sat Jun 25, 2022 6:08 am

ESPNow - receiving wrong data

Postby Rocket2022 » Sat Jun 25, 2022 6:38 am

Hi,

I've created some code to send and receive simple data over ESPNow.
The problem is that I've always receive 36 instead of 1 in the state value of my sending_data structure.

For the ESPNow connection I've created following class:

Can anybody help?

Code: Select all

#include "ESPConnection.h"

static const char *TAG = "ESPConnection";

void ESPConnection::get_master_mac(uint8_t *mac)
{
    uint8_t *master_mac = convert_mac_address(_master_mac);

    for (int i = 0; i < 6; i++)
    {
        memcpy(&mac[i], &master_mac[i], sizeof(mac[i]));
    }
}

void ESPConnection::init(uint32_t mode, esp_now_send_cb_t send_cb, esp_now_recv_cb_t receiv_cb)
{
    // Init Wifi
    init_wifi();

    // Init ESP32 Now
    init_esp32_now(mode, send_cb, receiv_cb);
}

/* WiFi should start before using ESPNOW */
void ESPConnection::init_wifi()
{
    ESP_ERROR_CHECK(esp_netif_init());
    ESP_ERROR_CHECK(esp_event_loop_create_default());
    wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
    ESP_ERROR_CHECK(esp_wifi_init(&cfg));
    ESP_ERROR_CHECK(esp_wifi_set_storage(WIFI_STORAGE_RAM));
    ESP_ERROR_CHECK(esp_wifi_set_mode(ESPNOW_WIFI_MODE));
    ESP_ERROR_CHECK(esp_wifi_start());

#if CONFIG_ESPNOW_ENABLE_LONG_RANGE
    ESP_ERROR_CHECK(esp_wifi_set_protocol(ESPNOW_WIFI_IF, WIFI_PROTOCOL_11B | WIFI_PROTOCOL_11G | WIFI_PROTOCOL_11N | WIFI_PROTOCOL_LR));
#endif
}

void ESPConnection::init_esp32_now(uint32_t mode, esp_now_send_cb_t send_cb, esp_now_recv_cb_t receiv_cb)
{
    ESP_ERROR_CHECK(esp_now_init());

    // Only send data
    if (mode == 1)
    {
        // esp_now_register_send_cb(ESPConnection::on_alarm_data_sent);
        ESP_ERROR_CHECK(esp_now_register_send_cb(send_cb));
    }
    // Only receive data
    else if (mode == 2)
    {
        // esp_now_register_recv_cb(ESPConnection::on_alarm_data_received);
        ESP_ERROR_CHECK(esp_now_register_recv_cb(receiv_cb));
    }
    // Send and receive data
    else if (mode == 3)
    {
        // esp_now_register_recv_cb(ESPConnection::on_alarm_data_received);
        // esp_now_register_send_cb(ESPConnection::on_alarm_data_sent);
        ESP_ERROR_CHECK(esp_now_register_send_cb(send_cb));
        ESP_ERROR_CHECK(esp_now_register_recv_cb(receiv_cb));
    }
}

void ESPConnection::read_mac(uint8_t *mac)
{
    // unsigned char mac_base[6] = {0};
    // esp_efuse_mac_get_default(mac_base);
    // esp_read_mac(mac_base, ESP_MAC_WIFI_STA);
    // unsigned char mac_local_base[6] = {0};
    // unsigned char mac_uni_base[6] = {0};
    // esp_derive_local_mac(mac_local_base, mac_uni_base);

    esp_efuse_mac_get_default(mac);
    esp_read_mac(mac, ESP_MAC_WIFI_STA);
}

void ESPConnection::register_master(mac_address mac)
{
    // Register peer
    esp_now_peer_info_t peerInfo = {};
    peerInfo.channel = 0;
    peerInfo.encrypt = false;
    // peerInfo.ifidx = WIFI_IF_AP;
    uint8_t *converted_address = convert_mac_address(mac);
    memcpy(peerInfo.peer_addr, converted_address, 6);
    ESP_ERROR_CHECK(esp_now_add_peer(&peerInfo));

    // Store master
    _master_mac = mac;
}

void ESPConnection::register_slave(mac_address mac)
{
    // Register peer
    esp_now_peer_info_t peerInfo = {};
    peerInfo.channel = 0;
    peerInfo.encrypt = false;
    // peerInfo.ifidx = WIFI_IF_AP;
    uint8_t *converted_address = convert_mac_address(mac);
    // uint8_t *converted_address = { 0 };
    // convert_mac_address(mac, converted_address);
    memcpy(peerInfo.peer_addr, converted_address, 6);
    ESP_ERROR_CHECK(esp_now_add_peer(&peerInfo));

    // Store slave to list
    _slave_mac_list.push_back(mac);
}

esp_err_t ESPConnection::send_data(const uint8_t *data)
{
    return esp_now_send(0, (uint8_t *)&data, sizeof(data));
}

uint8_t *ESPConnection::convert_mac_address(mac_address mac_address)
{
    static uint8_t mac[6] = {0, 0, 0, 0, 0, 0};
    mac[0] = mac_address.octet1;
    mac[1] = mac_address.octet2;
    mac[2] = mac_address.octet3;
    mac[3] = mac_address.octet4;
    mac[4] = mac_address.octet5;
    mac[5] = mac_address.octet6;

    return mac;
}
And here is my main file:

Code: Select all

#include <freertos/FreeRTOS.h>
#include <freertos/task.h>
#include "nvs_flash.h"
#include "../components/esp_connection/ESPConnection.h"
#include "../components/trigger/Trigger.h"

static const char *TAG = "Example";

typedef enum
{
    MASTER,
    SLAVE,
} device_type_t;

typedef struct sending_data
{
    bool state;
} sending_data_t;

sending_data_t _sending_data;
Trigger _button_send_data = Trigger(GPIO_NUM_4);
device_type_t _device_type;
ESPConnection _esp;
uint8_t flash_mode;

void handle_device();
void handle_master_device();
void handle_slave_device();
void init_data();
void init_esp();
void on_sending_data_received(const uint8_t *mac, const uint8_t *incomingData, int len);
void on_sending_data_sent(const uint8_t *mac_addr, esp_now_send_status_t status);
void print_local_mac();
void print_mac(unsigned char mac[6]);

void handle_device()
{
    if (_device_type == MASTER)
    {
        handle_master_device();
    }
    else if (_device_type == SLAVE)
    {
        handle_slave_device();
    }
}

void handle_master_device()
{
    ESP_LOGI(TAG, "Master device mode");

    if (_button_send_data.get_state() == true)
    {
        _sending_data.state = true;

        _esp.send_data((uint8_t *)&_sending_data);
   }
}

void handle_slave_device()
{
    ESP_LOGI(TAG, "Slave device mode");

    if (_button_send_data.get_state() == true)
    {
        _sending_data.state = true;

        _esp.send_data((uint8_t *)&_sending_data);

    }
}

void init_data()
{
    _sending_data = {0};
    _sending_data.state = {false};
}

void init_esp()
{
    // Initialize ESP_NOW
    _esp.init(3, on_sending_data_sent, on_sending_data_received);

    if (_device_type == MASTER)
    {
        mac_address slave_mac;
        slave_mac.octet1 = 0x21;
        slave_mac.octet2 = 0x33;
        slave_mac.octet3 = 0x23;
        slave_mac.octet4 = 0x3d;
        slave_mac.octet5 = 0xd3;
        slave_mac.octet6 = 0x32;

        _esp.register_slave(slave_mac);
    }
    else if (_device_type == SLAVE)
    {
        slave_mac.octet1 = 0x21;
        slave_mac.octet2 = 0x33;
        slave_mac.octet3 = 0x23;
        slave_mac.octet4 = 0x3d;
        slave_mac.octet5 = 0xe3;
        slave_mac.octet6 = 0x32;

        _esp.register_master(master_mac);
    }
}

// Callback when data is received
void on_sending_data_received(const uint8_t *mac, const uint8_t *incomingData, int len)
{
    memcpy(&_sending_data, incomingData, sizeof(_sending_data));

    // sending_data_t *buf = (sending_data_t *)incomingData;

    // if (len < sizeof(sending_data_t))
    // {
    //     ESP_LOGE(TAG, "Receive ESPNOW data too short, len:%d", len);
    // }
    // ESP_LOGI(TAG, "Sending data state: %d", buf->state);

    // _sending_data.state = buf->state;

    ESP_LOGI(TAG, "Bytes received: %d", len);

    ESP_LOGI(TAG, "Sending data state: %d", _sending_data.state);
}

// Callback when data is sent
void on_sending_data_sent(const uint8_t *mac_addr, esp_now_send_status_t status)
{
    char macStr[18];

    // Copies the sender mac address to a string
    snprintf(macStr, sizeof(macStr), "%02x:%02x:%02x:%02x:%02x:%02x",
             mac_addr[0], mac_addr[1], mac_addr[2], mac_addr[3], mac_addr[4], mac_addr[5]);

    ESP_LOGI(TAG, "Packet to: %s", macStr);

    ESP_LOGI(TAG, "Send status: %s", (status == ESP_NOW_SEND_SUCCESS ? "Delivery Success" : "Delivery Fail"));
}

void print_local_mac()
{
    unsigned char mac[6] = {0};
    _esp.read_mac(mac);

    ESP_LOGI(TAG, "Local");
    print_mac(mac);
}

void print_master_mac()
{
    unsigned char mac[6] = {0};
    _esp.get_master_mac(mac);

    ESP_LOGI(TAG, "Master");
    print_mac(mac);
}

void print_mac(unsigned char mac[6])
{
    char macStr[18];

    // Copies the sender mac address to a string
    snprintf(macStr, sizeof(macStr), "%02x:%02x:%02x:%02x:%02x:%02x",
             mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);

    ESP_LOGI(TAG, "MAC: %s", macStr);
}

extern "C" void app_main()
{

#if CONFIG_DEVICE_MODE_MASTER == 1
    _device_type = MASTER;
#else
    _device_type = SLAVE;
#endif

    // Initialize NVS
    esp_err_t ret = nvs_flash_init();
    if (ret == ESP_ERR_NVS_NO_FREE_PAGES || ret == ESP_ERR_NVS_NEW_VERSION_FOUND)
    {
        ESP_ERROR_CHECK(nvs_flash_erase());
        ret = nvs_flash_init();
    }
    ESP_ERROR_CHECK(ret);

    // Init ESP
    init_esp();

    // Init data
    init_data();

    // Print MAC
    // print_local_mac();
    // print_master_mac();
    while (true)
    {
        handle_device();

        vTaskDelay(1000 / portTICK_RATE_MS);
    }
}

Rocket2022
Posts: 3
Joined: Sat Jun 25, 2022 6:08 am

Re: ESPNow - receiving wrong data

Postby Rocket2022 » Mon Jun 27, 2022 7:40 pm

Hello together,

I figured out that I always receive too long data.

Has someone a hint for me why the data is too long?

Code: Select all

void on_sending_data_received(const uint8_t *mac, const uint8_t *incomingData, int len)
{
    memcpy(&_sending_data, incomingData, sizeof(_sending_data));

    if (len < sizeof(_sending_data))
    {
        ESP_LOGE(TAG, "Receive ESPNOW data too short, len:%d", len);
    }

    if (len > sizeof(_sending_data))
    {
        ESP_LOGE(TAG, "Receive ESPNOW data too long, len:%d", len);
    }

    ESP_LOGI(TAG, "Bytes received: %d", len);
}

boarchuz
Posts: 559
Joined: Tue Aug 21, 2018 5:28 am

Re: ESPNow - receiving wrong data

Postby boarchuz » Tue Jun 28, 2022 7:07 am

Rocket2022 wrote:
Sat Jun 25, 2022 6:38 am

Code: Select all

esp_err_t ESPConnection::send_data(const uint8_t *data)
{
    return esp_now_send(0, (uint8_t *)&data, sizeof(data));
}
Instead of sending [sizeof(object that data points to)] bytes of [object that data points to], you are sending [sizeof(the data pointer itself)] bytes of [a pointer to the data pointer].

You would typically have a second parameter for the number of bytes to send (if its generic), or take a pointer to your data type.

Code: Select all

esp_err_t ESPConnection::send_data(const uint8_t *data, size_t len)
{
    return esp_now_send(0, data, len);
}
// or
esp_err_t ESPConnection::send_data(const sending_data_t *data)
{
    return esp_now_send(0, (const uint8_t *)data, sizeof(*data));
}

Rocket2022
Posts: 3
Joined: Sat Jun 25, 2022 6:08 am

Re: ESPNow - receiving wrong data

Postby Rocket2022 » Wed Jun 29, 2022 1:03 pm

Hi boarchuz,

you are totaly right!

Thanks a lot!

BR
Marco

Who is online

Users browsing this forum: prodigysounds and 145 guests