ESP32 — петля DeepSleep или нет?
Я пытаюсь создать батарею & ESP32 на солнечной энергии для будущего использования с датчиками. Он подключается к Wi-Fi, MQTT, публикует некоторые показания и сообщения о состоянии и снова уходит в сон. Время от времени (может произойти после нескольких циклов сна, а иногда и после нескольких сотен циклов) я получаю 2 необъяснимых поведения: 1) не удается подключиться к MQTT при загрузке, 2) не удается заснуть.
Иногда эти действия происходят одновременно.
Есть ли известная проблема с deepsleep
и MQTT (с использованием PubSubClient
)? Самый большой пример глубокого сна, который я видел в Интернете, весь код находится за пределами секции loop()
— обязательно ли быть таким?
Я не делюсь кодом, так как это более общий вопрос.
Парень
ОБНОВЛЕНО 1
большая часть
обратного вызова
была закомментирована, осталась только печать входящего сообщения.Светодиод был подключен к GPIO, вызывая мигание в
loop()
— при успешном переходе в спящий режим он гаснет, при сбое — остается включенным. Этот тест показывает, что когда эта "ошибка" происходит, код на самом деле перестает работать, но не переходит в глубокий сон (в зависимости от мощности)
@Guy . D, 👍0
Обсуждение2 ответа
Лучший ответ:
Есть ли известная проблема с глубоким сном и MQTT?
Нет. Может быть конкретная проблема с конкретной библиотекой, которую вы используете, но концепция проблемы с MQTT в целом — чепуха.
В большинстве примеров глубокого сна, которые я видел в Интернете, весь код находится за пределами секции loop() - обязательно ли быть таким?
Нет, это просто структурировано и приведено в порядок с вашим кодом. Не имеет значения, находится ли код в цикле или в функциях, вызываемых циклом. Управлять кодом может быть намного проще, если вы структурируете его в виде функций, а не сбрасываете все в цикл.
Я не знаю насчет ерунды, но аналогичный вопрос был задан в https://github.com/knolleary/pubsubclient/issues/634 (такое же поведение, но дело все еще открыто...), @Guy . D
MQTT — это просто протокол. Концепция наличия проблемы не имеет логического смысла. Если есть проблема, связанная с использованием MQTT, то это проблема с pubsubclient, а не с MQTT., @Majenko
Хорошо, я согласен, я обращаюсь к pubsubClient
, @Guy . D
Проблема с вызовом ESP.deepSleep(xx)
внутри loop()
заключается в том, что там уже активирован сторожевой таймер, а затем во время спящего режима происходит сброс.< /п>
Чтобы исправить это, я использовал собственную технику сброса ESP.restart()
программного обеспечения после записи подписи для файла «not init». переменная следующим образом:
Область переменной:
uint16_t SleepSign __attribute__((section(".noinit"))); // Горячий сброс/подпись глубокого сна.
Затем в начале setup()
мы пишем код, который проверяет содержимое этой неинициализированной переменной и, если она содержит подпись, ESP.deepSleep(xx)
называется. В моем случае я использую ESP.deepSleep(0)
, потому что я хочу, чтобы устройство перезагружалось только при новой загрузке:
void setup()
{
if (SleepSign == 0xdd11) ESP.deepSleep(0);
Rest of the initialization:
...
Inside loop():
...
if ((millis() - timeconnect) > 300*1000) {
SleepSign = 0xdd11; // глубокий сон при перезапуске
ESP.restart();
}
...
Эта система протестирована и работает корректно, сокращая потребление до минимума, указанного espressif. Раньше я пытался заблокировать просмотр перед выходом из setup()
, но это, конечно, не сработало:
*((volatile uint32_t*) 0x60000900) &= ~(1); // Аппаратное WDT ВЫКЛ.
Очевидно, что если мы заинтересованы в использовании DeepSleep по времени и чтобы устройство делало что-либо перед тем, как снова перейти в спящий режим, мы можем присвоить несколько значений переменной SleepSign для управления перезапуском, а также сбросить ее значение перед вызовом ESP.deepSleep. (0):
void setup()
{
if (SleepSign == 0xdd11) {
SleepSign = 0xffff;
ESP.deepSleep(xx);
}
Rest of the initialization:
...
Единственный недостаток, который я обнаружил, это то, что esp выполняет сброс перед переходом в режим сна, но я не думаю, что это имеет большое значение.
- ESP32 не может спать дольше 35 минут.
- Невозможно создать переменную RTC_DATA_ATTR внутри класса
- ESP32 - неточность NTP после глубокого сна
- целочисленное переполнение в выражении типа 'int' приводит к
- Детектор браунаута ESP32-S2 Случайно срабатывает в глубоком сне
- Как узнать, просыпается ESP32 самостоятельно или вручную
- Монитор напряжения батареи сразу после глубокого сна
- Почему ESP32 не остается в глубоком сне дольше 35 минут?
пропустите вызов публикации MQTT, чтобы увидеть, не переходит ли устройство в спящий режим... пропустите вызов, выполнив вычисление, такое как
if (a+1 == 2) {
, а не комментируя строку, потому что комментирование строка приведет к тому, что компилятор сгенерирует другой код ........ сделайте то же самое с кодом сна, @jsotola@jsotola просто для понимания - «a + 1» должно создавать логическое состояние, которое не будет входить в цикл «if», чтобы аннулировать «публикацию»? а другая часть в
esp_deep_sleep_start();
? Я не понимаю, почему так... кстати - см. редактирование 1/, @Guy . Dесли вы используете знак комментария
//
, чтобы предотвратить запуск команды публикации MQTT, тогда компилятор создаст другой код, который может не иметь проблемы со сном .... использование оператора if гарантирует, что компилятор не пропустит un -исполняемый код ..... проведите такой же тест для спящего кода, чтобы увидеть, влияет ли он на код MQTT ...... проведите тесты отдельно, @jsotola@jsotola - я понял, почему это нужно сделать, я попросил только часть сна. кстати - обходной путь
publish
не сработал, даже когда я увеличил MQTT_MAX_PACKET_SIZE до 512, чтобы быть уверенным, @Guy . D@jsotola для второй проверки («маскировка» фазы сна) - все прошло, как и ожидалось. Чтобы вызвать «перезагрузку», в «loop()» каждые 30 секунд добавлялся ESP.restart()., @Guy . D