Maximale Übertragungsgeschwindigkeit ESP8266 TCP/IP

Hallo,

ich habe folgendes Problem. Ich möchte in einem Interval von 10ms Daten von meinem ESP an ein Socket auf meinem PC schicken.

Das Senden der Daten funktioniert einwandfrei. Auch das Empfangen.

Jedoch komme ich nicht auf die vorgegebene Zeit.

UDP ist keine Lösung, da ich die Daten geordnet und ohne Verlust brauche.

Code des ESP8266:

#include <Arduino.h>
#include <Wire.h>
#include <SPI.h>
#include <ESP8266WiFi.h>
#include <Adafruit_BNO055.h>
#include <Adafruit_Sensor.h>



/*SSID and Password for Connection*/
const char* ssid="ESP8266";
const char* password ="123";

IPAddress local_ip(192,168,11,1);
IPAddress gateway(192,168,1,1);
IPAddress subnet(255,255,255,0);





bool runTransmission;
bool stopTransmission;


WiFiServer server(1045);

Adafruit_BNO055 IMU = Adafruit_BNO055(-1, 0x28);



const unsigned long interval = 10;
//unsigned long previousmillis = 0;


//BNO055 data

double acc_x;
double acc_y;
double acc_z;

WiFiClient client; 

void readSensorData (){

  imu::Vector<3> acc = IMU.getVector(Adafruit_BNO055::VECTOR_ACCELEROMETER);
  acc_x = acc.x();
  acc_y = acc.y();
  acc_z = acc.z(); 
}


void setup() {


  

  WiFi.mode(WIFI_AP);
  WiFi.softAPConfig(local_ip,gateway,subnet);
  WiFi.softAP(ssid,password);


  Serial.begin(115200);
  Serial.println();
  Serial.print("IP Adresse: "); Serial.println(WiFi.softAPIP()); 

  



  
 
  

  Serial.println("Wifi started");
  /*WiFi.softAPConfig(local_ip,gateway, subnet);*/
  delay(100);

  server.begin();
  Serial.println("Server started");

  //start BNO055
  IMU.begin();
  
  //Timer interrupt
  noInterrupts();
 
  //disabling Nagle
  client.setNoDelay(true);
  
}

void loop() {

  

 
 
  client = server.available();

  if(client){
    Serial.println("Client vorhanden");

    while(client.connected()){
     
      if(client.available()>0){
        
        Serial.println("Nachricht erhalten! Starten");

        runTransmission   = 1;
        stopTransmission  = 0;

      }else{
        stopTransmission  = 1;
        runTransmission   = 0;
      }

          //String c = client.readStringUntil(end);

        while(runTransmission){
          
            
 
         /*if(millis() - previousmillis  >= interval){
          Serial.println(millis()-previousmillis);           
          previousmillis += interval;}*/


          //interval for sending data
          delay(interval);

          //readSensorData();
          
          //represent a data size of 6 double values(48byte) in one TCP_Packet
          char msg[49] = "123456781234567812345678123456781234567812345678";
          //client.println(msg);
          client.write((const char *) msg, 48);
             
          client.flush();

          
          
      

        }  

        



      

      

      

      
         
    }

  
 }

  
}

Ausgabe ESP:

Blockzitat

IP Adresse: 192.168.11.1
Wifi connected
Server started
Client vorhanden
Nachricht erhalten! Starten

Blockzitat

