• Система автоматизации с открытым исходным кодом на базе esp8266/esp32 микроконтроллеров и приложения IoT Manager. Наша группа в Telegram

Какова максимальная величина промежутка между просыпаниями ESP8266.

Продолжаю бороться со своей поделкой. Вроде все, но вот оказалась проблема с засыпанием и пробуждением.
Если я ставлю интервал 10 минут, то все прекрасно отрабатывает и работает ну скажем в течении 3 суток работало без проблем.
Это вот такая команда:
ESP.deepSleep(600e6);
Весь код, что отрабатывает перед отключение приводить не буду, т.к. он длинный и он работает при таком интервале.
Но в таком случае надолго моего аккумулятора не хватает. А мне надо, что бы хотя бы на 1-2 месяца работы от аккумулятора хватало.
Я решил ставить интервал 3 часа:
ESP.deepSleep(216e8);
Так вот в этом случае код ни разу не срабатывает. Кажется я пробовал 30 минут и 1 час. Вроде работало, но не помню точно, тогда я об этом не задумывался, т.к. код еще не был отработан. Отсюда у меня возникло подозрение, что число 216e8 слишком большое и оно превышает значение переменной, которая тут назначена.
Подскажите, прав ли я и есть ли из этого выход?
 
Вот что нашел сам.
Since SDK 2.1 the maximum Deep Sleep time has changed. The old maximum was based on uint32_t(micros) or ~71.58 minutes (2^32-1 microseconds). The new maximum is calculated from the RTC clock, which drifts with temperature from 5 to 7 timer ticks per microsecond, and will return a different number each time you read system_rtc_clock_cali_proc(). Depending on CPU and temperature, you will get between 3 and 4 hours maximum Deep Sleep. You can read the current theoretical maximum with uint64_t deepSleepMax = ESP.deepSleepMax(); although you should set your time a little less than that due to the RTC drift. If you go over the maximum time when you finally enter Deep Sleep, it disconnects the timer and won't wake without an external RESET.

If you need a longer sleep time than 3 hours, you can pass zero as the time variable to Deep Sleep and it disconnects the RTC. The only way to wake it at that point is an external RESET; D0 can't do it. Both Forced Light Sleep and Deep Sleep(0) are woken by an external signal, so short delays are more efficient with Forced Light Sleep, and longer delays are more energy efficient with Deep Sleep.
Но смысл не понял. Пишут, что раньше было в районе 70 минут. Ну тогда понятно. Но пишут, что новый максимальный период 3-4 часа. Я правильно понимаю, что нужно использовать команду
ESP.deepSleepMax();?
Гугль переводит так:
Новый максимум рассчитывается по часам RTC, которые колеблются в зависимости от температуры от 5 до 7 тактов таймера в микросекунду и возвращают разные числа каждый раз, когда вы читаете system_rtc_lock_cali_proc(). В зависимости от процессора и температуры вы получите максимум от 3 до 4 часов глубокого сна.
И вот тут я недопонимаю. Будет ли работать как я хочу каждые 3 часа или нет? Или надо опытным путем выводить? Или может сработать, а может нет и лучше сделать скажем срабатывание каждые 2ч30 минут или 50 минут?
 

aZholtikov

Active member
На счет вопроса не подскажу, но уточню одну деталь (из SDK 32 - к 8266 применимо тоже) - поможет сберечь батарейку:

esp_deep_sleep does not shut down WiFi, BT, and higher level protocol
Make sure relevant WiFi and BT stack functions are called to close any connections and deinitialize the peripherals. These include:
- esp_bluedroid_disable
- esp_bt_controller_disable
- esp_wifi_stop
 
С длительностью сна понятно. Непонятно как задать. Я нашел примеры в инете. Там пишут так:

ESP.deepSleep(ESP.deepSleepMax())

Но я не понимаю сколько это по времени.
Я попробовал написать так:
ESP.deepSleepMax(21600e6);
Получил ошибку
no matching function for call to 'EspClass::deepSleepMax(double)'
aZholtikov, я правильно понимаю, что перед deepSleep нужно дать команду esp_wifi_stop
 
Что-то не получается. Вставляю команду
esp_wifi_stop();
Сразу пишет о нехватке библиотеки FreeRTOS.h. Я ее нашел, скачал, положил в библиотеки, но все равно не работает.
sketch\esp_wifi.h:62:31: fatal error: freertos/FreeRTOS.h: No such file or directory
Я попробовал внутри папки с библиотекой создать папку freertos и туда файлы переложить. Не помогает.
 
