• Уважаемые посетители сайта esp8266.ru!
    Мы отказались от размещения рекламы на страницах форума для большего комфорта пользователей.
    Вы можете оказать посильную поддержку администрации форума. Данные средства пойдут на оплату услуг облачных провайдеров для сайта esp8266.ru
  • Система автоматизации с открытым исходным кодом на базе esp8266/esp32 микроконтроллеров и приложения IoT Manager. Наша группа в Telegram

ESP32C3 заглушка DeepSleep перестала исполняться

pvvx

Активный участник сообщества
13 ms - это пробуждение (включение) самого чипа ESP-С3 из deep-sleep:
1746722868373.png
 

pvvx

Активный участник сообщества
По старту питания ситуация аналогична - те-же 12..13 ms на приход в себя у ESP32-C3:
1746723681510.png
 

pvvx

Активный участник сообщества
Т.е. в документации 280 мкс - это всего время работы кода до чего-то. А старт до запуска CPU из отключки - более 12 мс.

Deep-sleep

Средние 519 мкА на 10 циклов сна по 1 сек. В самом Deep-sleep + светодиод и прочее = 434 мкА.

Окно в 15 мс с активностью = 6.209 мА
1746728505255.png

Light-sleep

Средние 629 мкА на 10 циклов сна по 1 сек. В самом Light-sleep + светодиод и прочее = 623 мкА.

Окно в 15 мс с активностью = 1.141 мА (это с выбросом коммутации включения-заряда емкостей в ESP и прочего)

1746728537871.png

Итог

Примерный график тока потребления в зависимости от длительности sleep:
1746728459228.png
(Это с учетом, что в deep-sleep потребление устройства равно 10 мкА, в для Light-sleep соответственно 199 мкА.)

Имеем пересечение в области 400 мс.
Т.е. для WiFi при удержании соединения с AP лучше подойдет Light-sleep.
До этого deep-sleep имеет потребление более 6 раз от light-sleep.
 

pvvx

Активный участник сообщества
Для Zigbee, если у ESP32-S6 примерно тоже-самое, тогда когда идет общение с роутером или координатором меньшее потребление будет при light-sleep. Т.к. тик в Zigbee (QT) = 1/4 секунды.
Но всё равно всё это не имеет смысла для ESP - как только врубит RF на прием или передачу - кранты всем батарейкам. Долгую работу с ESP могут выдержать только сильноточные Li АКБ - а у них саморазряд сверх большой :) :)
 

pvvx

Активный участник сообщества
Так что ESP - это не беспроводное решение :p
 

pvvx

Активный участник сообщества
Пример потребления Zigbee роутера (20.2 мА 3.3V) и измерителя на TLSR8250 c INA226 (до 0.2мА 3.3V) от одного Li-ion 18550 (2Ач):
1746730968651.png
и зарядка. Итог до 3.47В - 2.01 Ач и работа ровно 100 часов до зарядки. Общее потребление ~20.5 мА. С него и приняты замеры BLE маяками в HA. А Zigbee (типовой от Tuya) роутер вечно принимает и передает без всяких снов.
Как это сделать на ESP?
 

nikolz

Well-known member
Спросим у DeepSeek
Можешь предложить программу для ESP32 заглушки для максимально быстрого выхода из сна ESP32C3 и возврата в сон и оценить время работы такой программы
DeepSeek отвечает:
Программа для ESP32-C3 с максимально быстрым выходом из сна и возвратом в режим глубокого сна (Deep Sleep)
ESP32-C3 поддерживает Ultra-Low-Power (ULP) режимы, включая Deep Sleep, из которого можно проснуться по таймеру или внешнему сигналу (например, GPIO).

1. Оптимальная схема работы:
  1. Просыпается по таймеру или внешнему прерыванию (например, кнопка).
  2. Выполняет минимальные действия (например, чтение датчика).
  3. Мгновенно возвращается в Deep Sleep.
2. Оценка времени работы:
  • Выход из Deep Sleep: ~2–5 мс (зависит от тактовой частоты).
  • Возврат в Deep Sleep: ~1–2 мс (после завершения кода).
  • Общее время бодрствования: 3–10 мс (если код минималистичный).
