Trên máy chủ web Arduino Do, có độ trễ 5 giây trên Windows, chỉ khi được kết nối qua cổng gốc


7

Máy chủ web của tôi đã hoạt động rất tốt trong nhiều tháng khi được kết nối với Linux thông qua cổng gốc.

Nhưng khi được kết nối với Windows 10 thông qua cổng gốc, nếu máy chủ web Arduino không hoạt động trong khoảng 5 phút (khi không có máy khách nào gọi trang web), thì sẽ có độ trễ 5-10 giây trước khi trang web có thể tải. Sự chậm trễ này không xảy ra khi được kết nối với máy chủ web thông qua cổng lập trình.

Có vẻ như Windows có thể đặt cổng ở chế độ ngủ khi nhận thấy độ trễ không hoạt động, và sau đó phải chờ cổng thức dậy trước khi có thể gọi trang web.

Trên Windows "Cài đặt nguồn", tôi đặt máy tính không bao giờ chuyển sang chế độ ngủ và trong Nguồn "Cài đặt nâng cao", tôi đã tắt "tạm dừng chọn lọc" USB.

Bạn có biết tại sao chỉ có sự chậm trễ kỳ lạ này trên Windows và chỉ khi được kết nối qua cổng gốc không?


PHỤ LỤC: Tôi đã tạo một ví dụ đơn giản tái tạo vấn đề trên máy của tôi. Tôi tự hỏi nếu bất cứ ai có thể thấy bất kỳ vấn đề với mã này.

Đầu tiên, mã trăn. Lưu ý rằng nếu tập lệnh python không bao giờ chạy, không có độ trễ trên máy chủ web Arduino và mọi thứ hoạt động như mong đợi.

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

Và dưới đây là mã Arduino đơn giản hóa. Nó chỉ là một máy chủ web đơn giản phục vụ một trang có nút "tải lại" để tải lại trang. Bạn có thể nhấn "tải lại" bao nhiêu lần tùy ý và chương trình không bao giờ bị đóng băng. Nhưng nếu bạn chạy mã python ở trên và sau đó thử tải lại trang, sẽ có độ trễ dài (khoảng 10-60 giây theo ước tính hiện tại của tôi).

Nếu bạn nhận xét tất cả các dòng "SerialUSB.print" ở bất kỳ đâu trong vòng lặp (trong trường hợp đơn giản này, chỉ có 1 dòng tại: "SerialUSB.println (data);" trong hàm processData), thì trang web không bao giờ đóng băng, ngay cả khi bạn chạy mã python thường xuyên.

Trong ví dụ thực tế của tôi, mã trăn của tôi đã chạy một lần một phút, gây ra đóng băng ngẫu nhiên. Nếu tôi dừng mã python chạy, thì trang web sẽ không còn bị đóng băng nữa. Cuối cùng tôi đã bình luận tất cả các câu lệnh SerialUSB.print của tôi trong vòng lặp và bằng cách đó tôi có thể có mã python chạy đúng lịch trình và chương trình của tôi có đầy đủ chức năng (ngoại trừ việc mất 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

Đây không phải là vấn đề về mặt kỹ thuật đối với tôi nữa, ngoại trừ việc phải bình luận tất cả các tuyên bố "SerialUSB.print" của tôi. Nhưng tôi quan tâm đến việc tìm hiểu những gì gây ra hành vi kỳ lạ này.

Lưu ý: các chức năng "processIncomeByte" và "processData" chủ yếu là từ các bài viết và hướng dẫn của ông Gammon và chúng hoạt động hoàn hảo cho tôi trong 2 máy chủ web Arduino khác mà tôi đang chạy. Tôi muốn lưu ý điều này bởi vì nếu tôi đã tự viết các chức năng, thì rõ ràng chúng sẽ đòi hỏi sự xem xét kỹ lưỡng hơn nhiều.


Làm thế nào để cổng USB liên quan đến Do đang chạy như một máy chủ web?!
Majenko

Điểm tốt! Tôi đoán điều đó làm tăng thêm sự bí ẩn! Tôi không thể hiểu tại sao sẽ có độ trễ (chỉ sau khi không hoạt động) với cổng gốc, nhưng không có độ trễ với cổng lập trình ... và chỉ trên Windows.
Jerry

4
Nhưng bạn vẫn chưa đề cập đến cách bạn tạo Máy chủ web. Đó là một gợi ý tinh tế để nói " Chúng tôi cần xem và hiểu thiết lập và mã của bạn " trước khi chúng tôi có thể giúp bạn.
Majenko

1
Nếu chương trình đáo hạn của bạn được viết đúng thì nó sẽ không gây ra bất kỳ sự chậm trễ nào. Nếu nó không được viết đúng (và mã nối tiếp thường không được viết đúng) thì có thể thấy sự chậm trễ. Đăng mã do của bạn - ít nhất là phần mã liên quan đến serial.
Majenko

1
@Matt - Cảm ơn bạn đã chia sẻ ý tưởng của bạn. Tôi rất thích cuối cùng sẽ tìm ra điều này một ngày nào đó. Tôi đã phát hiện ra từ kinh nghiệm của những người khác rằng có một số điểm kỳ lạ với Arduino Do, và bây giờ, hội đồng quản trị đã chính thức ngừng sử dụng dòng sản phẩm Arduino, tôi không hy vọng các lỗi lạ sẽ được giải quyết. Tôi vẫn cởi mở với ý tưởng rằng nó có thể là một sự cố mạng Windows và thỉnh thoảng tôi thực hiện các thử nghiệm với nó (bao gồm cả những đề xuất ở đây), nhưng cho đến nay tôi không tìm thấy gì.
Jerry

Câu trả lời:


1

Đây là suy đoán vì gần như không ai có thể mô phỏng mạng của bạn (ví dụ, không chỉ phiên bản Windows bạn đang chạy mà tất cả các trình điều khiển được cài đặt và phần cứng dành riêng cho giao diện Ethernet của bạn ... chỉ đề cập đến một số biến).

Cân nhắc sử dụng màn hình mạng để ghi lại tất cả các thông tin liên lạc được thiết lập bởi máy tính Windows. Hãy xem xét máy tính Windows thỉnh thoảng bị lỗi mạng của bạn. Hãy xem xét sự chậm trễ mà bạn gặp phải có thể là thời gian để Windows phục hồi từ những gì nó cho là một mạng xấu.

Quan sát là Windows gửi nhiều tin nhắn tự động qua một mạng mới ở chế độ "khám phá". Sự nghi ngờ là việc thiếu phản hồi đối với một số hoặc tất cả các thông báo này sẽ dẫn đến việc Windows bị lỗi mạng.

Windows có cách báo cáo trạng thái của các mạng thay đổi theo phiên bản Windows. Nhưng các phương thức (menu) này có thể gây khó chịu khi sử dụng vì chúng dường như không cập nhật thường xuyên đủ để phản ánh hành vi thực sự của lưu lượng truy cập ra khỏi máy tính Windows.

Bất kể, kiểm tra nếu trạng thái của mạng luôn luôn tốt. Ngoài ra, kiểm tra xem thiết bị kết nối Windows có thể mong đợi trên mạng hoạt động không (ví dụ: bộ định tuyến có máy chủ DHCP) có cải thiện thời gian phản hồi không. Điều này, như một nỗ lực / thử nghiệm để xác định xem Windows có phản ứng nhanh hơn trong khi kết nối với mạng hoạt động / lành mạnh hay không.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.