ESP-NOW slow acknowledge from receiver

map_93
Posts: 2
Joined: Wed Nov 16, 2022 9:55 am

ESP-NOW slow acknowledge from receiver

Postby map_93 » Fri Nov 18, 2022 10:23 am

Hello,
Let me start by saying I am new to the esp32 platform, so excuse me for any blatant mistakes that might be present in my code.
I am trying to make an live audio transmission system using 2 esp32 and esp-now.
I managed to initiate communication successfully, but the results puzzle me a bit. I started out by sending 250 bytes and measuring the time between the esp_now_send() and the send callback function. This ranged from 600us to more than 20ms in a seemingly random fashion. Is this normal?
To understand if what I would like to achieve is at all feasible, I tried setting up the following system:
- The transmitter uses a timer interrupt with a frequency of 20kHz to output a sine wave on DAC1. After the first 250 points of the sine wave have been sent out on the DAC, the 250 points get sent via esp-now to the receiver.
- The receiver gets 250 bytes from the transmitter and copies these in a buffer. Through a timer interrupt with a frequency of 20kHz, every time a new 250-bytes packet is available, these get sent one by one to the DAC1 interface, therefore recreating the sine wave on the receiver end.
This is the code for the transmitter:

Code: Select all

#define CONFIG_ESP32_WIFI_AMPDU_RX_ENABLED 0
#define CONFIG_ESP32_WIFI_AMPDU_TX_ENABLED 0

#include <esp_now.h>
#include <esp_wifi.h>
#include <driver/adc.h>
#include <driver/dac.h>

uint8_t broadcastAddress[] = {0xC0, 0x49, 0xEF, 0xCA, 0x3B, 0x00}; //


uint8_t IN_BUFF[250]={128, 131, 134, 138, 141, 144, 147, 150, 153, 157, 160, 163, 166, 169, 172, 175, 178, 181, 184, 187, 189, 192, 195, 198, 200, 203, 205, 208, 210, 213, 215, 218, 220, 222, 224, 226, 228, 230, 232, 234, 236, 237, 239, 240, 242, 243, 244, 246, 247, 248, 249, 250, 251, 252, 252, 253, 253, 254, 254, 255, 255, 255, 255, 255, 255, 255, 254, 254, 254, 253, 253, 252, 251, 250, 249, 248, 247, 246, 245, 244, 242, 241, 240, 238, 236, 235, 233, 231, 229, 227, 225, 223, 221, 219, 216, 214, 212, 209, 207, 204, 202, 199, 196, 194, 191, 188, 185, 182, 179, 176, 173, 170, 167, 164, 161, 158, 155, 152, 149, 146, 142, 139, 136, 133, 130, 126, 123, 120, 117, 114, 110, 107, 104, 101, 98, 95, 92, 89, 86, 83, 80, 77, 74, 71, 68, 65, 62, 60, 57, 54, 52, 49, 47, 44, 42, 40, 37, 35, 33, 31, 29, 27, 25, 23, 21, 20, 18, 16, 15, 14, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 3, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 2, 2, 3, 3, 4, 4, 5, 6, 7, 8, 9, 10, 12, 13, 14, 16, 17, 19, 20, 22, 24, 26, 28, 30, 32, 34, 36, 38, 41, 43, 46, 48, 51, 53, 56, 58, 61, 64, 67, 69, 72, 75, 78, 81, 84, 87, 90, 93, 96, 99, 103, 106, 109, 112, 115, 118, 122, 125, 128};

uint8_t OUT_BUFF[250];

volatile uint8_t i=0;
volatile uint8_t sent=1;
volatile uint8_t ack=1;
volatile uint8_t dataReady=0;
volatile uint8_t pin_state=0;

hw_timer_t *My_timer = NULL;

esp_now_peer_info_t peerInfo;

// callback when data is sent
void OnDataSent(const uint8_t *mac_addr, esp_now_send_status_t status) {
  if(status){
      Serial.println("PACKET ERROR!");
  }
  else{
  	ack=1;
  }
}

void IRAM_ATTR sampleADC(){
  //sending 1 new sample of the sine wave to DAC1
  dac_output_voltage(DAC_CHANNEL_1, IN_BUFF[i++]);
  if(i==250){
    //when 250 samples have been sent to DAC1, if the previous esp-now frame has been sent, prepare new 250 bytes to be sent
    i=0;
    if(sent){
      memcpy(OUT_BUFF, IN_BUFF, 250);
      dataReady=1;
      sent=0;
    }
  }
}
 