Код для ESP32-C3 (Arduino IDE)

#include <esp_sleep.h>

#define WAKEUP_PIN GPIO_NUM_2 // Пин для пробуждения (можно любой RTC)

void setup() {
Serial.begin(115200);

// Настройка пина для пробуждения (если нужно)
esp_sleep_enable_ext0_wakeup(WAKEUP_PIN, LOW); // Просыпаться по LOW на GPIO2

// ИЛИ пробуждение по таймеру (например, каждые 10 секунд)
// esp_sleep_enable_timer_wakeup(10 * 1000000); // В микросекундах

Serial.println("Проснулся! Делаю полезную работу...");

// --- Минимальная полезная нагрузка (например, чтение ADC) ---
uint16_t adc_value = analogRead(A0);
Serial.printf("ADC: %d\n", adc_value);

// --- Возврат в Deep Sleep ---
Serial.println("Возвращаюсь в сон...");
delay(1); // Даём Serial завершить передачу (опционально)
esp_deep_sleep_start(); // Мгновенный сон
}

void loop() {} // Не используется (ESP сразу уходит в сон)
Как ускорить процесс:
  1. Отключите Serial (если не нужен) — экономит ~2–5 мс.
  2. Используйте RTC-память для сохранения данных между циклами сна.
  3. Минимизируйте код между setup() и esp_deep_sleep_start().
Пример без Serial (рекордное время бодрствования ~1–3 мс):

#include <esp_sleep.h>

void setup() {
// Полезная нагрузка (например, включить светодиод на 1 мс)
pinMode(GPIO_NUM_8, OUTPUT);
digitalWrite(GPIO_NUM_8, HIGH);
delay(1);
digitalWrite(GPIO_NUM_8, LOW);

// Сон до следующего прерывания
esp_deep_sleep_enable_timer_wakeup(1000000); // 1 секунда
esp_deep_sleep_start();
}

void loop() {}
Измерение времени бодрствования
Чтобы точно замерить, сколько времени ESP32-C3 находится в активном режиме:

  1. Подключите осциллограф к GPIO (например, включать его при старте и выключать перед сном).
  2. Или используйте RTC-таймер:

    uint64_t start_time = esp_timer_get_time();
    // ... полезный код ...
    uint64_t duration = esp_timer_get_time() - start_time;
    Энергопотребление
    Deep Sleep: ~20–50 мкА (зависит от конфигурации).
    • Активный режим (на 3 мс): ~40–80 мА (на частоте 160 МГц).
  3. Итог: ESP32-C3 может просыпаться каждые 0.1 секунды и работать годами от батарейки, если код оптимизирован.
Если нужно ещё больше ускорения — можно использовать Light Sleep (просыпается за ~500 мкс, но потребляет больше энергии).
 

pvvx

Активный участник сообщества
Врет. Считает только время исполнения кода без учета старта SoC в 12 ms.
 

pvvx

Активный участник сообщества
Итог: ESP32-C3 может просыпаться каждые 0.1 секунды и работать годами от батарейки, если код оптимизирован.
И тут совравши.
CR2032 при указанных 20 мкА и импульсе за 16 мА не отработает и 8 месяцев.
CR2450 наверно протянет год, если будет всё по минимуму - до 20 мкА и никакого кода кроме входа и выхода из deep-sleep каждые пару сек.
 

pvvx

Активный участник сообщества
Для средней паршивости CR2032 всё просто - после 60% разряда у неё внутренне сопротивление будет к 100 Ом. А при токе 16 мА это составит падение в 1.6В от химии в 3.0В и выйдет всего 1.4В, чего ну ни как не достаточно для работы ESP-С3. В итоге выкачав половину заряда из CR2032 ESP-C3 просто не сможет стартануть.
 

pvvx

