Ethernet on Opta - slow request read times

(note, I have cross posted this on: Ethernet on Opta - slow request read times · Issue #1067 · arduino/ArduinoCore-mbed · GitHub)

I have an Opta RS485 with code compiled with the following libraries/platform:
Ethernet 1.0.0
SocketWrapper 1.0
arduino:mbed_opta 4.3.1

When running a simple http server (following a simplified version of Web Server on the Finder Opta):

#include <Arduino.h>
#include <Ethernet.h>
#include <opta_info.h>

OptaBoardInfo *info;
OptaBoardInfo *boardInfo();

// IP address of the Opta server.
IPAddress ip(192, 168, 1, 12);
// Ethernet server on port 80.
EthernetServer server(80);

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

  info = boardInfo();
  // Check if secure informations are available since MAC Address is among them.
  if (info->magic == 0xB5)
  {
    // Assign static IP address.
    Ethernet.begin(info->mac_address, ip);
  }
  else
  {
    Serial.println("Error: Secure information not available. Cannot start server.");
    while (1)
    {
    }
  }

  // Start the server.
  server.begin();
  Serial.println("Server started");
}

void loop()
{
  // Check if any client is available.
  EthernetClient client = server.available();
  if (client)
  {
    unsigned long startTime = millis();
    Serial.println("Client connected");

    // Read the HTTP request line
    unsigned long readStart = millis();
    String request = client.readStringUntil('\r');
    unsigned long readEnd = millis();
    client.flush();

    // Check if it's a GET request to "/"
    unsigned long handleStart = millis();
    if (request.indexOf("GET /") == 0)
    {
      sendHomepage(&client);
    }
    unsigned long handleEnd = millis();

    // Close the connection
    unsigned long stopStart = millis();
    client.stop();
    unsigned long stopEnd = millis();

    unsigned long endTime = millis();
    Serial.print("Client disconnected. Total handling time: ");
    Serial.print(endTime - startTime);
    Serial.println(" ms");

    Serial.print("  Request read time: ");
    Serial.print(readEnd - readStart);
    Serial.println(" ms");

    Serial.print("  Homepage send time: ");
    Serial.print(handleEnd - handleStart);
    Serial.println(" ms");

    Serial.print("  Client stop time: ");
    Serial.print(stopEnd - stopStart);
    Serial.println(" ms");
  }
}

void sendHomepage(EthernetClient *client)
{
  String html = "<html><body>Hello, World!</body></html>";

  client->println("HTTP/1.1 200 OK");
  client->println("Content-Type: text/html");
  client->println("Connection: close");
  client->println("Content-Length: " + String(html.length()));
  client->println();
  client->println(html);

  Serial.println("Homepage sent");
}

The client.readStringUntil('\r') is consistently around 100ms.

Total handling time: 102 ms
  Request read time: 101 ms
  Homepage send time: 1 ms
  Client stop time: 0 ms

Is there an issue with the mbed Ethernet library?

We want to use the Opta for repeated http requests, but the 100 ms delay is unfortunately unacceptable. Any plug-and-play alternatives or ideas for a fix are welcome. Thank you.

Try a different way to test for \r other than readStringUntil

1 Like

Hey Faraday, thank you for the reply.

I changed the code to and I still get ~100ms:

    // Read the HTTP request line
    unsigned long readStart = millis();
    String request = "";
    char c;
    Serial.print("before connected(): ");
    Serial.println(millis() - readStart);
    while (client.connected())
    {
      Serial.print("before available(): ");
      Serial.println(millis() - readStart);
      if (client.available())
      {
        Serial.print("Reading request...: ");
        Serial.println(millis() - readStart);

        c = client.read();
        if (c == '\r')
          break;
        request += c;
        Serial.println(c);
      }
    }
    unsigned long readEnd = millis();
    client.flush();

Serial print output:

