ESP8266 всегда сбрасывается после 65 секунд работы
У меня есть простой код, в котором ESP8266 запрашивает базу данных MySQL о фактическом состоянии светодиода (будь то 1 или 0), и когда в БД есть 1, ESP8266 включает светодиод... Но моя проблема после 65-66 секунд работы сервера все равно сбрасывает... Программа делает то, что должна, но через 65-66 секунд перезагружается и пытается переподключиться к wifi
---- РЕДАКТИРОВАТЬ -----
После некоторых экспериментов с кодом я обнаружил, что не имеет значения время выполнения, но количество циклов цикла... Каждый раз, независимо от задержки или скорости обработки, происходит сбой после 48 циклов....
код .ino
// Загрузить библиотеку Wi-Fi
#include <ESP8266WiFi.h>
#include <WiFiClient.h>
#include <ESP8266WebServer.h>
#include <ESP8266HTTPClient.h>
// Замените учетными данными вашей сети
const char* ssid = "XXXX";
const char* password = "XXXX";
const char* host = "http://www.XXXX.XX/arduino_PHP/post_data.php";
// Установить номер порта веб-сервера на 80
WiFiServer server(80);
HTTPClient http;
// Переменная для хранения HTTP-запроса
String header;
// Вспомогательные переменные для хранения текущего состояния вывода
String output5State = "off";
String output4State = "off";
// Назначаем выходные переменные контактам GPIO
const int output5 = 5;
const int output4 = 4;
byte green, red= 0;
void setup() {
Serial.begin(115200);
// Инициализировать выходные переменные как выходы
WiFi.mode(WIFI_OFF); // Предотвращает проблему повторного подключения (слишком долгое подключение)
WiFi.mode(WIFI_STA); //Эта строка скрывает просмотр ESP как точки доступа Wi-Fi
delay(1000);
pinMode(output5, OUTPUT);
pinMode(output4, OUTPUT);
// Установить выходы на НИЗКИЙ уровень
digitalWrite(output5, LOW);
digitalWrite(output4, LOW);
// Подключаемся к сети Wi-Fi с SSID и паролем
Serial.print("Connecting to ");
Serial.println(ssid);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
// Выводим локальный IP-адрес и запускаем веб-сервер
Serial.println("");
Serial.println("WiFi connected.");
Serial.println("IP address: ");
Serial.println(WiFi.localIP());
server.begin();
}
void loop(){
delay(500);
DB_state("Green",green);
DB_state("Red",red);
delay(500);
}
void DB_state(String component,int state){
String postData =("component=" + String(component) + "&state=" + String(state));
Serial.println(postData);
http.begin("http://www.XXXX.XX/arduino_PHP/DB_state.php");
http.addHeader("Content-Type", "application/x-www-form-urlencoded");
http.POST(postData); //Отправить запрос
String payload = http.getString(); //Получить полезную нагрузку ответа
Serial.println(payload);
http.end(); //Закрыть соединение
state_LED(payload,component);
}
void state_LED(String str, String led){
int x;
if (led== "Green") {
x = 4;}
else if (led== "Red") {
x = 5;}
if (str == "State: 1") {
digitalWrite(x, HIGH);}
else if (str == "State: 0") {
digitalWrite(x, LOW);}
}
Отладка стека ESP8266
Exception 28: LoadProhibited: A load referenced a page mapped with an attribute that does not permit loads
PC: 0x4020744a: ClientContext::state() const at C:\Users\XXXX\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.7.4\libraries\ESP8266WiFi\src/include/ClientContext.h line 364
EXCVADDR: 0x00000184
Decoding stack results
0x40203f10: HardwareSerial::write(unsigned char const*, unsigned int) at C:\Users\XXXX\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.7.4\cores\esp8266/HardwareSerial.h line 164
0x40203f1c: HardwareSerial::write(unsigned char const*, unsigned int) at C:\Users\XXXX\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.7.4\cores\esp8266/HardwareSerial.h line 165
0x40207512: HTTPClient::connected() at C:\Users\XXXX\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.7.4\libraries\ESP8266HTTPClient\src\ESP8266HTTPClient.cpp line 475
0x40202d24: HTTPClient::disconnect(bool) at C:\Users\XXXX\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.7.4\libraries\ESP8266HTTPClient\src\ESP8266HTTPClient.cpp line 434
0x40203ac8: HTTPClient::end() at C:\Users\XXXX\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.7.4\libraries\ESP8266HTTPClient\src\ESP8266HTTPClient.cpp line 425
0x402012ba: DB_State(String, int) at C:\Users\XXXX\Documents\Arduino\ESP8266_php_DB_control/ESP8266_php_DB_control.ino line 87
0x40201334: loop() at C:\Users\XXXX\Documents\Arduino\ESP8266_php_DB_control/ESP8266_php_DB_control.ino line 73
0x40100175: esp_schedule() at C:\Users\XXXX\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.7.4\cores\esp8266\core_esp8266_main.cpp line 125
0x40205628: loop_wrapper() at C:\Users\XXXX\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.7.4\cores\esp8266\core_esp8266_main.cpp line 197
Спасибо за любой совет
@Sahasrar, 👍3
Обсуждение1 ответ
Лучший ответ:
Не знаю как, но наконец-то я нашел работающее решение... Я добавил HTTPClient http;
поверх функции, и все работает...
void DB_state(String component,int state){
HTTPClient http; // ЭТО ДОБАВЛЕНО
String postData =("component=" + String(component) + "&state=" + String(state));
Serial.println(postData);
http.begin("http://www.XXXX.XX/arduino_PHP/DB_state.php");
http.addHeader("Content-Type", "application/x-www-form-urlencoded");
http.POST(postData); //Отправить запрос
String payload = http.getString(); //Получить полезную нагрузку ответа
Serial.println(payload);
http.end(); //Закрыть соединение
state_LED(payload,component);
}
Кто-нибудь может объяснить мне, как это возможно? Потому что я не совсем понимаю эту процедуру.
Теперь вы каждый раз создаете и уничтожаете объект HTTPClient
в этой области, как [указывает C++](https://en.cppreference.com/w/cpp/language/storage_duration#Storage_duration). Предположительно глобальная утечка какого-то ресурса, но я могу только строить догадки на этот счет., @nanofarad
Извините, я не понимаю. Не могли бы вы быть проще?, @Sahasrar
Я не могу разбить это дальше в пространстве, предоставленном мне комментарием. Я предлагаю взять учебник по C++, который охватывает объекты, конструкторы, деструкторы и т. д., который предоставит эту информацию в более понятном виде. Но в основном вместо того, чтобы иметь один HTTPClient на время жизни программы, вы создаете новый HTTPClient и очищаете его после каждого запроса. Это интуитивно понятно, но я недостаточно знаю внутренности HTTPClient, чтобы понять, почему это происходит. в конечном итоге сбой, если вы повторно используете один и тот же экземпляр снова и снова., @nanofarad
https://github.com/esp8266/Arduino/issues/7613#issuecomment-700782051, @Juraj
- Как читать и записывать EEPROM в ESP8266
- Как исправить: Invalid conversion from 'const char*' to 'char*' [-fpermissive]
- ошибка: espcomm_upload_mem failed при загрузке скетча
- Как определить размер Flash?
- Несколько клиентских серверов через Wi-Fi
- Передача функции-члена класса в качестве аргумента
- В ESP-12E NodeMCU, какой выход PIN A0?
- Esp8266 Vin контакт
Таким образом, это может быть проблема с памятью, такая как утечка или проблема с распределением ресурсов., @the busybee
Я так и думал, но как это исправить?, @Sahasrar
Прежде чем вы сможете исправить это, вам нужно его идентифицировать. Прочтите документацию по
WiFiServer
иHTTPClient
, используйте свои навыки поиска в Интернете для подробного сообщения об ошибке «исключение 28» и так далее. Проверьте свои выводы и предположения с помощью тестовых программ; например, дважды вызовитеhttp.POST()
вDB_state()
и подсчитайте количество циклов., @the busybeeсначала я бы перестал использовать String, @Juraj
Почему? И как вы его заменяете?, @Sahasrar
@Juraj pozdravujem slovenského brata v programovaní :D :D :D, @Sahasrar