Problems with small packet transfers with WiFi TCP connection

Nebulous
Posts: 2
Joined: Tue Dec 31, 2024 1:13 pm

Problems with small packet transfers with WiFi TCP connection

Postby Nebulous » Tue Dec 31, 2024 1:39 pm

Hi, I'm having problems with very slow transaction turnaround when using an ESP32 Dev module to communication with some hardware using modbus over TCP. I use the Arduino framework in platformio/VSCode

To simplify everything for the purpose of this post, I created two simple projects:

Both use an ESP32 Dev module, with one as the client, and one as the server to simulate the real device.

The client opens a connection, then writes a small packet of data and waits for the response. It repeats that 10 times and then closes the connection.

The server waits for a connection and then just echos back any packets that it receives.

The problem is that the time for each of the 10 transactions takes too long. In my real application I have to poll 10 registers from the device every 5 seconds, but it takes longer than that to complete each block of registers.

Below is a sample of the serial monitor output from the client. The number in brackets at the end of each line is the number of milliseconds it took between issuing the request and receiving the response:

Code: Select all

Connection Open.
Recv: 00 01 00 00 00 06 01 04 13 87 00 00  ( 612 )
Recv: 00 01 00 00 00 06 01 04 13 87 00 01  ( 3083 )
Recv: 00 01 00 00 00 06 01 04 13 87 00 02  ( 603 )
Recv: 00 01 00 00 00 06 01 04 13 87 00 03  ( 614 )
Recv: 00 01 00 00 00 06 01 04 13 87 00 04  ( 717 )
Recv: 00 01 00 00 00 06 01 04 13 87 00 05  ( 518 )
Recv: 00 01 00 00 00 06 01 04 13 87 00 06  ( 607 )
Recv: 00 01 00 00 00 06 01 04 13 87 00 07  ( 614 )
Recv: 00 01 00 00 00 06 01 04 13 87 00 08  ( 615 )
Recv: 00 01 00 00 00 06 01 04 13 87 00 09  ( 614 )
Connection closed.
Connection Open.
Recv: 00 01 00 00 00 06 01 04 13 87 00 00  ( 613 )
Recv: 00 01 00 00 00 06 01 04 13 87 00 01  ( 614 )
Recv: 00 01 00 00 00 06 01 04 13 87 00 02  ( 60 )
Recv: 00 01 00 00 00 06 01 04 13 87 00 03  ( 10 )
Recv: 00 01 00 00 00 06 01 04 13 87 00 04  ( 12 )
Recv: 00 01 00 00 00 06 01 04 13 87 00 05  ( 10 )
Recv: 00 01 00 00 00 06 01 04 13 87 00 06  ( 14 )
Recv: 00 01 00 00 00 06 01 04 13 87 00 07  ( 18 )
Recv: 00 01 00 00 00 06 01 04 13 87 00 08  ( 11 )
Recv: 00 01 00 00 00 06 01 04 13 87 00 09  ( 15 )
Connection closed.
The strange thing is, the delays seem to be quantum like. i.e. it's either 3000, 600 or ~14. (maybe that is a clue to the problem?).

The last few (10-20 ms) are fine, but it is very rare that I get that.

I have tried using setNoDelay() and flush() hoping that would fix it but seems to make no difference.

Am I doing something wrong? Or is there a different approach I should take?
I've run out of ideas and hope someone can help me or suggest a solution.

Below is my the test code:

Code: Select all

// Server Test

#include <Arduino.h>
#include <WiFi.h>

const char *ssid     = "mySSID";
const char *password = "MyPassword";

WiFiServer server(502);

#define LED_RED  5
#define LED_GRN  4

#define G_BUFFER_SIZE 1024
uint8_t gRxBuff[ G_BUFFER_SIZE ];
uint16_t gRxBuffSize;