Активный участник сообщества
У EFR32MG21 старт из отключки SoC аж 17.8 ms до старта исполнения кода из Flash.
Но для deep-sleep предусмотрено сохранение внутренних потрохов для быстрого рестарта уже в 12.2 us.
Всё это типично, но с плюс - минус для других специализированных для быстрого пробуждения чипов.
А в ESP этого не предусмотрено - при deep-sleep вырубается всё и новый старт обходится от 12 ms, как при первом включении питания на SoC.
По рестарту надо включить и питание на Flash - на это так-же уходит время...
 

pvvx

Активный участник сообщества
Включение питания на SPI-Flash (в доках для низковольтных Flash) параметр времени старта указан как 1..10 ms. Т.е. минимум 1 ms !
"Program, Erase and Write command are ignored" в течении до 10ms.
В BLE/Zigbee чипах питание FLash и RAM (если выставлены флаги) на deep-sleep не отключается. А дается команда перехода в сон и напряжение питания понижается для минимизации утечки.
 

pvvx

Активный участник сообщества
На другом модуле ESP32-C3 c внешней Flash наблюдаем те-же 12..13 ms на время пробуждения SoC:
1746783393134.png
 

pvvx

Активный участник сообщества
Ущё враньё DeepSeek. Но это не ИИ врет, а пользователи ESP создали такой спам :)

Указанный пример:
Код:
#define uS_TO_S_FACTOR 1000000ULL /* Conversion factor for micro seconds to seconds */
#define TIME_TO_SLEEP  1          /* Time ESP32 will go to sleep (in seconds) */

void setup() {
  // Полезная нагрузка (например, включить светодиод на 1 мс)
  pinMode(GPIO_NUM_8, OUTPUT);
  digitalWrite(GPIO_NUM_8, HIGH);
  delay(1);
  digitalWrite(GPIO_NUM_8, LOW);
  esp_sleep_enable_timer_wakeup(TIME_TO_SLEEP * uS_TO_S_FACTOR);
  esp_deep_sleep_start();
}

void loop() {
}
Итог:
1746786879190.png
1. Всё те-же 13 ms прихода в себя SoC.
2. До старта инициализации в Arduino проходит 26 ms
3. Вывод нуля на GPIO наблюдаем через 40 ms от начала пробуждения SoC по таймеру.

Работа с GPIO в ESP как всегда некорректна. При инициализации GPIO возникает импульс.
 

pvvx

Активный участник сообщества
Не тот диапазон тока включил (срабатывало ограничение в 24 мА).
На большем диапазоне, чтобы видно было ток работы в Arduino:
1746787574937.png
Клетка тока как и указано для синего - 5 мА.
 

pvvx

Активный участник сообщества
И для сравнения в nRF Power Profiler Kit II (PPK2) тоже самое (при установке напряжения 3.3В):
1746789331644.png
В низу график GPIO вывода...

1746789508678.png
 

pvvx

Активный участник сообщества
И расчет сколько это проработает от батарейки CR2032 указывает на 7 дней :ROFLMAO: Далее сбой из-за просадки напряжения ниже 1.6B при токе в 32 мА на старте инициализации Arduino.
 

pvvx

Активный участник сообщества
А вы знаете чип nRF или TLSR и т.д. с таким RAM и FLASH и скоростью процессора? И по таким ценам?
Кто-то там говорил о производительности ESP32-C3.
Попробуем посчитать реальную производительность ESP32-C3 для больших объемов кода или для задач, где фигурирует чтение-запись Flash (вызывающая полное опустошение кэша CPU).
Для примера создадим задачу из трех сумм и одного умножения 32-х битного числа со знаком...
И сделаем это 10 раз и надеемся, что компилятор не оптимизировал добирающуюся последовательность.
Плюс для анализа времени выполнения вывода GPIO добавим тестовые переключения.
Скетч
Код:
#define uS_TO_S_FACTOR 1000000ULL /* Conversion factor for micro seconds to seconds */
#define TIME_TO_SLEEP  1          /* Time ESP32 will go to sleep (in seconds) */

