1

I'm working on a project that consists in sending data frames at a frequency of 200Hz, from a Teensy 4.1 to another, through two ESP-01S (See diagram and code below).

Hardware :

The system is composed of two identical subsystems, themselves composed of a Teensy 4.1, transmitting frames via the RX and TX pins to an ESP-01, which transmits these same frames to a second ESP-01, which finally transmits them via serial transmission to a receiving Teensy. The circuit is powered as follows: each Teensy is powered via USB, connected to a desktop computer, and each ESP is powered by pin 3.3 of its respective Teensy. The baudrate for serial transmission is 230400. I've seen that the max baudrate for ESP is 115200, so I tried at 115200 and 230400 and I don't see any difference.

ESP-01 specifications :

  • CPU frequency : 160MHz
  • Crystal frequency : 26MHz

Circuit diagram (both parts are identical so I am posting only one):

enter image description here

Software :

The frames are between 15 and 30 bytes long and are made of an array of uint8_t more or less large. For the Wifi transmission, I use the UDP protocol, which is less reliable than TCP, but faster.

Here is the code for the sending ESP :

#include <ESP8266WiFi.h>
#include <WiFiUdp.h>
#include <MicroMetro.h>

// Set WiFi credentials
#define WIFI_SSID "TheOtherESP"
#define WIFI_PASS "flashmeifyoucan"

// UDP
WiFiUDP UDP;
IPAddress remote_IP(192, 168, 4, 1);
#define UDP_PORT 4210

// -------------------- Prototypes --------------------
//reception function via serial
void receiveArray(uint8_t* arr, uint8_t* sizeFrame);

void setup() {
  Serial.begin(230400);

  // -------------------- Wifi Initialisation --------------------
  //Begin WiFi
  WiFi.begin(WIFI_SSID, WIFI_PASS);
  WiFi.mode(WIFI_STA);

  // Connecting to WiFi...
  Serial.print("Connecting to ");
  Serial.print(WIFI_SSID);

  // Loop continuously while WiFi is not connected
  while (WiFi.status() != WL_CONNECTED) {
    delay(100);
    Serial.print(".");
  }

  // Connected to WiFi
  Serial.println();
  Serial.print("Connected! IP address: ");
  Serial.println(WiFi.localIP());

  // Begin UDP port
  UDP.begin(UDP_PORT);
  Serial.print("Opening UDP port ");
  Serial.println(UDP_PORT);
}

void loop() {
  // -------------------- serial reception --------------------
  uint8_t arr[30];      //reception buffer max 30o
  uint8_t sizeFrame;    
  receiveArray(arr, &sizeFrame);
  
  // -------------------- sending via WiFi --------------------

  if(arr[0]==30){
    UDP.beginPacket(remote_IP, UDP_PORT); // begin of sending
    UDP.write(arr, sizeFrame);            // sending
    UDP.endPacket();                      // end of sending
  }
}

// -------------------- FUNCTIONS --------------------


void receiveArray(uint8_t* arr, uint8_t* sizeFrame){
  while(Serial.available() < (int)sizeof(*sizeFrame)) {}      //wait for the reception of array size
  Serial.readBytes((uint8_t*)sizeFrame, sizeof(*sizeFrame));  //read array size
  while(Serial.available() < *sizeFrame) {}              //wait for the reception of array data
  Serial.readBytes(arr, *sizeFrame);                     //read array data
}

Here is the code for the receiving ESP :

#include <ESP8266WiFi.h>
#include <WiFiUdp.h>
#include <MicroMetro.h>

// Set AP credentials
#define AP_SSID "TheOtherESP"
#define AP_PASS "flashmeifyoucan"

// -------------------- Prototypes --------------------
//reception function via WiFi
void receiveArray_Wifi(uint8_t* arr, uint8_t* size);

// UDP
WiFiUDP UDP;
IPAddress local_IP(192, 168, 4, 1);
IPAddress gateway(192, 168, 4, 1);
IPAddress subnet(255, 255, 255, 0);
#define UDP_PORT 4210

void setup() {
  // Setup serial port
  Serial.begin(230400);

  // Begin Access Point
  Serial.println("Starting access point...");
  WiFi.softAPConfig(local_IP, gateway, subnet);
  WiFi.softAP(AP_SSID, AP_PASS);
  Serial.println(WiFi.localIP());

  // Begin listening to UDP port
  UDP.begin(UDP_PORT);
  Serial.print("Listening on UDP port "); Serial.println(UDP_PORT);
  delay(1000);
}

void loop() {
  // Receive packet
  uint8_t buffer[30]; // buffer
  int packetSize = UDP.parsePacket();

  if (packetSize) {
    int size_frame = UDP.read(buffer, 30); // read buffer
    if (size_frame > 0) {
      sendArray(buffer, size_frame);
    }
  }
}

// -------------------- FUNCTIONS --------------------

// send via UART
void sendArray(uint8_t* arr, uint8_t size) {
  Serial.write((uint8_t*)&size, sizeof(size));  // send array size
  Serial.write(arr, size);                      // send array data
}

The problem is that I can't transmit at 200Hz. Indeed, the average transmission time after which I receive 200 frames at the receiving Teensy is about 1.5s, instead of 1s at most. After checking the execution time of each of the devices, the problem is in the Wifi and not in the serial transmission.

What is strange is that by oversampling and sending frames at 400Hz, we keep about the same proportion of transfer time and we get an average of 750ms to transmit 200 frames.

Is this a code problem? Or hardware?

I thought of a power supply problem, because the Wifi transmission can generate consumption peaks. I tried to put a 4.7µF electrolytic capacitor at the Vcc and GND terminals of each ESP. I also connected a 100µF electrolytic capacitor in parallel to the first capacitor. The performances are better (about 650ms for 200 frames with a 400Hz sending), but still not good enough...

Thanks to all

Juno
  • 69
  • 2
  • If a 4.7 uF cap makes SOME difference then you have a power supply issue which MUSt be fixed. What does an oscilloscope show on the power supply AT the devices concerned? || How well does it work operating it at a usefully lower baud rate? – Russell McMahon Jul 23 '23 at 02:10

0 Answers0