//------------------------------------------------------------------------------
void setup() 
{
  Serial.begin(115200);
  pinMode( LED_RED, OUTPUT);  // set the LED pin mode
  pinMode( LED_GRN, OUTPUT);  // set the LED pin mode

  digitalWrite( LED_RED, HIGH ); // off
  digitalWrite( LED_GRN, HIGH ); // off

  delay(10);

  // We start by connecting to a WiFi network

  Serial.println();
  Serial.print("Looking for Wifi..");

  WiFi.begin( ssid, password );
  while (WiFi.status() != WL_CONNECTED) 
  {
    delay(500);
    Serial.print(".");
  }
  Serial.println("");
  digitalWrite( LED_GRN, false ); 

  Serial.println("WiFi connected.");
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());

  server.begin();
}

//------------------------------------------------------------------------------
void loop() 
{
  WiFiClient client = server.accept();  // listen for incoming clients

  if (client)                       // if you get a client,
  {  
    client.setNoDelay(true);
    digitalWrite( LED_RED, LOW ); // ON
    Serial.println("New Client.");  // print a message out the serial port
    gRxBuffSize = 0;
    while (client.connected())      // loop while the client's connected
    {
      while ( client.available() && gRxBuffSize < ( G_BUFFER_SIZE -1 ) )
      {
        gRxBuff[ gRxBuffSize++ ] = client.read();
      }
      if ( gRxBuffSize != 0 )
      {
        client.write( gRxBuff, gRxBuffSize );
        client.flush();
      }

      gRxBuffSize = 0;

    }
    // close the connection:
    client.stop();
    Serial.println("Client Disconnected.");
    digitalWrite( LED_RED, HIGH ); // OFF
  }
}

Code: Select all

// Client Test

#include <Arduino.h>
#include <WiFi.h>

const char *ssid = "MySSID";
const char *password = "MyPassword";

const char *Host = "192.168.2.21";  // IP of server
const int Port = 502;

uint32_t TimeStamp;
char TxBuff[] = { 0x00, 0x01, 0x00, 0x00, 0x00, 0x06, 0x01, 0x04, 0x13, 0x87, 0x00, 0x01 };
#define TX_SIZE (sizeof(TxBuff))

//------------------------------------------------------------------------------
void setup() 
{
  Serial.begin(115200);
  while (!Serial) 
  {
    delay(100);
  }
  delay(3000); //Give time for serial monitor to start up again after upload
  
  Serial.println("Starting...");

  WiFi.begin(ssid, password);

  while (WiFi.status() != WL_CONNECTED) 
  {
    delay(500);
    Serial.print(".");
  }

  Serial.println("WiFi connected");
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());
}

//------------------------------------------------------------------------------
void GetResponse(WiFiClient *client) 
{
  unsigned long timeout = millis();
  while (client->available() == 0) 
  {
    if (millis() - timeout > 5000) 
    {
      Serial.println(">>> Client Timeout !");
      client->stop();
      return;
    }
  }

  char ch;
  Serial.print("Recv: ");
  while (client->available()) 
  {
    ch = client->read();
    Serial.printf( "%02X ", ch);
  }
  Serial.printf( " ( %d )\r\n", millis() - TimeStamp );
}

//------------------------------------------------------------------------------
void loop() 
{
  if ( !digitalRead(0) ) // button pressed?
  {
    WiFiClient client;

    if ( client.connect(Host, Port) ) 
    {
      Serial.println("Connection Open.");
      client.setNoDelay(true);
      for( uint8_t i = 0; i < 10; i++ )
      {
        TxBuff[TX_SIZE-1] = i;
        TimeStamp = millis();
        client.write( TxBuff, TX_SIZE );
        client.flush();
        GetResponse(&client);
      }  
      client.stop();
      Serial.println("Connection closed.");
    }
    else
    {
      Serial.println("Connection fail.");
      return;
    }

    delay(500); // for button debounce
  }
}

Nebulous
Posts: 2
Joined: Tue Dec 31, 2024 1:13 pm

Re: Problems with small packet transfers with WiFi TCP connection

Postby Nebulous » Thu Jan 09, 2025 11:18 am

Nobody knows? :sad:
I have a couple of ESP32-S3 modules on order. Maybe I will have more luck with those.

Who is online

Users browsing this forum: No registered users and 51 guests