void setup() {
  // Init Serial Monitor
  Serial.begin(115200);
  adc1_config_width(ADC_WIDTH_BIT_12);
  adc1_config_channel_atten(ADC1_CHANNEL_0, ADC_ATTEN_DB_0);
  dac_output_enable(DAC_CHANNEL_1);
  // Set device as a Wi-Fi Station
  esp_netif_init();
  wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
  esp_wifi_init(&cfg);
  esp_wifi_set_mode(WIFI_MODE_STA);
  esp_wifi_set_bandwidth(WIFI_IF_STA, WIFI_BW_HT40);
  esp_wifi_set_storage(WIFI_STORAGE_RAM);
  esp_wifi_set_ps(WIFI_PS_NONE);
  esp_wifi_start();
  // Init ESP-NOW
  if (esp_now_init() != ESP_OK) {
    Serial.println("Error initializing ESP-NOW");
    return;
  }
  esp_wifi_config_espnow_rate(WIFI_IF_STA, WIFI_PHY_RATE_54M);
  esp_now_register_send_cb(OnDataSent);
  
  // Register peer
  memcpy(peerInfo.peer_addr, broadcastAddress, 6);
  peerInfo.channel = 0;  
  peerInfo.encrypt = false;
  
  // Add peer        
  if (esp_now_add_peer(&peerInfo) != ESP_OK){
    Serial.println("Failed to add peer");
    return;
  }
  
  //Setting up a timer interrupt with frequency of 20kHz
  My_timer = timerBegin(0, 8, true);
  timerAttachInterrupt(My_timer, &sampleADC, true);
  timerAlarmWrite(My_timer, 500, true);
  Serial.println("Ready to start...");
  
  uint8_t started=0;
  while(!started){
    if(Serial.available()>0){
      char c=Serial.read();
      if(c=='1'){
        started=1;
      }
    }
  }
  Serial.println("Entering loop...");
  timerAlarmEnable(My_timer);
}
 
void loop() {
  //if new data ready to be sent and previous frame acknowledged by receiver, send new one
  if(dataReady && ack){
    esp_err_t result = esp_now_send(broadcastAddress, OUT_BUFF, sizeof(OUT_BUFF));
    sent=1;
    dataReady=0;
    ack=0;
  }
}
This is the code for the receiver

Code: Select all

#define CONFIG_ESP32_WIFI_AMPDU_RX_ENABLED 0
#define CONFIG_ESP32_WIFI_AMPDU_TX_ENABLED 0

#include <esp_now.h>
#include <esp_wifi.h>
#include <driver/dac.h>

// Structure example to receive data
// Must match the sender structure
uint8_t IN_BUFF[250];
uint8_t OUT_BUFF[250];

volatile uint8_t i=0;
volatile uint8_t data4dac=0;
volatile uint8_t niente=0;

hw_timer_t *My_timer = NULL;

// callback function that will be executed when data is received
void OnDataRecv(const uint8_t * mac, const uint8_t *incomingData, int len) {
  //Copy received data to Input buffer and signal new data available
  memcpy(IN_BUFF, incomingData, sizeof(IN_BUFF));
  data4dac=1;
}

void IRAM_ATTR writeDAC(){
  //If there is data for the DAC
  if(data4dac){
    if(i==0){
      //If we finished sending the previous 250 bytes, copy new ones from IN_BUFF to OUT_BUFF
      memcpy(OUT_BUFF, IN_BUFF, sizeof(OUT_BUFF));
    }
    dac_output_voltage(DAC_CHANNEL_1, OUT_BUFF[i++]);
    if(i==250){
        //If finished sending, reset counter and data4dac
        i=0;
        data4dac=0;
    }
  }
}
 
void setup() {
  // Initialize Serial Monitor
  Serial.begin(115200);
  dac_output_enable(DAC_CHANNEL_1);
  
  // Set device as a Wi-Fi Station
  esp_netif_init();
  wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
  esp_wifi_init(&cfg);
  esp_wifi_set_mode(WIFI_MODE_STA);
  esp_wifi_set_bandwidth(WIFI_IF_STA, WIFI_BW_HT40);
  esp_wifi_set_storage(WIFI_STORAGE_RAM);
  esp_wifi_set_ps(WIFI_PS_NONE);
  esp_wifi_start();
  
  // Init ESP-NOW
  if (esp_now_init() != ESP_OK) {
    Serial.println("Error initializing ESP-NOW");
    return;
  }
  esp_wifi_config_espnow_rate(WIFI_IF_STA, WIFI_PHY_RATE_54M);

  //Setting up a timer interrupt with a frequency of 20kHz
  My_timer = timerBegin(0, 8, true);
  timerAttachInterrupt(My_timer, &writeDAC, true);
  timerAlarmWrite(My_timer, 500, true);
  timerAlarmEnable(My_timer);
  
  // Once ESPNow is successfully Init, we will register for recv CB to
  // get recv packer info
  esp_now_register_recv_cb(OnDataRecv);
}
 
void loop() {
  
}
I acquired the output of DAC1 pins of the two esp32. As expected, the output from the receiver is one full sine wave behind the transmitter, but then weird things start happening: multiple skipped sine waves, varying latency, etc...
I also tried various WIFI_PHY_RATEs, slower and faster ones, but the results have not improved.

Has anyone got any suggestions on why this is happening? I am now running the timer interrupt at 20kHz, but in the final application I would like it to run at 44kHz for audio sampling.
Thanks a lot for the help!

Who is online

Users browsing this forum: No registered users and 85 guests