int speed_test(int a) {
  volatile int b = 0;
  volatile int c;
  a++;
  b++;

  c = a + b;
  a = c + b;
  b = a - c;
  b = b * c;

  c = a + b;
  a = c + b;
  b = a - c;
  b = b * c;

  c = a + b;
  a = c + b;
  b = a - c;
  b = b * c;

  c = a + b;
  a = c + b;
  b = a - c;
  b = b * c;

  c = a + b;
  a = c + b;
  b = a - c;
  b = b * c;

  c = a + b;
  a = c + b;
  b = a - c;
  b = b * c;

  c = a + b;
  a = c + b;
  b = a - c;
  b = b * c;

  c = a + b;
  a = c + b;
  b = a - c;
  b = b * c;

  c = a + b;
  a = c + b;
  b = a - c;
  b = b * c;

  c = a + b;
  a = c + b;
  b = a - c;
  b = b * c;

  return b;
}

void setup() {
  // Полезная нагрузка (например, включить светодиод на 1 мс)
  pinMode(GPIO_NUM_8, OUTPUT); // стартовый импульс в "0"
  // вывод импулса в "0" длительностью 1 us -_-
  digitalWrite(GPIO_NUM_8, HIGH);
  digitalWrite(GPIO_NUM_8, LOW);
  // кривая задержка != 1
  delay(1);
  digitalWrite(GPIO_NUM_8, HIGH); // фронт в "1" старта отсчета времени испольнения теста
  speed_test(22); // время исполнения 11.8 мкс !
  // импульс в "0" -_-  длительностью 1 мкс
  digitalWrite(GPIO_NUM_8, LOW);
  // импульс "1" _-_ длительностью 1 мкс
  digitalWrite(GPIO_NUM_8, HIGH);
  // импульс "0" -_ длительностью до выхода в deep-sleep (до отключения SoC)
  digitalWrite(GPIO_NUM_8, LOW);
  esp_sleep_enable_timer_wakeup(TIME_TO_SLEEP * uS_TO_S_FACTOR);
  esp_deep_sleep_start();
}

void loop() {
}
Соберем с максимальными частотами и QIO к Flash.
1746795146815.png
В итоге получаем такой тайминг GPIO:
1746795187949.png

Анализируем и получаем время переключения GPIO = чуть менее 1 мкс.
1746795214269.png
Время исполнения тестовой процедуры выходит 11.9 - 0.9 = 11 мкс

Делим на количество арифметических операции в тесте (42) и получаем 11/42=0.262 мкс.

Итог:

Среднее время выполнения одной операции целочисленной числодробилки на ESP32-C3 равно 260 нс.

= 3846154 операций в секунду.
Т.е. производительность ESP32-C3 на CLK в 160 MHz не более чем у CPU в 4..6 MHz типа Cortex M0.

Это при условии размещения программы в Flash и частичного не попадания в кэш CPU. В реальных вычислениях может быть всё гораздо хуже.
 

aZholtikov

Active member
Уважаемый @pvvx.
А если этот тест запустить не в столь Вами "обожаемом" Arduino, а в ESP-IDF с установленным флагом CONFIG_COMPILER_OPTIMIZATION_PERF=y?
Разница будет?
 

pvvx

Активный участник сообщества
Уважаемый @pvvx.
А если этот тест запустить не в столь Вами "обожаемом" Arduino, а в ESP-IDF с установленным флагом CONFIG_COMPILER_OPTIMIZATION_PERF=y?
Разница будет?
Разницы не должно быть. Производится измерение времени выполнения процедуры, а тип среды IDE тут ни при чем.
Цель тут в том, чтобы добиться линейного кода, когда отрабатывается заполнение кэш. Хорошая оптимизация компилятором может оптимизировать данный код вообще в nop, т.к. результат вызова процедуры не используется. А надо проверить производительность списка команд и лучше вообще выключить любую оптимизацию компилятору...

И разница будет если разместить все коды в IRAM. Но это не задача для данного теста, т.к. нужно измерить производительность кода из Flash.
Реальные задачи могут содержать множество вызовов отдельных процедур, которые будут кэшироваться по мере их вызова.
 
Последнее редактирование:
Сверху Снизу