Auf dem Arduino Due-Webserver gibt es unter Windows eine Verzögerung von 5 Sekunden, nur wenn eine Verbindung über den nativen Port besteht

7

Mein Due-Webserver funktionierte monatelang einwandfrei, als er über den nativen Port mit Linux verbunden war.

Wenn der Arduino-Webserver jedoch über den nativen Port mit Windows 10 verbunden ist und etwa 5 Minuten lang inaktiv ist (wenn kein Client eine Webseite aufruft), tritt eine merkwürdige Verzögerung von 5 bis 10 Sekunden auf, bevor die Webseite geladen werden kann. Diese Verzögerung tritt nicht auf, wenn eine Verbindung zum Webserver über den Programmierport hergestellt wird.

Es scheint fast so, als würde Windows den Port in den Ruhezustand versetzen, wenn es eine Leerlaufverzögerung bemerkt, und dann muss es warten, bis der Port aufwacht, bevor es die Webseite aufrufen kann.

In den Windows "Energieeinstellungen" habe ich den Computer so eingestellt, dass er niemals in den Ruhezustand wechselt, und in den Energie "Erweiterte Einstellungen" habe ich das USB "Selective Suspend" deaktiviert.

Haben Sie Ideen, warum es diese seltsame Verzögerung nur unter Windows und nur bei Verbindung über den nativen Port geben würde?


ERGÄNZUNGEN: Ich habe ein vereinfachtes Beispiel erstellt, das das Problem auf meinem Computer reproduziert. Ich frage mich, ob jemand Probleme mit diesem Code sehen kann.

Zuerst der Python-Code. Beachten Sie, dass es auf dem Arduino-Webserver keine Verzögerungen gibt, wenn das Python-Skript nie ausgeführt wird, und alles wie erwartet funktioniert.

import serial, sys

SERIALPORT = "COM5" # Change this to your serial port!

# Set up serial port
try:
  ser = serial.Serial(SERIALPORT, 115200, timeout=0)
except serial.SerialException:
  sys.exit()

ser.write("Hello World")
print("Hello World")

ser.close()

Und unten ist der vereinfachte Arduino-Code. Es ist nur ein einfacher Webserver, der eine Seite mit einer Schaltfläche zum erneuten Laden bedient, mit der die Seite neu geladen wird. Sie können so oft Sie möchten auf "Neu laden" klicken, und das Programm friert nie ein. Wenn Sie jedoch den obigen Python-Code ausführen und dann versuchen, die Seite neu zu laden, tritt eine lange Verzögerung auf (nach meiner aktuellen Schätzung zwischen 10 und 60 Sekunden).

Wenn Sie alle "SerialUSB.print" -Zeilen auskommentieren, die sich an einer beliebigen Stelle in der Schleife befinden (in diesem vereinfachten Fall gibt es nur 1 Zeile unter: "SerialUSB.println (Daten);" in der processData-Funktion), wird die Webseite niemals angezeigt friert ein, auch wenn Sie den Python-Code häufig ausführen.

In meinem Beispiel aus der Praxis wurde mein Python-Code einmal pro Minute ausgeführt und verursachte zufällige Einfrierungen. Wenn ich die Ausführung des Python-Codes gestoppt habe, gab es auf der Webseite keine Einfrierungen mehr. Am Ende habe ich alle meine SerialUSB.print-Anweisungen auskommentiert, die sich in der Schleife befanden, und auf diese Weise konnte der Python-Code planmäßig ausgeführt werden, und mein Programm hatte die volle Funktionalität (mit Ausnahme des Verlusts von SerialUSB.print).

#include <Ethernet.h>

byte mac[] = {
  0x04, 0xBA, 0xB0, 0xCC, 0xDF, 0x04
};
EthernetServer server(80);
EthernetClient client;

const byte MAX_INPUT = 25; //for processIncomingByte

void setup ()
{
  SerialUSB.begin (115200);
  Ethernet.begin(mac);
  SerialUSB.print("server is at ");
  SerialUSB.println(Ethernet.localIP());
}  // end of setup

bool processIncomingByte (const byte inByte)
{
  static char input_line [MAX_INPUT];
  static unsigned int input_pos = 0;
  switch (inByte)
  {
    case '\n':   // end of text
      input_line [input_pos] = 0;  // terminating null byte
      if (input_pos == 0)
        return true;   // got blank line
      // terminator reached! process input_line here ...
      processData (input_line);
      // reset buffer for next time
      input_pos = 0;
      break;
    case '\r':   // discard carriage return
      break;
    default:
      // keep adding if not full ... allow for terminating null byte
      if (input_pos < (MAX_INPUT - 1)) input_line [input_pos++] = inByte;
      break;
  }  // end of switch
  return false;    // don't have a blank line yet
} // end of processIncomingByteWeb

void processData (const char * data)
{ //Note: since there are no GET requests in this simple example, I removed the parts for processing GET.
  SerialUSB.println (data);
  if (strlen (data) < 4)
    return;
}  // end of processDataWeb

