Вызовы Arduino https работают, когда код перемещается из «цикла» в отдельную функцию. Почему?

#arduino #client #esp8266

#arduino #клиент #esp8266

Вопрос:

Я создал простую процедуру вызова https, которую я использую для проверки того, отвечает определенный сервер или нет. Он использует библиотеки ESP8266WiFi и WiFiClientSecure. Раздел настройки выглядит следующим образом (ssid и пароль, определенные ранее, конечно):

 void setup() {
    Serial.begin(115200);
    Serial.println();
    Serial.print("connecting to ");
    Serial.println(ssid);
    WiFi.begin(ssid, password);
    while (WiFi.status() != WL_CONNECTED) {
        delay(500);
        Serial.print(".");
    }
    Serial.println("");
    Serial.println("WiFi connected");
    Serial.println("IP address: ");
    Serial.println(WiFi.localIP());
}
  

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

 void loop() {
    if (WiFi.status() != WL_CONNECTED) {
        connectToWifi();
    }

    WiFiClientSecure client;
    Serial.print("connecting to ");
    Serial.println(host);
    if (!client.connect(host, httpsPort)) {
        Serial.println("connection failed");
        return;
    }

    String url = "/Views/Something.aspx";
    Serial.print("requesting URL: ");
    Serial.println(url);

    client.print(String("GET ")   url   " HTTP/1.1rn"  
        "Host: "   host   "rn"  
        "User-Agent: BuildFailureDetectorESP8266rn"  
        "Connection: closernrn");

    int zzz = random(5000)   500;
    delay(zzz);
}
  

Этот код будет выполняться от пяти до десяти раз или около того, а затем просто перестанет что-либо делать. Некоторые тесты показали, что он действительно передаст код «delay (zzz)», но больше ничего не произошло.

Теперь вот что: я взял код «цикла» и переместил его в функцию, которую я вызываю из раздела «цикл». И без видимой причины теперь он запускается и выполняется без проблем.

Единственная причина, о которой я мог подумать, заключается в том, что объекты, созданные в «loop ()», не были должным образом выпущены, и, возможно, из-за этого у меня заканчивалась память, когда множество объектов WiFiClientSecure оставались задержанными. Но это всего лишь смутное предположение — и я действительно хотел бы понять, что произошло! Заставить его работать было удовлетворительно, но если я не пойму, ПОЧЕМУ, я действительно многому не научился! =)

Комментарии:

1. Может быть, попробуйте проверить потребление памяти с помощью ESP.getFreeHeap() ?

2. Спасибо за предложение, я попробую это, как только вернусь к этому компьютеру!

Ответ №1:

Проблема в том, что когда в главном цикле установлена задержка, вы, по сути, блокируете все фоновые служебные функции, связанные с управлением стеком TCP / IP и т.д.

Причина, по которой это срабатывает 5-10 раз, заключается в случайном размере задержки, когда задержка слишком велика, код завершает работу esp.

Помещение кода в функцию приводит к некоторому неблокирующему времени и, таким образом, фактически «откладывает задержку» на каждой итерации цикла, и поэтому код работает.

Комментарии:

1. delay() по-прежнему позволяет запускать задачи Wi-Fi и TCP / IP. Даже если бы этого не произошло, ваша более короткая задержка все равно была бы слишком длинной, и ставить yield() в конце loop() бесполезно, поскольку она все равно выполнялась бы после каждого завершения итерации цикла. Документы

2. @gre_gor — ваш комментарий противоречит сам себе. «Даже если бы этого не произошло, ваша более короткая задержка все равно была бы слишком длинной» — как она может быть слишком длинной, если она не блокируется?

3. Я имел в виду «Даже если это не позволяло запускать задачи Wi-Fi и TCP / IP (т. Е. блокировку), ваша более короткая задержка все равно была бы слишком большой «.

4. Фрейзер, ты прав насчет задержки; обычно сбой происходит после задержки, которая составляет около пяти секунд или более — так что этот ответ имеет смысл. То, что вы говорите, очень интересно, поскольку это может и должно повлиять на довольно много кодирования Arduino. Есть ли у вас какие-либо источники, где я мог бы найти какую-нибудь легкую информацию по вопросу неблокирующего кода в отдельных функциях?