А что бы получить нужно время, нужно как-то так?
ESP.deepSleep(ESP.deepSleepMax() - 10000)
 

CodeNameHawk

Moderator
Команда форума
Проверил, задал сон на час, проснулась.
нужно как-то так?
Нет.
Значение не должно превышать ESP.deepSleepMax() , а нужное время просто посчитайте.
Количество секунд сна умножьте на 1000000, причем это сделайте зарание в калькуляторе или почитайте про "приведение" типов.
 
Не совсем понял. Ведь ESP.deepSleepMax() - 10000 не может превышать ESP.deepSleepMax() ведь я вычитаю из него.
Я посмотрел через вывод в лог. ESP.deepSleepMax() = 13630439417. Это если разделить на 1000000, а потом на 3600 получается 3,786233171388889 часа. Т.е. разница с 3 часами 2830439417. И если сделать
ESP.deepSleepMax() - 2830439417 разве не получу 3 часа?
Про приведение типов почитал. Но не понимаю что к чему приводить надою
 

aZholtikov

Active member
deep sleep в ESP имеет размерность uint32_t в микросекундах (4,294,967,295). Максимальное значение 71 минута. Фсё.
 

CodeNameHawk

Moderator
Команда форума
Ведь ESP.deepSleepMax() - 10000 не может превышать ESP.deepSleepMax() ведь я вычитаю из него.
Не может, но
А что бы получить нужно время,
для меня тут главное "нужное время", а не максимальное время.

deep sleep в ESP имеет размерность uint32_t в микросекундах (4,294,967,295). Максимальное значение 71 минута. Фсё.
Вы бы хотя бы попробовали функцию Serial.println(ESP.deepSleepMax()); и посмотрели, что она возвращает.
Да и на саму deep sleep вам обоим неплохо бы посмотреть, особенно на разрядности ее переменных.
У меня это так выглядит.
1705162949062.png
 

aZholtikov

Active member
вам обоим неплохо бы посмотреть
Не имею возможности и желания работать с Arduino. Написал основываясь на NONOS_SDK (финальной версии). Если ардуинщики улучшили уже года 3 как "умершую" SDK - честь им и хвала. Все равно развития ESP8266 в Arduino не будет. Не обновляют SDK...
 

CodeNameHawk

Moderator
Команда форума
ESP.deepSleepMax() - 2830439417 разве не получу 3 часа?
Скорее всего получите, иногда нет, а чтобы не сидеть лишние 3 часа на отладке, отнимите в калькуляторе 13630439417 - 2830439417 и эту разницу поместите в ESP.deepSleep.
Компилятор приводит значения переменных к большему типу, иногда это приводит к перекосам.
Написал основываясь на NONOS_SDK
а покажите декларацию там этой функции, мне кажется, что делаются они с одной SDK.
 

CodeNameHawk

Moderator
Команда форума
отнимите в калькуляторе 13630439417 - 2830439417 и эту разницу поместите в ESP.deepSleep.
Или можно еще проще, создайте переменную uint64_t и ей присвойте разницу ESP.deepSleepMax() - 2830439417 , после этого напечатайте это переменную для проверки.
Так будите точно знать значение задержки и на этом сэкономите пару часиков.
Мне показалось, что есп спала больше часа, но время мерил на глаз.
 

CodeNameHawk

Moderator
Команда форума
bool system_deep_sleep(uint64 time_in_us)
Высчитывается она с 32 битной функции
//this calculation was taken verbatim from the SDK api reference for SDK 2.1.0.
//Note: system_rtc_clock_cali_proc() returns a uint32_t, even though system_deep_sleep() takes a uint64_t.
Код:
uint64_t EspClass::deepSleepMax()
{
  //cali*(2^31-1)/(2^12)
  return (uint64_t)system_rtc_clock_cali_proc()*(0x80000000-1)/(0x1000);

}
 
Или можно еще проще, создайте переменную uint64_t и ей присвойте разницу ESP.deepSleepMax() - 2830439417 , после этого напечатайте это переменную для проверки.
Да, я такое видел в примерах в инете. Но думал, что задать сначала переменную, в ней посчитать и значение вставить и вставить арифметическое действие это одно и то же. Ну если ESP.deepSleepMax() постоянная величина на одном процессоре.
 
Сутки проверял, работает. Только на 19 минут до 3 часов не догоняет. Подкорректировал, еще запустил.
 
Сверху Снизу