7

My Due webserver was working perfectly fine for months when connected to Linux via the native port.

But when connected to Windows 10 via the native port, if the Arduino webserver is idle for about 5 minutes (when no client calls a webpage), then there is a strange 5-10 second delay before the webpage is able to load. This delay doesn't happen when connected to the webserver via the programming port.

It almost seems like maybe Windows is putting the port to sleep when it notices an idle delay, and then it has to wait for the port to wake up before it can call the webpage.

On the Windows "Power Settings" I set the computer to never go to sleep, and also in the Power "Advanced Settings" I disabled the USB "selective suspend".

Do you have any ideas why there would be this strange delay only on Windows and only when connected via the native port?


ADDITIONS: I made a simplified example that reproduces the problem on my machine. I wonder if anyone can see any problems with this code.

First, the python code. Note that if the python script is never run, there are no delays on the Arduino webserver, and everything works as expected.

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()

And below is the simplified Arduino code. It's just a simple webserver that serves a page that has a "reload" button that reloads the page. You can hit "reload" as many times as you want, and the program never freezes. But if you run the python code above and then try to reload the page, there is a long delay (anywhere between 10-60 seconds by my current estimate).

If you comment out all of the "SerialUSB.print" lines that are anywhere in the loop (in this simplified case, there's only 1 line at: "SerialUSB.println (data);" in the processData function), then the webpage never freezes, even if you run the python code frequently.

In my real-world example, my python code was running once a minute, causing random freezes. If I stopped the python code from running, then there were no more freezes on the webpage. I ended up commenting out all of my SerialUSB.print statements that were in the loop, and that way I could have the python code running on schedule, and my program had full functionality (except for the loss of 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

This is not technically a problem for me anymore, except for having had to comment out all my "SerialUSB.print" statements. But I am interested in learning what is causing this strange behavior.

Note: the "processIncomingByte" and "processData" functions are mainly from Mr. Gammon's writings and tutorials, and they are working flawlessly for me in 2 other Arduino webservers I have running. I wanted to note this because if I had written the functions myself, then obviously they would require much more scrutiny.

  • How does the USB port relate to the Due running as a webserver?! – Majenko Dec 1 '15 at 21:14
  • Good point! I guess that adds to the mystery! I can't figure out why there would be a delay (only after being idle) with the native port, but no delay with the programming port... and only on Windows. – Jerry Dec 1 '15 at 21:23
  • 4
    But you still haven't mentioned how you are making the Due a webserver. It's a subtle hint to say "We need to see and understand your setup and your code" before we can help you out. – Majenko Dec 1 '15 at 21:24
  • 1
    If your Due program is written properly then it shouldn't cause any delays. If it's not written properly (and serial code so often is not written properly) then it's possible to see delays. Post your Due code - at least the portion of it that deals with the serial. – Majenko Dec 2 '15 at 11:29
  • 1
    @Matt - Thanks for sharing your ideas. I would love to eventually figure this out some day. I've been discovering from other peoples' experiences that there are some strange quirks with the Arduino Due, and now that the board is technically officially discontinued from the Arduino product line, I'm not expecting the stranger bugs to get ironed out. I'm still open to the idea that it might be a Windows networking problem, and every once in a while I do experiments with it (including those suggested here), but so far I've found nothing. – Jerry Jul 5 '16 at 17:41
1

This is speculation as it may be nearly impossible for any given person to simulate your network (for example, not only the version of Windows you are running but all the drivers installed and hardware specific to your Ethernet interface ... to only mention a few variables).

Consider using a network monitor to capture all communications set out by the Windows computer. Consider the Windows computer occasionally failing your network. Consider the delay you experience may be the time it takes for Windows to recover from what it thinks is a bad network.

The observation is that Windows sends out many autonomous messages over a new network in a "discovery" mode. The suspicion is that the lack of response to some or all of these messages will result in Windows failing a network.

Windows does have ways of reporting the status of networks that vary with the version of Windows. But these methods (menus) can be frustrating to use as they don't appear to update often enough to reflect the true behavior of traffic coming out of the Windows computer.

Regardless, test if the state of the network is always good. Also, test if connecting equipment Windows might expect on a functioning network (for example, a router with a DHCP server) improves the response time. This, as an effort / test to determine if Windows is more responsive while connected to a healthy / active network.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.