TeensyThreads / Webserver Responsetime

AcidZero

New member
Hello,

I'm using a Teensy 4.1 with the nativ ethernet and trying to run a webserver with TeensyThreads.
There is the problem that the response time is very different.
I get a response between 0.03 seconds and 5 seconds.
Everything is connected with network cable, no wifi.

sketch:

Code:
/*
  Web Server

 A simple web server that shows the value of the analog input pins.
 using an Arduino Wiznet Ethernet shield.

 Circuit:
 * Ethernet shield attached to pins 10, 11, 12, 13
 * Analog inputs attached to pins A0 through A5 (optional)

 created 18 Dec 2009
 by David A. Mellis
 modified 9 Apr 2012
 by Tom Igoe
 modified 02 Sept 2015
 by Arturo Guadalupi
 
 */

#include <SPI.h>
#include <NativeEthernet.h>
#include <TeensyThreads.h>


// Enter a MAC address and IP address for your controller below.
// The IP address will be dependent on your local network:
byte mac[] = {
  0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED
};
IPAddress ip(192, 168, 2, 161);

// Initialize the Ethernet server library
// with the IP address and port you want to use
// (port 80 is default for HTTP):
EthernetServer server(80);

void setup() {
  // You can use Ethernet.init(pin) to configure the CS pin
  //Ethernet.init(10);  // Most Arduino shields
  //Ethernet.init(5);   // MKR ETH shield
  //Ethernet.init(0);   // Teensy 2.0
  //Ethernet.init(20);  // Teensy++ 2.0
  //Ethernet.init(15);  // ESP8266 with Adafruit Featherwing Ethernet
  //Ethernet.init(33);  // ESP32 with Adafruit Featherwing Ethernet

  // Open serial communications and wait for port to open:
  Serial.begin(9600);
  while (!Serial) {
    ; // wait for serial port to connect. Needed for native USB port only
  }
  Serial.println("Ethernet WebServer Example");

  // start the Ethernet connection and the server:
  Ethernet.begin(mac, ip);

  // Check for Ethernet hardware present
  if (Ethernet.hardwareStatus() == EthernetNoHardware) {
    Serial.println("Ethernet shield was not found.  Sorry, can't run without hardware. :(");
    while (true) {
      delay(1); // do nothing, no point running without Ethernet hardware
    }
  }
  if (Ethernet.linkStatus() == LinkOFF) {
    Serial.println("Ethernet cable is not connected.");
  }

  // start the server
  server.begin();
  Serial.print("server is at ");
  Serial.println(Ethernet.localIP());
  std::thread first(loopWeb, 1);
  first.detach();
}


void loop() {
  
}


void loopWeb()
{
    while (1)
  {
   
    // listen for incoming clients
    EthernetClient client = server.available();
    if (client) {
      Serial.println("new client");
      // an http request ends with a blank line
      boolean currentLineIsBlank = true;
      while (client.connected()) {
        if (client.available()) {
          char c = client.read();
          Serial.write(c);
          // if you've gotten to the end of the line (received a newline
          // character) and the line is blank, the http request has ended,
          // so you can send a reply
          if (c == '\n' && currentLineIsBlank) {
            // send a standard http response header
            client.println("HTTP/1.1 200 OK");
            client.println("Content-Type: text/html");
            client.println("Connection: close");  // the connection will be closed after completion of the response
            client.println("Refresh: 5");  // refresh the page automatically every 5 sec
            client.println();
            client.println("<!DOCTYPE HTML>");
            client.println("<html>");
            // output the value of each analog input pin
            for (int analogChannel = 0; analogChannel < 6; analogChannel++) {
              int sensorReading = analogRead(analogChannel);
              client.print("analog input ");
              client.print(analogChannel);
              client.print(" is ");
              client.print(sensorReading);
              client.println("<br />");
            }
            client.println("</html>");
            break;
          }
          if (c == '\n') {
            // you're starting a new line
            currentLineIsBlank = true;
          } else if (c != '\r') {
            // you've gotten a character on the current line
            currentLineIsBlank = false;
          }
        }
      }
      // give the web browser time to receive the data
      delay(1);
      // close the connection:
      client.stop();
      Serial.println("client disconnected");
    }
  }
}

For the connection test I used curl:
Code:
time curl -v --header "Content-Type: text/plain" --header "Accept: application/json" "http://192.168.2.161/"

If I use it without threads, then the response time is always <0,05 seconds.
Does anyone have an idea what I am doing wrong?
 
For one, this version of NativeEthernet is not really thread safe so I can’t attest to the stability. Before I made NativeEthernet I was using FNET in a thread safe manner and I don’t remember ever having delays of any significance. If anything it’s probably that it’s not thread safe right now that’s causing the issue.
 
Thanks for the answer.
Sorry if it's a stupid question, I'm a newbie.
Is thread-safe not when multiple threads execute the same code?
Here the code is executed only once but in a different thread?

I used the Teensythread Test example and there I got this:

Code:
CPU speed consistency ***FAIL***
Test thread start OK
Test thread run state OK
Test thread return OK
Test thread speed ***FAIL***
Speed no threads: 64318116
Speed 1 thread: 45516065
Ratio: 0.71
Test set time slice OK
Speed default ticks: 45516174
Speed 200 ticks: 86087821
Expected: 86697480.00
Ratio with expected: 0.99
Test delay yield OK
Yield wait ratio: 1.40
Test thread end state OK
Test thread reinitialize OK
Test stack usage OK
Test thread suspend OK
Test thread restart OK
Test thread stop OK
Test thread start OK
Test thread wait OK
Test thread wait time OK
Test thread kill OK
Test std::thread scope OK
Test basic lock OK
Test basic unlock OK
Test mutex lock state OK
Test mutex lock thread OK
Test mutex unlock OK
Test fast locks OK
18450000 18750000 16359966
Test std::mutex lock OK
Test std::mutex unlock OK
Test Grab init OK
Test Grab set OK
Test Grab lock OK
Test thread stack overflow OK
Test infinite loop (will not end)
0: 0 sec 56400898 440313259 13193278
1: 5 sec 56400898 627492009 13193278
2: 10 sec 56400898 815495335 13193278
3: 15 sec 56400898 1002674085 13193278

If I understand correctly, this reflects my problem.
The thread "CPU speed consistency ***FAIL***" and "Test thread speed ***FAIL***" fails.

Can it be that the thread library has something or my teensy4.1@ 450MHz?
I'am use arduino 1.8.15 / teensyduino 1.54

Regards
 
Back
Top