Arduino Ethernet Shield часто теряет свой IP-адрес

Я работаю над скетчем, который должен отображать некоторые значения внутренних переменных и аналоговые чтения на простой веб-странице. Единственная загвоздка в том, что он должен быть как можно более надежным.

Я получаю странное поведение на нескольких экранах, когда скетч работает некоторое время (иногда до 5-6 минут), прежде чем вырезать и установить какой-то странный IP-адрес (обычно 0.0.0.0 или что-то подобное)

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

void loop()
{
  ... do some stuff ...
  // прослушивание входящих клиентов
    EthernetClient client = server.available();
    if (client) {
        Serial.println("new client");
        // HTTP-запрос заканчивается пустой строкой
        boolean currentLineIsBlank = true;
        while (client.connected()) {
            if (client.available()) {
                char c = client.read();
                Serial.write(c);
                // если вы дошли до конца строки (получили перевод строки
                // символ) и строка пуста, HTTP-запрос завершился,
                // чтобы вы могли отправить ответ
                if (c == '\n' && currentLineIsBlank) {
                    // отправляем стандартный HTTP-заголовок ответа
                    client.println("HTTP/1.1 200 OK");
                    client.println("Content-Type: text/html");
                    client.println("Connnection: close");
                    client.println();
                    client.println("<!DOCTYPE HTML>");
                    client.println("<html>");
                    // добавить мета-тег обновления, чтобы браузер выполнял повторную загрузку каждые 5 секунд:
                    client.println("<meta http-equiv=\"refresh\" content=\"5\">");
                    // вывод значения каждого аналогового входного вывода
                    client.println(getStrDivByTag("MyWebPage", "h3"));
                    client.println("<br />");


                    client.println("</html>");
                    break;
                }
                if (c == '\n') {
                    // вы начинаете новую строку
                    currentLineIsBlank = true;
                } else if (c != '\r') {
                    // вы получили символ в текущей строке
                    currentLineIsBlank = false;
                }
            }
        }
        // дать веб-браузеру время для получения данных
        delay(1);
        // закрыть соединение:
        client.stop();
        Serial.println("client disconnected");
    }

  ... do some more stuff ...

}

Когда сервер работает должным образом, мой последовательный вывод дает мне что-то вроде:

новый клиент

ПОЛУЧИТЬ / HTTP/1.1

Хост: 192.168.1.17

Агент пользователя: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:73.0) Геккон/20100101 Firefox/73.0

Принимать: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,/;q=0.8

Но незадолго до того, как он перестает работать, я получаю два последовательных запроса:

GET / HTTP/1.1 Host: 192.168.1.17 User-Agent: Mozilla/5.0 (X11;

Убунту; линукс x86_64; rv:73.0) Gecko/20100101 Firefox/73.0 Принять:

текст/html,application/xhtml+xml,application/xml;q=0.9,image/webp,/;q=0.8

Принимаемый язык: en-CA,en-US;q=0.7,en;q=0.3 Принимаемый кодировщик: gzip,

deflate Connection: keep-alive Upgrade-Insecure-Requests: 1

Управление кешем: max-age=0

клиент отключился. Потребляемый ток: -0,341

192.168.1.17 новый клиент GET /favicon.ico Хост HTTP/1.1: 192.168.1.17 Агент пользователя: Mozilla/5.0 (X11; Ubuntu; Linux х86_64; рв:73.0)

Gecko/20100101 Firefox/73.0 Accept: image/webp,/ Accept-Language:

en-CA,en-US;q=0.7,en;q=0.3 Accept-Encoding: gzip, deflate Соединение: Keep-alive Cache-Control: max-age=0

клиент отключился. Потребляемый ток: -0,048

0.0.0.0

Принимаемые языки: en-CA,en-US;q=0.7,en;q=0.3

Accept-Encoding: gzip, deflate

Соединение: поддержка активности

Небезопасные запросы на обновление: 1

Управление кешем: max-age=0

клиент отключен

Что это за запрос, что-то о favicon.ico? После этих последовательных запросов IP-адрес сбрасывается до 0.0.0.0, иногда переходя к чему-то странному, например, 0.64.1.0, 0.1.0.64 и т. д.

Есть ли проблема с конфигурацией моей сети, используемой библиотекой ethernet2?

, 👍0

Обсуждение

использовать библиотеку Ethernet, @Juraj

Убедитесь, что вы явно отключили слот для SD-карты, если вы его не используете, установив для контакта 4 высокое значение в настройках (по крайней мере, это контакт, который использует мой экран Ethernet2). Я чуть не рвал на себе волосы, находя причину, по которой мой (автономный) скетч иногда запускался по 10 минут, иногда по часу, но всегда через какое-то время переставал отвечать. Кажется, что интерфейс SPI SD-карты иногда мешает трафику Ethernet SPI, если вы явно не отключите его., @StarCat


1 ответ


Лучший ответ:

1

Есть много примеров скетчей Ethernet, которые вообще ненадежны. Они в основном управляют настройкой сети в setup() и соединениями TCP в loop(). Это не верно. Это просто означает, что если с вашим сетевым подключением что-то не так, оно не перезапустится правильно. Вы должны проверить Ethernet.localIP(); и перезапустите свой скетч, если он не подходит. Эта процедура должна помочь: void reset() { asm volatile ("jmp 0");

Кроме того, вы должны быть готовы к запросам на favicon.ico из обычных браузеров (это маленький значок, который появляется на ваших вкладках и в избранном) и отвечать на него (вы можете использовать ответ 404, если не хотите отправить файл). Предоставление файла robots.txt также является хорошей практикой.

,

Я не хочу сбрасывать весь скетч, так как это приведет к отключению некоторых реле, передающих мощность, которую скетч должен держать открытым, но я полагаю, что должна быть возможность просто повторять процесс настройки сети каждый раз при изменении IP, верно?, @BruceJohnJennerLawso

Есть ли способ плавного перезапуска экземпляра Ethernet без полной перезагрузки скетча?, @BruceJohnJennerLawso

Да, вы должны переместить процедуру запуска Ethernet из настройки в цикл, но в операторе «если», который проверяет, активен ли Ethernet или нет. Я помню, что видел несколько скетчей, которые делали именно это на github, но я не мог найти их, чтобы сослаться на них в ответе (возможно, они использовали старый чип Ethernet ENC28J60). Извини за это., @Chris