Page 1 of 1

ESP32: low jitter implementation

Posted: Thu Nov 28, 2024 5:18 pm
by salman2135
Hi everyone,
I am working on a low jitter solution using two ESP32 S3 V1 board with Arduino IDE. My delay and jitter is currently 8 ms and 4 ms respectively. I am wondering how to improve the performace of in terms of jitter. Any clue would be greatly appreciated!
Below is my code:
Sender Code:

Code: Select all

#include <WiFi.h>
#include <esp_now.h>
#include <esp_wifi.h>
#include <esp_pm.h>
#include <esp_wifi_types.h>
#define REF_PIN 35
uint8_t receiverMacList[][6] = {
  { 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF }, // dummy
  { 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF  } // dummy
};
uint8_t dataToSend = 0;             // Variable to hold the integer to send
int receivedData = 0;           // Variable to store the data received from the receiver
bool dataReceivedFlag = false;  // Flag to check if data is received
// Callback function for send status
void onDataSent(const uint8_t *mac_addr, esp_now_send_status_t status) {
  Serial.println(status == ESP_NOW_SEND_SUCCESS ? "Success" : "Fail");
}
// Callback function for receiving data
void onDataReceive(const esp_now_recv_info_t *recv_info, const uint8_t *incomingData, int len) {
}
void setup() {
  Serial.begin(115200);
  // Initialize Wi-Fi in Station Mode
  WiFi.mode(WIFI_STA);
  WiFi.disconnect();
  // Set Long Range Mode
  esp_wifi_set_protocol(WIFI_IF_STA, WIFI_PROTOCOL_LR);
  // Fix Wi-Fi Channel for Low Jitter
  esp_wifi_set_channel(1, WIFI_SECOND_CHAN_NONE);
  // Set Max Transmission Power
  esp_wifi_set_max_tx_power(78);  // Max TX power (19.5 dBm)
  esp_wifi_set_ps(WIFI_PS_NONE);
  // Initialize ESP-NOW
  if (esp_now_init() != ESP_OK) {
    Serial.println("ESP-NOW initialization failed");
    return;
  }
  // Register the send and receive callback functions
  esp_now_register_send_cb(onDataSent);
  esp_now_register_recv_cb(onDataReceive);
  // Add each MAC address as a peer
  for (int i = 0; i < sizeof(receiverMacList) / sizeof(receiverMacList[0]); i++) {
    esp_now_peer_info_t peerInfo = {};
    memcpy(peerInfo.peer_addr, receiverMacList[i], 6);
    peerInfo.channel = 0;  // Use the default channel
    peerInfo.encrypt = false;
    if (esp_now_add_peer(&peerInfo) != ESP_OK) {
      Serial.printf("Failed to add peer: %02X:%02X:%02X:%02X:%02X:%02X\n",
                    receiverMacList[i][0], receiverMacList[i][1], receiverMacList[i][2],
                    receiverMacList[i][3], receiverMacList[i][4], receiverMacList[i][5]);
    }
  }
  Serial.println("ESP-NOW Sender Ready. Enter a number to send:");
}
void loop() {
  // Check if data is available on the serial port
  if (Serial.available() == 1) {
    // Read integer from the serial port
    dataToSend = Serial.read();
    // NULL means send to all peers
    for (int i = 0; i < sizeof(receiverMacList) / sizeof(receiverMacList[0]); i++) {
      esp_err_t result = esp_now_send(receiverMacList[i], (uint8_t *)&dataToSend, sizeof(dataToSend));
      if (result == ESP_OK) {
        Serial.printf("Data sent to %02X:%02X:%02X:%02X:%02X:%02X\n",
                      receiverMacList[i][0], receiverMacList[i][1], receiverMacList[i][2],
                      receiverMacList[i][3], receiverMacList[i][4], receiverMacList[i][5]);
      } else {
        Serial.println("Unknown error");
      }
    }
  }
}
Receiver code

Code: Select all

#include <WiFi.h>
#include <esp_now.h>
#include <esp_wifi.h>
// Queue for received messages
QueueHandle_t espNowQueue;
uint8_t eight_bit_value = 0;                                       // Variable to hold received integer
uint8_t senderMAC[] = { 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB };  // Replace with the sender's MAC address
#define TX_PIN 17                                              // Define TX pin for UART1
#define RX_PIN 16                                              // Define RX pin for UART1
#define BAUD_RATE 115200                                       // Set baud rate
// Callback function for receiving data
void onDataReceive(const esp_now_recv_info_t *recv_info, const uint8_t *incomingData, int len) {
  eight_bit_value = incomingData[0];
  BaseType_t xHigherPriorityTaskWoken = pdFALSE;
  xQueueSendFromISR(espNowQueue, &eight_bit_value, &xHigherPriorityTaskWoken);
  portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
}
void espNowTask(void *param) {
  int message;
  while (true) {
    if (xQueueReceive(espNowQueue, &message, portMAX_DELAY)) {
      // Log the received message
      uint8_t cmd[] = {
        (uint8_t)0xAB
        (uint8_t)0xBB
      };
      Serial1.write(cmd, sizeof(cmd));
    }
  }
}
void setup() {
  Serial.begin(115200);
  Serial1.begin(BAUD_RATE, SERIAL_8N1, RX_PIN, TX_PIN);
  // Set the ESP32 to station mode
  WiFi.mode(WIFI_STA);
  WiFi.disconnect();
  // Set Long Range Mode
  esp_wifi_set_protocol(WIFI_IF_STA, WIFI_PROTOCOL_LR);
  esp_wifi_set_ps(WIFI_PS_NONE);
  // Fix Wi-Fi Channel
  esp_wifi_set_channel(1, WIFI_SECOND_CHAN_NONE);
  // Initialize ESP-NOW
  if (esp_now_init() != ESP_OK) {
    Serial.println("ESP-NOW initialization failed");
    return;
  }
  // Register the receive callback function
  esp_now_register_recv_cb(onDataReceive);
  // Create Queue for Received Messages
  espNowQueue = xQueueCreate(10, sizeof(int));
  if (espNowQueue == NULL) {
    Serial.println("Failed to create queue");
    return;
  }
  // Create Processing Task
  xTaskCreate(espNowTask, "ESPNow Task", 4096, NULL, 2, NULL);
}
void loop() {
}
Any clue/help would be really appreciated!!

Re: ESP32: low jitter implementation

Posted: Fri Nov 29, 2024 11:13 pm
by MicroController
salman2135 wrote:
Thu Nov 28, 2024 5:18 pm
Receiver code

Code: Select all

void loop() {
}
Any clue/help would be really appreciated!!
Give the CPU some breathing room:

Code: Select all

void loop() {
  vTaskDelete(NULL);
}
or at least

Code: Select all

void loop() {
  vTaskDelay(10000/portTICK_PERIOD_MS);
}

Re: ESP32: low jitter implementation

Posted: Tue Dec 10, 2024 3:48 pm
by salman2135
MicroController wrote:
Fri Nov 29, 2024 11:13 pm
salman2135 wrote:
Thu Nov 28, 2024 5:18 pm
Receiver code

Code: Select all

void loop() {
}
Any clue/help would be really appreciated!!
Give the CPU some breathing room:

Code: Select all

void loop() {
  vTaskDelete(NULL);
}
or at least

Code: Select all

void loop() {
  vTaskDelay(10000/portTICK_PERIOD_MS);
}

Thanks a lot! I realized that the esp32 boards were not running with full speed in Arduino by reading this issue:
https://github.com/espressif/esp-idf/issues/3238

I tried with ESP8266 and could get the desired result.