Обновление веб-страницы зависает через несколько раз

Я использую плату Nucleo F429ZI и написал скетч, позволяющий создать простой веб-сервер:

#include <LwIP.h>
#include <STM32Ethernet.h>

const int WEB_PORT = 80;
EthernetServer server(WEB_PORT);
char buffer[1024];

void setup() 
{
    Serial.begin(115200);
    // определяем переменные
    Ethernet.begin(localIP, netmask, dns, gateway);
    server.begin();
}

void loop() 
{
    processServer();
}

void processServer()
{
  String readString; 
  EthernetClient client = server.available();
  if (client) 
  {
    while (client.connected()) 
    {
      if (client.available()) 
      {
        char c = client.read();
        readString += c; 

        if (c == '\n')
        {
          if (readString.startsWith("GET"))
          {
            readString.remove(0, 4);
            int pos = readString.indexOf(' ');
            String path = readString.substring(0, pos);

            if (path == "/status") pageStatus(client);
            break;
          }
        }
      }
    }
    delay(1);
    client.stop();
  }
}

void pageStatus(EthernetClient client)
{
    sectionHeader(client, 2);
    client.println("<html>");
    client.println("<style>table{font-family: verdana, sans-serif;border-collapse: collapse;width: 30%;}");
    client.println("td, th{border: 1px solid #dddddd;text-align: left;padding: 8px;}tr:nth-child(even)");
    client.println("{background-color: #dddddd;}</style>");
    client.println("<table>");
    client.println("<tr><th>Servo</th><th>Position</th><th>Running</th><th>Initialized</th></tr>");

    for (int i = 0; i < getParamUInt8(P_SERVO_SIZE); i++) 
    {
        sprintf(buffer, "<tr><td>%u</td><td>%d</td><td>%s</td><td>%s</td></tr>", i + 1, (int16_t) _servo[i].current, _servo[i].ended ? "NO" : "YES", _servo[i].initialized ? "YES" : "NO" );
        client.println(buffer);
    }
    client.println("</table>");

    client.println("<br><hr><br>");

    client.println("<table>");
    client.println("<tr><th>Led</th><th>PWM</th><th>Running</th></tr>");

    for (int i = 0; i < getParamUInt8(P_LED_SIZE); i++) 
    {
        sprintf(buffer, "<tr><td>%u</td><td>%d</td><td>%s</td></tr>", i + 1, (int16_t) _led[i].pwm, _led[i].ended ? "NO" : "YES");
        client.println(buffer);
    }
    client.println("</table>");

    client.println("<br><hr><br>");

    client.println("<table>");
    client.println("<tr><th>Stepper</th><th>Position</th><th>Running</th></tr>");

    for (int i = 0; i < getParamUInt8(P_STEPPER_SIZE); i++) 
    {
        sprintf(buffer, "<tr><td>%u</td><td>%d</td><td>%s</td></tr>", i + 1, (int16_t) _stepper[i].stepper.getCurrentPositionInMillimeters(), _stepper[i].stepper.motionComplete() ? "NO" : "YES");
        client.println(buffer);
    }
    client.println("</table>");
    client.println("</html>");
}

void sectionHeader(EthernetClient client, int refresh)
{
    client.println("HTTP/1.1 200 OK");
    client.println("Content-Type: text/html");
    client.println("Connection: close");
    if (refresh) client.println("Refresh: 2"); 
    client.println();
    client.println("<!DOCTYPE HTML>");
}

Как видно из sectionHeader(), я хочу обновлять страницу каждые 2 секунды. Он работает, но после 3 или 4 обновлений он зависает, и мне приходится сбрасывать всю плату.

Конечно, со встроенной системой я бы использовал Ajax... здесь я подумал, что перезагрузки страницы должно быть достаточно.

Что может вызвать такое зависание?

, 👍0

Обсуждение

Я рекомендую https://www.stm32duino.com, @Juraj

Добро пожаловать в ужасно плохой мир объекта String. Откажитесь от него в первую очередь., @Majenko

@Majenko, я использовал объект String только для анализа входящего запроса GET. Как думаете, стоит его удалить, о моей проблеме?, @Mark

1. Вы можете посмотреть HTTP-разговор с Wireshark. 2. Что делает ваш сервер, когда клиент запрашивает "GET /favicon.ico"? 3. Что, если он вместо этого запросит «HEAD /favicon.ico»?, @Edgar Bonet

@EdgarBonet, он просто не отвечает. Это плохое поведение? Должен ли я в любом случае дать ответ?, @Mark


1 ответ


1

Имеющийся у вас код, который говорит readString += c, должен выделять целую новую строку всякий раз, когда в ней не хватает места для дополнительных символов. Все эти распределения заполняют память.

Вместо класса String используйте один массив символов C, например

символ с[128];

его достаточно для всего, что вы в него поместите.

Если это поможет, я написал простой веб-сервер на Arduino для своего собственного проекта, и если вы посмотрите на код здесь, это может дать вам идеи о том, как это реализовать.

,

Или просто установите readString = "" после обработки запроса, я думаю., @Mark