void loop ()
{
  client = server.available();
  if (client) {
    boolean done = false;
    while (client.connected() && !done)
    {
      while (client.available () > 0 && !done)
        done = processIncomingByte (client.read ());
    }  // end of while client connected

      client.println("HTTP/1.1 200 OK");
      client.println("Content-Type: text/html");
      client.println();
      client.print("<html><body>");
      client.print("<a href=\"/\">Reload</a></body></html>");
      delay(10); client.stop();
  }
}  // end of loop

Dies ist für mich technisch gesehen kein Problem mehr, außer dass ich alle meine "SerialUSB.print" -Anweisungen auskommentieren musste. Aber ich bin daran interessiert zu erfahren, was dieses seltsame Verhalten verursacht.

Hinweis: Die Funktionen "processIncomingByte" und "processData" stammen hauptsächlich aus Mr. Gammons Schriften und Tutorials und funktionieren in zwei anderen von mir ausgeführten Arduino-Webservern einwandfrei für mich. Ich wollte dies zur Kenntnis nehmen, denn wenn ich die Funktionen selbst geschrieben hätte, würden sie offensichtlich viel mehr Kontrolle erfordern.

Jerry
quelle
In welcher Beziehung steht der USB-Anschluss zum Due, der als Webserver ausgeführt wird?!
Majenko
Guter Punkt! Ich denke, das trägt zum Rätsel bei! Ich kann nicht herausfinden, warum es eine Verzögerung (nur nach dem Leerlauf) mit dem nativen Port geben würde, aber keine Verzögerung mit dem Programmierport ... und nur unter Windows.
Jerry
4
Sie haben jedoch noch nicht erwähnt, wie Sie den Due zu einem Webserver machen. Es ist ein subtiler Hinweis zu sagen: " Wir müssen Ihr Setup und Ihren Code sehen und verstehen ", bevor wir Ihnen helfen können.
Majenko
1
Wenn Ihr Due-Programm richtig geschrieben ist, sollte es keine Verzögerungen verursachen. Wenn es nicht richtig geschrieben ist (und der Seriencode so oft nicht richtig geschrieben ist), können Verzögerungen auftreten. Veröffentlichen Sie Ihren Fälligkeitscode - zumindest den Teil davon, der sich mit der Seriennummer befasst.
Majenko
1
@Matt - Danke, dass du deine Ideen geteilt hast. Ich würde das gerne eines Tages herausfinden. Ich habe aus den Erfahrungen anderer Leute herausgefunden, dass es einige seltsame Macken beim Arduino Due gibt, und jetzt, da das Board technisch offiziell von der Arduino-Produktlinie ausgeschlossen ist, erwarte ich nicht, dass die fremden Bugs ausgebügelt werden. Ich bin immer noch offen für die Idee, dass es sich um ein Windows-Netzwerkproblem handeln könnte, und gelegentlich experimentiere ich damit (einschließlich der hier vorgeschlagenen), aber bisher habe ich nichts gefunden.
Jerry

Antworten:

1

Dies ist eine Spekulation, da es für eine bestimmte Person möglicherweise nahezu unmöglich ist, Ihr Netzwerk zu simulieren (z. B. nicht nur die von Ihnen ausgeführte Windows-Version, sondern alle installierten Treiber und die für Ihre Ethernet-Schnittstelle spezifische Hardware ... um nur einige zu nennen Variablen).

Verwenden Sie einen Netzwerkmonitor , um alle vom Windows-Computer festgelegten Kommunikationen zu erfassen. Betrachten Sie den Windows-Computer, der gelegentlich Ihr Netzwerk ausfällt. Bedenken Sie, dass die Verzögerung möglicherweise die Zeit ist, die Windows benötigt, um sich von einem seiner Meinung nach schlechten Netzwerk zu erholen.

Die Beobachtung ist, dass Windows viele autonome Nachrichten über ein neues Netzwerk in einem "Erkennungs" -Modus sendet. Der Verdacht besteht darin, dass die fehlende Antwort auf einige oder alle dieser Nachrichten dazu führt, dass Windows ein Netzwerk ausfällt.

Windows bietet Möglichkeiten, den Status von Netzwerken zu melden, die je nach Windows-Version variieren. Die Verwendung dieser Methoden (Menüs) kann jedoch frustrierend sein, da sie anscheinend nicht oft genug aktualisiert werden, um das tatsächliche Verhalten des vom Windows-Computer kommenden Datenverkehrs widerzuspiegeln.

Testen Sie unabhängig davon, ob der Status des Netzwerks immer gut ist. Testen Sie außerdem, ob das Verbinden von Geräten, die Windows in einem funktionierenden Netzwerk erwartet (z. B. einem Router mit einem DHCP-Server), die Antwortzeit verbessert. Dies ist ein Versuch, festzustellen, ob Windows bei einer Verbindung mit einem fehlerfreien / aktiven Netzwerk reaktionsfähiger ist.

st2000
quelle