Wi-Fi sending delays

maximekli
Posts: 8
Joined: Thu May 14, 2020 12:29 pm

Wi-Fi sending delays

Postby maximekli » Wed Jul 29, 2020 10:57 am

Hello,

I am currently working on a project where an ESP32 based board is used in a legged robot as a bridge between a control computer using Ethernet or Wi-Fi and a set of sensors and actuators using SPI. The control loop is working at 1kHz.

While working in Wi-Fi, we are sometimes witnessing some sending delays, as if the ESP32 was queuing or holding the outgoing packets, not sending them immediately.

The following graph represents some Wireshark capture of the ESP to PC communication, where the ESP sends a message every 1ms.
X axis holds the timestamps of when each packet was captured, and Y axis is for the packet index (incremented after each sending instruction).
figure_post.png
figure_post.png (54.52 KiB) Viewed 198 times
We should expect the plotted dots to almost lie on a straight line (the blue line for instance), whereas we clearly see that packets are sometimes way off, as if they were sent by the masterboard with a delay (represented by the red lines).

Any idea on how to avoid this buffering of the packets before sending them or what could be the cause?

Here is the Wi-Fi code we are using:
direct_wifi.h

Code: Select all

#ifndef DIRECT_WIFI_H
#define DIRECT_WIFI_H

#include <stdlib.h>
#include <string.h>
#include "freertos/FreeRTOS.h"
#include "freertos/semphr.h"
#include "freertos/timers.h"
#include "esp_event.h"
#include "nvs_flash.h"
#include "tcpip_adapter.h"
#include "esp_wifi.h"
#include "esp_log.h"
#include "esp_system.h"
#include "esp_now.h"

esp_err_t esp_wifi_internal_set_fix_rate(wifi_interface_t ifx, bool en, wifi_phy_rate_t rate);

#if CONFIG_WIFI_DATARATE_6
  #define CONFIG_WIFI_DATARATE WIFI_PHY_RATE_6M
#elif CONFIG_WIFI_DATARATE_9
  #define CONFIG_WIFI_DATARATE WIFI_PHY_RATE_9M
#elif CONFIG_WIFI_DATARATE_12
  #define CONFIG_WIFI_DATARATE WIFI_PHY_RATE_12M
#elif CONFIG_WIFI_DATARATE_18
  #define CONFIG_WIFI_DATARATE WIFI_PHY_RATE_18M
#elif CONFIG_WIFI_DATARATE_24
  #define CONFIG_WIFI_DATARATE WIFI_PHY_RATE_24M
#elif CONFIG_WIFI_DATARATE_36
  #define CONFIG_WIFI_DATARATE WIFI_PHY_RATE_36M
#elif CONFIG_WIFI_DATARATE_48
  #define CONFIG_WIFI_DATARATE WIFI_PHY_RATE_48M
#elif CONFIG_WIFI_DATARATE_56
  #define CONFIG_WIFI_DATARATE WIFI_PHY_RATE_56M
#else
  #error No valid WIFI datarate specified
#endif

void (*wifi_recv_cb)(uint8_t src_mac[6], uint8_t *data, int len, char eth_or_wifi); // eth_or_wifi = 'e' when eth is used, 'w' when wifi is used

void wifi_init();
void wifi_deinit_func();
void wifi_send_data(uint8_t *data, int len);
void wifi_attach_recv_cb(void (*cb)(uint8_t src_mac[6], uint8_t *data, int len, char eth_or_wifi));
void wifi_detach_recv_cb();
void wifi_change_channel(uint8_t wifi_channel);
static void wifi_recv_func(uint8_t src_mac[6], uint8_t *data, int len);

#endif

direct_wifi.c

Code: Select all

#include "direct_wifi.h"

static const char *WIFI_TAG = "Direct_Wifi";

void (*wifi_recv_cb)(uint8_t src_mac[6], uint8_t *data, int len, char eth_or_wifi) = NULL; // eth_or_wifi = 'e' when eth is used, 'w' when wifi is used

esp_now_peer_info_t peer;
static uint8_t s_example_broadcast_mac[ESP_NOW_ETH_ALEN] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};

void wifi_send_data(uint8_t *data, int len)
{
  esp_now_send(peer.peer_addr, data, len);
}

static void wifi_recv_func(uint8_t src_mac[6], uint8_t *data, int len)
{
  if (wifi_recv_cb == NULL)
  {
    ESP_LOGW(WIFI_TAG, "Wifi frame received but no callback function is set on received...");
  }
  else
  {
    wifi_recv_cb(src_mac, data, len, 'w');
  }
}

static void wifi_send_cb(const uint8_t *mac_addr, esp_now_send_status_t status)
{
  if (status != ESP_OK)
  {
    //error_send++;
  }
}

void wifi_attach_recv_cb(void (*cb)(uint8_t src_mac[6], uint8_t *data, int len, char eth_or_wifi))
{
  wifi_recv_cb = cb;
}

void wifi_detach_recv_cb()
{
  wifi_recv_cb = NULL;
}

void wifi_init()
{
  /* Init 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 WiFi */
  tcpip_adapter_init();
  wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
  cfg.ampdu_tx_enable = 0;
  ESP_ERROR_CHECK(esp_wifi_init(&cfg));
  ESP_ERROR_CHECK(esp_wifi_set_storage(WIFI_STORAGE_RAM));
  ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA));
  wifi_country_t country = {.cc = "JP", .schan = 1, .nchan = 14, .policy = WIFI_COUNTRY_POLICY_MANUAL};
  ESP_ERROR_CHECK(esp_wifi_start());
  ESP_ERROR_CHECK(esp_wifi_set_country(&country));
  ESP_ERROR_CHECK(esp_wifi_set_channel(1, WIFI_SECOND_CHAN_NONE));
  ESP_ERROR_CHECK(esp_wifi_internal_set_fix_rate(ESP_IF_WIFI_STA, true, CONFIG_WIFI_DATARATE));

  /* Init ESPNOW */
  ESP_ERROR_CHECK(esp_now_init());
  ESP_ERROR_CHECK(esp_now_register_recv_cb(wifi_recv_func));

  memset(&peer, 0, sizeof(esp_now_peer_info_t));
  peer.channel = 1;
  peer.ifidx = ESP_IF_WIFI_STA;
  peer.encrypt = false;
  memcpy(peer.peer_addr, s_example_broadcast_mac, ESP_NOW_ETH_ALEN);
  ESP_ERROR_CHECK(esp_now_add_peer(&peer));
}

void wifi_deinit_func()
{
  ESP_ERROR_CHECK(esp_now_deinit());
  ESP_ERROR_CHECK(esp_wifi_stop());
  ESP_ERROR_CHECK(esp_wifi_deinit());
}

void wifi_change_channel(uint8_t wifi_channel)
{
  ESP_ERROR_CHECK(esp_wifi_set_channel(wifi_channel, WIFI_SECOND_CHAN_NONE));
  peer.channel = wifi_channel;
  ESP_ERROR_CHECK(esp_now_mod_peer(&peer));
}

Thank you for your help,

Maxime

The project : https://open-dynamic-robot-initiative.github.io/
The ESP32 firmware : https://github.com/maximekli/master-boa ... r/firmware

Who is online

Users browsing this forum: No registered users and 20 guests