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.