Code ClientSocket (C++) Terminal:

    char buff[4096];
    string userInput;


  
    

   do {


        cout << " 1 zum starten der Uebertragung";
        getline(cin, userInput);


        //record starttime 
        auto start = std::chrono::high_resolution_clock::now();
        if (userInput.size() > 0) {
            int sendResult = send(sock, userInput.c_str(), userInput.size() + 1, 0);
            listenStatus = 1;

        

            //if (sendResult != SOCKET_ERROR)

            
           
            while(listenStatus = 1 && counter < 1000 && )
            {   
        
                //wait for response 
                ZeroMemory(buff, 4096);
                int bytesReceived = recv(sock, buff, 4096, 0);
                if (bytesReceived > 0)
                {

                    cout << "Server: " << string(buff, 0, bytesReceived) << endl;
                    counter++;
                    cout << counter << endl;
                }

            }

        }

         auto finish = std::chrono::high_resolution_clock::now();
        std::chrono::duration<double> elapsed = finish - start;
        std::cout << "Elapsed time for 1000 packets receiving with a data size 48bytes : " << elapsed.count() << " s\n";

Ausgabe der Konsole:

Blockzitat

Elapsed time for 1000 packets receiving with a data size 48bytes : 61.7903 s

Blockzitat

Wireshark:

Da ich aber pro Sekunde 100Packete empfangen sollte, müsste die Elapsed time bei 10 s sein.

Kennt sich jemand hier aus und weiß welchen Fehler ich mache ?
Nagle hab ich schon deaktiviert, hat nichts gebracht.

Da Websockets meines Wissens nach langsamer sind als RawSockets habe ich den Weg auch ausgeschlossen.

Verzeiht mir wenn der Code nicht sauber ist, habe nur etwas Programmiererfahrung.

Vielen Dank :slight_smile:

Nimm mal das "delay" aus der Sendeschleife. Du wartest dort immer nach jedem Paket
10ms. D.h. selbst wenn die Übertragung zeitlos wäre schaffst du maximal 100 Päckchen.
Da sie aber Zeit braucht schaffst du entsprechend weniger.

Ulli

Danke für die Antwortet:) habe das davor ohne delay realisiert mit den millis das hat aber zum selben Effekt geführt. Und wenn ich das Delay weglasse, komme ich auch nur auf 46s für 1000 packete...

Zeig den Sketch.
Man kann auch mit millis() blockierend programmieren.

Grüße Uwe

Serial.println(millis() - previousmillis);

Das wird nichts.
Du bekommst über den SerMon nicht alle 10ms diese Meldung raus.
Also las sie weg.

Dann eine Bitte: Vor der Veröffentlichung einmal STRG-T drücken und die ganzen Leerzeilen löschen.
Danke.

Ersetze mal loop:

void loop()
{
  client = server.available();
  if (client)
  {
    Serial.println(F("Client vorhanden"));
    while (client.connected())
    {
      if (client.available() > 0)
      {
        Serial.println(F("Nachricht erhalten! Starten"));
        if (millis() - previousmillis  >= interval)
        {
          
          previousmillis += interval;
          //readSensorData();
          //represent a data size of 6 double values(48byte) in one TCP_Packet
          char msg[49] = "123456781234567812345678123456781234567812345678";
          //client.println(msg);
          client.write((const char *) msg, 48);
          client.flush();
        }
      }
      else
      {
        Serial.println(F("Client not available"));
      }
    }
  }
}

Ich habe keinen ESP - kann das also nicht testen.

ESP ist eben kein Arduino, Der ESP-core für Arduino emuliert einen Arduino.
Das eigentliche "Ethernet" läuft im freeRTOS Betriebssystem ab (Auch bzw. gerade während eines delay)
Die Frage richtet sich daher auch weniger an ein Arduino- als an ein espressif- Forum, fürchte ich.
Mal abgesehen davon, dass Ethernet prinzipiell mit nicht-deterministischen Kollisionen im Netz und daraus bedingten variablen Response-Zeiten leben muss.

Hi Uwe,

Der Programmcode mit den milis(), ist im obigen Sketch auskommentiert. Jedoch hat das Ganze auch ganz ohne Delay und ohne milis(), das heißt ne pure while Schleife keine akzeptable Geschwindigkeit. Ca. 46s für 1000Pakete..

client.flush() lässt das Programm „warte“ bis alle Daten aus client.write() verschickt wurden.

Hallo,

Danke für den Sketch werde ihn ausprobieren sobald ich wieder in Deutschland bin. Bin grad im Ausland und hab meinen Laptop nicht dabei..

Gebe aufjedenfall Rückmeldung.

Hallo Michael,

Vielen Dank für den Tipp ! Habe mich im espressif Forum etwas umgeschaut und es könnte auch daran liegen!

Sobald ich dort was herausfinden würde ich es hier bekanntgeben, falls jemand zukünftig diese Problem hat.