Client connected
before connected(): 0
before available(): 1
before available(): 1
before available(): 1
before available(): 1
before available(): 1
before available(): 1
before available(): 1
before available(): 1
before available(): 2
before available(): 2
before available(): 2
before available(): 2
before available(): 2
before available(): 2
before available(): 2
before available(): 2
before available(): 3
before available(): 3
before available(): 3
before available(): 3
before available(): 3
before available(): 3
before available(): 3
before available(): 3
before available(): 4
before available(): 4
before available(): 4
before available(): 4
before available(): 4
before available(): 4
before available(): 4
before available(): 4
before available(): 4
before available(): 5
before available(): 5
before available(): 5
before available(): 5
before available(): 5
before available(): 5
before available(): 5
before available(): 5
before available(): 6
before available(): 6
before available(): 6
before available(): 6
before available(): 6
before available(): 6
before available(): 6
before available(): 6
before available(): 7
before available(): 7
before available(): 7
before available(): 7
before available(): 7
before available(): 7
before available(): 7
before available(): 7
before available(): 8
before available(): 8
before available(): 8
before available(): 8
before available(): 8
before available(): 8
before available(): 8
before available(): 8
before available(): 8
before available(): 9
before available(): 9
before available(): 9
before available(): 9
before available(): 9
before available(): 9
before available(): 9
before available(): 9
before available(): 10
before available(): 10
before available(): 10
before available(): 10
before available(): 10
before available(): 10
before available(): 10
before available(): 10
before available(): 11
before available(): 11
before available(): 11
before available(): 11
before available(): 11
before available(): 11
before available(): 11
before available(): 11
before available(): 11
before available(): 12
before available(): 12
before available(): 12
before available(): 12
before available(): 12
before available(): 12
before available(): 12
before available(): 12
before available(): 13
before available(): 13
before available(): 13
before available(): 13
before available(): 13
before available(): 13
before available(): 13
before available(): 13
before available(): 14
before available(): 14
before available(): 14
before available(): 14
before available(): 14
before available(): 14
before available(): 14
before available(): 14
before available(): 15
before available(): 15
before available(): 15
before available(): 15
before available(): 15
before available(): 15
before available(): 15
before available(): 15
before available(): 16
before available(): 16
before available(): 16
before available(): 16
before available(): 16
before available(): 16
before available(): 16
before available(): 16
before available(): 17
before available(): 17
before available(): 17
before available(): 17
before available(): 17
before available(): 17
before available(): 17
before available(): 17
before available(): 18
before available(): 18
before available(): 18
before available(): 18
before available(): 18
before available(): 18
before available(): 18
before available(): 18
before available(): 19
before available(): 19
before available(): 19
before available(): 19
before available(): 19
before available(): 19
before available(): 19
before available(): 19
before available(): 19
before available(): 20
before available(): 20
before available(): 20
before available(): 20
before available(): 20
before available(): 20
before available(): 20
before available(): 20
before available(): 21
before available(): 21
before available(): 21
before available(): 21
before available(): 21
before available(): 21
before available(): 21
before available(): 21
before available(): 22
before available(): 22
before available(): 22
before available(): 22
before available(): 22
before available(): 22
before available(): 22
before available(): 22
before available(): 23
before available(): 23
before available(): 23
before available(): 23
before available(): 23
before available(): 23
before available(): 23
before available(): 23
before available(): 24
before available(): 24
before available(): 24
before available(): 24
before available(): 24
before available(): 24
before available(): 24
before available(): 24
before available(): 25
before available(): 25
before available(): 25
before available(): 25
before available(): 25
before available(): 25
before available(): 25
before available(): 25
before available(): 25
before available(): 26
before available(): 26
before available(): 26
before available(): 26
before available(): 26
before available(): 26
before available(): 26
before available(): 26
before available(): 27
before available(): 27
before available(): 27
before available(): 27
before available(): 27
before available(): 27
before available(): 27
before available(): 27
before available(): 28
before available(): 28
before available(): 28
before available(): 28
before available(): 28
before available(): 28
before available(): 28
before available(): 28
before available(): 29
before available(): 29
before available(): 29
before available(): 29
before available(): 29
before available(): 29
before available(): 29
before available(): 29
before available(): 30
before available(): 30
before available(): 30
before available(): 30
before available(): 30
before available(): 30
before available(): 30
before available(): 30
before available(): 31
before available(): 31
before available(): 31
before available(): 31
before available(): 31
before available(): 31
before available(): 31
before available(): 31
before available(): 32
before available(): 32
before available(): 32
before available(): 32
before available(): 32
before available(): 32
before available(): 32
before available(): 32
before available(): 33
before available(): 33
before available(): 33
before available(): 33
before available(): 33
before available(): 33
before available(): 33
before available(): 33
before available(): 33
before available(): 34
before available(): 34
before available(): 34
before available(): 34
before available(): 34
before available(): 34
before available(): 34
before available(): 34
before available(): 35
before available(): 35
before available(): 35
before available(): 35
before available(): 35
before available(): 35
before available(): 35
before available(): 35
before available(): 36
before available(): 36
before available(): 36
before available(): 36
before available(): 36
before available(): 36
before available(): 36
before available(): 36
before available(): 37
before available(): 37
before available(): 37
before available(): 37
before available(): 37
before available(): 37
before available(): 37
before available(): 37
before available(): 38
before available(): 38
before available(): 38
before available(): 38
before available(): 38
before available(): 38
before available(): 38
before available(): 38
before available(): 38
before available(): 39
before available(): 39
before available(): 39
before available(): 39
before available(): 39
before available(): 39
before available(): 39
before available(): 39
before available(): 40
before available(): 40
before available(): 40
before available(): 40
before available(): 40
before available(): 40
before available(): 40
before available(): 40
before available(): 41
before available(): 41
before available(): 41
before available(): 41
before available(): 41
before available(): 41
before available(): 41
before available(): 41
before available(): 42
before available(): 42
before available(): 42
before available(): 42
before available(): 42
before available(): 42
before available(): 42
before available(): 42
before available(): 42
before available(): 43
before available(): 43
before available(): 43
before available(): 43
before available(): 43
before available(): 43
before available(): 43
before available(): 43
before available(): 44
before available(): 44
before available(): 44
before available(): 44
before available(): 44
before available(): 44
before available(): 44
before available(): 44
before available(): 45
before available(): 45
before available(): 45
before available(): 45
before available(): 45
before available(): 45
before available(): 45
before available(): 46
before available(): 46
before available(): 46
before available(): 46
before available(): 46
before available(): 46
before available(): 46
before available(): 46
before available(): 46
before available(): 47
before available(): 47
before available(): 47
before available(): 47
before available(): 47
before available(): 47
before available(): 47
before available(): 47
before available(): 48
before available(): 48
before available(): 48
before available(): 48
before available(): 48
before available(): 48
before available(): 48
before available(): 48
before available(): 49
before available(): 49
before available(): 49
before available(): 49
before available(): 49
before available(): 49
before available(): 49
before available(): 49
before available(): 50
before available(): 50
before available(): 50
before available(): 50
before available(): 50
before available(): 50
before available(): 50
before available(): 50
before available(): 51
before available(): 51
before available(): 51
before available(): 51
before available(): 51
before available(): 51
before available(): 51
before available(): 51
before available(): 52
before available(): 52
before available(): 52
before available(): 52
before available(): 52
before available(): 52
before available(): 52
before available(): 52
before available(): 53
before available(): 53
before available(): 53
before available(): 53
before available(): 53
before available(): 53
before available(): 53
before available(): 53
before available(): 54
before available(): 54
before available(): 54
before available(): 54
before available(): 54
before available(): 54
before available(): 54
before available(): 54
before available(): 54
before available(): 55
before available(): 55
before available(): 55
before available(): 55
before available(): 55
before available(): 55
before available(): 55
before available(): 55
before available(): 56
before available(): 56
before available(): 56
before available(): 56
before available(): 56
before available(): 56
before available(): 56
before available(): 56
before available(): 57
before available(): 57
before available(): 57
before available(): 57
before available(): 57
before available(): 57
before available(): 57
before available(): 57
before available(): 58
before available(): 58
before available(): 58
before available(): 58
before available(): 58
before available(): 58
before available(): 58
before available(): 58
before available(): 58
before available(): 59
before available(): 59
before available(): 59
before available(): 59
before available(): 59
before available(): 59
before available(): 59
before available(): 59
before available(): 60
before available(): 60
before available(): 60
before available(): 60
before available(): 60
before available(): 60
before available(): 60
before available(): 60
before available(): 61
before available(): 61
before available(): 61
before available(): 61
before available(): 61
before available(): 61
before available(): 61
before available(): 61
before available(): 62
before available(): 62
before available(): 62
before available(): 62
before available(): 62
before available(): 62
before available(): 62
before available(): 62
before available(): 63
before available(): 63
before available(): 63
before available(): 63
before available(): 63
before available(): 63
before available(): 63
before available(): 63
before available(): 63
before available(): 64
before available(): 64
before available(): 64
before available(): 64
before available(): 64
before available(): 64
before available(): 64
before available(): 64
before available(): 65
before available(): 65
before available(): 65
before available(): 65
before available(): 65
before available(): 65
before available(): 65
before available(): 65
before available(): 66
before available(): 66
before available(): 66
before available(): 66
before available(): 66
before available(): 66
before available(): 66
before available(): 66
before available(): 67
before available(): 67
before available(): 67
before available(): 67
before available(): 67
before available(): 67
before available(): 67
before available(): 67
before available(): 68
before available(): 68
before available(): 68
before available(): 68
before available(): 68
before available(): 68
before available(): 68
before available(): 68
before available(): 69
before available(): 69
before available(): 69
before available(): 69
before available(): 69
before available(): 69
before available(): 69
before available(): 69
before available(): 70
before available(): 70
before available(): 70
before available(): 70
before available(): 70
before available(): 70
before available(): 70
before available(): 70
before available(): 71
before available(): 71
before available(): 71
before available(): 71
before available(): 71
before available(): 71
before available(): 71
before available(): 71
before available(): 72
before available(): 72
before available(): 72
before available(): 72
before available(): 72
before available(): 72
before available(): 72
before available(): 72
before available(): 73
before available(): 73
before available(): 73
before available(): 73
before available(): 73
before available(): 73
before available(): 73
before available(): 73
before available(): 74
before available(): 74
before available(): 74
before available(): 74
before available(): 74
before available(): 74
before available(): 74
before available(): 74
before available(): 75
before available(): 75
before available(): 75
before available(): 75
before available(): 75
before available(): 75
before available(): 75
before available(): 75
before available(): 76
before available(): 76
before available(): 76
before available(): 76
before available(): 76
before available(): 76
before available(): 76
before available(): 76
before available(): 77
before available(): 77
before available(): 77
before available(): 77
before available(): 77
before available(): 77
before available(): 77
before available(): 77
before available(): 78
before available(): 78
before available(): 78
before available(): 78
before available(): 78
before available(): 78
before available(): 78
before available(): 78
before available(): 79
before available(): 79
before available(): 79
before available(): 79
before available(): 79
before available(): 79
before available(): 79
before available(): 79
before available(): 80
before available(): 80
before available(): 80
before available(): 80
before available(): 80
before available(): 80
before available(): 80
before available(): 80
before available(): 80
before available(): 81
before available(): 81
before available(): 81
before available(): 81
before available(): 81
before available(): 81
before available(): 81
before available(): 81
before available(): 82
before available(): 82
before available(): 82
before available(): 82
before available(): 82
before available(): 82
before available(): 82
before available(): 82
before available(): 83
before available(): 83
before available(): 83
before available(): 83
before available(): 83
before available(): 83
before available(): 83
before available(): 83
before available(): 84
before available(): 84
before available(): 84
before available(): 84
before available(): 84
before available(): 84
before available(): 84
before available(): 84
before available(): 85
before available(): 85
before available(): 85
before available(): 85
before available(): 85
before available(): 85
before available(): 85
before available(): 85
before available(): 86
before available(): 86
before available(): 86
before available(): 86
before available(): 86
before available(): 86
before available(): 86
before available(): 87
before available(): 87
before available(): 87
before available(): 87
before available(): 87
before available(): 87
before available(): 87
before available(): 87
before available(): 88
before available(): 88
before available(): 88
before available(): 88
before available(): 88
before available(): 88
before available(): 88
before available(): 88
before available(): 89
before available(): 89
before available(): 89
before available(): 89
before available(): 89
before available(): 89
before available(): 89
before available(): 89
before available(): 89
before available(): 90
before available(): 90
before available(): 90
before available(): 90
before available(): 90
before available(): 90
before available(): 90
before available(): 90
before available(): 91
before available(): 91
before available(): 91
before available(): 91
before available(): 91
before available(): 91
before available(): 91
before available(): 91
before available(): 92
before available(): 92
before available(): 92
before available(): 92
before available(): 92
before available(): 92
before available(): 92
before available(): 93
before available(): 93
before available(): 93
before available(): 93
before available(): 93
before available(): 93
before available(): 93
before available(): 93
before available(): 94
before available(): 94
before available(): 94
before available(): 94
before available(): 94
before available(): 94
before available(): 94
before available(): 94
before available(): 94
before available(): 95
before available(): 95
before available(): 95
before available(): 95
before available(): 95
before available(): 95
before available(): 95
before available(): 95
before available(): 96
before available(): 96
before available(): 96
before available(): 96
before available(): 96
before available(): 96
before available(): 96
before available(): 96
before available(): 97
before available(): 97
before available(): 97
before available(): 97
before available(): 97
before available(): 97
before available(): 97
before available(): 97
before available(): 98
before available(): 98
before available(): 98
before available(): 98
before available(): 98
before available(): 98
before available(): 98
before available(): 98
before available(): 99
before available(): 99
before available(): 99
before available(): 99
before available(): 99
before available(): 99
before available(): 99
before available(): 99
before available(): 100
before available(): 100
before available(): 100
before available(): 100
Reading request...: 100
G
before available(): 100
Reading request...: 100
E
before available(): 101
Reading request...: 101
T
before available(): 101
Reading request...: 101
 
before available(): 101
Reading request...: 102
/
before available(): 102
Reading request...: 102
 
before available(): 102
Reading request...: 102
H
before available(): 103
Reading request...: 103
T
before available(): 103
Reading request...: 103
T
before available(): 103
Reading request...: 103
P
before available(): 104
Reading request...: 104
/
before available(): 104
Reading request...: 104

if (client.available()) seems to the lagger here, hmmm.

I have found the culprit: ArduinoCore-mbed/libraries/SocketWrapper/src/MbedClient.cpp at 1302d80a4c1e770460132c76a280388bf44fe153 · arduino/ArduinoCore-mbed · GitHub

void arduino::MbedClient::readSocket() {
  uint8_t data[SOCKET_BUFFER_SIZE];

  while (sock != nullptr) {
    event->wait_any(0xFF, 100);
    int ret = NSAPI_ERROR_WOULD_BLOCK;
    do {
      mutex->lock();
      if (sock != nullptr && rxBuffer.availableForStore() == 0) {
        mutex->unlock();
        yield();
        continue;
      } else if (sock == nullptr) {
        goto cleanup;
      }
      ret = sock->recv(data, rxBuffer.availableForStore());
      if (ret < 0 && ret != NSAPI_ERROR_WOULD_BLOCK) {
        goto cleanup;
      }
      if (ret == NSAPI_ERROR_WOULD_BLOCK || ret == 0) {
        yield();
        mutex->unlock();
        continue;
      }
      for (int i = 0; i < ret; i++) {
        rxBuffer.store_char(data[i]);
      }
      mutex->unlock();
      _status = true;
    } while (ret == NSAPI_ERROR_WOULD_BLOCK || ret > 0);
  }
cleanup:
  _status = false;
  return;
}

Adjusting event->wait_any(0xFF, 100) to shorter timeouts yields much faster queries. Now, to notify the developers to figure out why it hangs...