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

Вопрос Auto Light Sleep Mode - модуль отказывается входить в режим

warl0rd

New member
Здравствуйте, уважаемые форумчане!

Модуль - esp-03. NONOS-SDK взят из официального репозитория espressif/ESP8266_NONOS_SDK, с последними коммитами.

В прошивке реализовано установление режима энергосбережения LIGHT_SLEEP_T и последующее подключение к точке доступа. Модуль успешно подключается и его потребление начинает варьироваться, чаще всего видно число 60мА. Дальше я из обычного виндового терминала делаю ping ip_addr и в результате отправки этих 4 ICMP запросов (ответы приходят) энергосбережение модуля рушится и потребление замирает на отметке в 61-62мА. Если выключить точку доступа и включить, то модуль точку теряет, находит, подключается, и режим энергосбережения восстанавливается.

После экспериментов выяснилось, что для порчи энергосбережения нужно отправить минимум 4 пакета с периодом от 0.5 до 0.8 секунды.​

Есть предположение, что виноват может быть lwip стек, который придерживает какой-нибудь таймер, буду пробовать собрать lwip из исходников SDK и пришвартовать их к сборке.

файл user_init.c
Код:
#define SPI_FLASH_SIZE_MAP              FLASH_SIZE_8M_MAP_512_512


#define SYSPART_OTA_SIZE                0x6A000
#define SYSPART_OTA_2_ADDR              0x81000
#define SYSPART_RF_CAL_ADDR             0xFB000
#define SYSPART_PHY_DATA_ADDR           0xFC000
#define SYSPART_SYSTEM_PARAMETER_ADDR   0xFD000

static const partition_item_t st_ptable[] =
{
  { SYSTEM_PARTITION_RF_CAL, SYSPART_RF_CAL_ADDR, 0x1000},
  { SYSTEM_PARTITION_PHY_DATA, SYSPART_PHY_DATA_ADDR, 0x1000},
  { SYSTEM_PARTITION_SYSTEM_PARAMETER, SYSPART_SYSTEM_PARAMETER_ADDR, 0x3000},
};

//***********************************************
ICACHE_FLASH_ATTR
static void init_done(void)
{
  struct station_config sta_conf;

  wifi_set_opmode_current(STATION_MODE);

  wifi_set_sleep_type(LIGHT_SLEEP_T);

  sta_conf.bssid_set = 0;
  os_memcpy(&sta_conf.ssid, AP_SSID, 32);
  os_memcpy(&sta_conf.password, AP_PASSWD, 64);
  wifi_station_set_config_current(&sta_conf);

  wifi_station_disconnect();
  wifi_station_connect();
}

//***********************************************
ICACHE_FLASH_ATTR
void user_pre_init(void)
{
  if (system_partition_table_regist(st_ptable, ARRAY_SIZE(st_ptable), SPI_FLASH_SIZE_MAP) == 0)
  {
    os_printf("system_partition_table_regist fail\r\n");
    while(1);
  }
}

//***********************************************
ICACHE_FLASH_ATTR
void user_init(void)
{
  system_set_os_print(0);

  system_init_done_cb(init_done);
}
 

warl0rd

New member
nikolz, да, это весь код. Я максимально его упростил, оставил только то, что относится к делу.
>> А где колбек wifi?
Если в нём ничего полезного не делается, то он не нужен.
 

warl0rd

New member
nikolz, я готов добавить куски кода, которые смогут изменить ход событий. Что мне следует добавить в первую очередь?? колбек wifi??
Код:
//***********************************************
ICACHE_FLASH_ATTR
static void wifi_event(System_Event_t *ev)
{
}

ICACHE_FLASH_ATTR
static void init_done(void)
{
  ...
  wifi_set_event_handler_cb(wifi_event);
  ...
}
но что в нём делать, не ясно...
 

warl0rd

New member
@nikolz, я добавлю колбэк wifi, с печатью всех событий в него поступающих. И добавлю лог самого SDK, для большего понимания происходящего. Это у меня всё уже было, до того, как я оставил минимум кода.

>>кроме того я не увидел у вас колбек отправки и приема
Отправки и приёма чего?? Вся суть программы заключается в подключении к заданной точке доступа. Больше от программы ничего не требуется. Но так как в SDK вкомпилен стек LWIP с включенным ICMP, то бонусом этот стек отвечает на пинги.

>>Режим Ligh включается не сразу а лишь если процессор простаивает возможно у вас что-то крутится на процессоре
Да, по логу SDK видно, что режим энергосбережения включается: "pm open,type:1 0"
и потребление начинает скакать. Я для того и выскреб из своего кода всё, что можно, чтобы было сложно сказать, что в моём коде что-то крутится. Остаются задачи SDK и LWIP.
 
Последнее редактирование:

warl0rd

New member
@nikolz,
Лог модуля, последняя строчка - включение режима энергосбережения, после этой строчки модуль больше ничего не сообщает.

Код:
00:00:00.069 OS: mode : null
00:00:00.070 OS: mode : sta(18:fe:34:84:7a:d5)
00:00:00.070 OS: add if0
00:00:00.071 OS: sleep enable,type: 1
00:00:00.071 wifi_event OPMODE_CHANGED
00:00:01.589 wifi_event STAMODE_AUTHMODE_CHANGE
00:00:02.910 OS: scandone
00:00:03.794 OS: state: 0 -> 2 (b0)
00:00:03.799 OS: state: 2 -> 3 (0)
00:00:03.803 OS: state: 3 -> 5 (10)
00:00:03.803 OS: add 0
00:00:03.803 OS: aid 1
00:00:03.803 OS: cnt
00:00:03.817 OS: connected with ap_001, channel 11
00:00:03.817 OS: dhcp client start...
00:00:03.818 wifi_event STAMODE_CONNECTED
00:00:06.795 OS: ip:172.16.1.12,mask:255.240.0.0,gw:172.16.0.1
00:00:06.796 wifi_event STAMODE_GOT_IP
00:00:13.803 OS: pm open,type:1 0
>>если вы посылаете пинг то чем вы его принимаете?
Посылаю пинг с помощью терминала винды. Принимает его LWIP стек модуля, так как там включена поддержка ICMP, то стек отвечает на запрос и виндовый терминал видит ответ.
>>я пинг не делал, но возможно стоит поставить колбек приема и посмотреть реакцию
Изначально у меня был колбэк приёма, но он исправно работал - как часы, со включенным энергосбережением или без него - пинги принимались кодом и отправлялся ответ.

>>Вы уверены что ESP может обрабатывать пинги?
Да, уверенность есть. Больше отвечать некому. Точка доступа и её трафик находятся под контролем.

>>В результате я отказался от этого режима так как нет особого смысла в нем
Я разрабатываю телефон с поддержкой WiFi на этом чипе, поэтому режим энергосбережения для меня так важен.
 

nikolz

Well-known member
@nikolz,
Лог модуля, последняя строчка - включение режима энергосбережения, после этой строчки модуль больше ничего не сообщает.

Код:
00:00:00.069 OS: mode : null
00:00:00.070 OS: mode : sta(18:fe:34:84:7a:d5)
00:00:00.070 OS: add if0
00:00:00.071 OS: sleep enable,type: 1
00:00:00.071 wifi_event OPMODE_CHANGED
00:00:01.589 wifi_event STAMODE_AUTHMODE_CHANGE
00:00:02.910 OS: scandone
00:00:03.794 OS: state: 0 -> 2 (b0)
00:00:03.799 OS: state: 2 -> 3 (0)
00:00:03.803 OS: state: 3 -> 5 (10)
00:00:03.803 OS: add 0
00:00:03.803 OS: aid 1
00:00:03.803 OS: cnt
00:00:03.817 OS: connected with ap_001, channel 11
00:00:03.817 OS: dhcp client start...
00:00:03.818 wifi_event STAMODE_CONNECTED
00:00:06.795 OS: ip:172.16.1.12,mask:255.240.0.0,gw:172.16.0.1
00:00:06.796 wifi_event STAMODE_GOT_IP
00:00:13.803 OS: pm open,type:1 0
>>если вы посылаете пинг то чем вы его принимаете?
Посылаю пинг с помощью терминала винды. Принимает его LWIP стек модуля, так как там включена поддержка ICMP, то стек отвечает на запрос и виндовый терминал видит ответ.
>>я пинг не делал, но возможно стоит поставить колбек приема и посмотреть реакцию
Изначально у меня был колбэк приёма, но он исправно работал - как часы, со включенным энергосбережением или без него - пинги принимались кодом и отправлялся ответ.

>>Вы уверены что ESP может обрабатывать пинги?
Да, уверенность есть. Больше отвечать некому. Точка доступа и её трафик находятся под контролем.

>>В результате я отказался от этого режима так как нет особого смысла в нем
Я разрабатываю телефон с поддержкой WiFi на этом чипе, поэтому режим энергосбережения для меня так важен.
Я использую deep-sleep для энергосбережения.
Я реализовывал Ligth без пингов. Зачем вам пинг?
А сколько времени уходит на ответ?
 

nikolz

Well-known member
фактически у вас перестает работать таймер по которому включается и выключается приемник. приемник всегда включен
Попробуйте все-таки сделать еще колбек по таймеру и поставьте в нем принт
 

warl0rd

New member
@nikolz, deep-sleep для моих целей не годится, пакет от Wifi сети может прийти в любой момент, нужно периодически слушать. Light - это самое то.

>>Я реализовывал Ligth без пингов. Зачем вам пинг?
Пинг - это просто удобный метод для тестирования. В винде ping ip_addr и пакеты пошли. Есть подозрение, что модуль раскорячится, если посылать череду любых IP пакетов, но я это не проверял. Когда я впервые увидел, что модуль более не входит в режим энергосбережения - это были именно пакеты пинга.

>>А сколько времени уходит на ответ?
Здесь прослеживается очень характерная картина, пока модуль в режиме энергосбережения - то задержка ответа достигает десятков мс, как только режим ломается - ответ единицы мс и меньше.
Код:
Первый заход:
Ответ от 172.16.1.12: число байт=32 время=5мс TTL=128
Ответ от 172.16.1.12: число байт=32 время=98мс TTL=128
Ответ от 172.16.1.12: число байт=32 время=24мс TTL=128
Ответ от 172.16.1.12: число байт=32 время=274мс TTL=128

Второй заход:
Ответ от 172.16.1.12: число байт=32 время=13мс TTL=128
Ответ от 172.16.1.12: число байт=32 время=248мс TTL=128
Ответ от 172.16.1.12: число байт=32 время=175мс TTL=128
Ответ от 172.16.1.12: число байт=32 время=1мс TTL=128

Третий заход
Ответ от 172.16.1.12: число байт=32 время=160мс TTL=128
Ответ от 172.16.1.12: число байт=32 время=89мс TTL=128
Ответ от 172.16.1.12: число байт=32 время=16мс TTL=128
Ответ от 172.16.1.12: число байт=32 время=22мс TTL=128
После этого режим энергосбережения ломается и далее ответы идут так:
Код:
Ответ от 172.16.1.12: число байт=32 время=6мс TTL=128
Ответ от 172.16.1.12: число байт=32 время=1мс TTL=128
Ответ от 172.16.1.12: число байт=32 время=1мс TTL=128
Ответ от 172.16.1.12: число байт=32 время=3мс TTL=128
 

warl0rd

New member
фактически у вас перестает работать таймер по которому включается и выключается приемник. приемник всегда включен
Попробуйте все-таки сделать еще колбек по таймеру и поставьте в нем принт
Да, это похоже на правду, подскажите, что это за таймер такой, насколько я понимаю - он в потрохах SDK, просто так к нему не подобраться??
 

nikolz

Well-known member
Да, это похоже на правду, подскажите, что это за таймер такой, насколько я понимаю - он в потрохах SDK, просто так к нему не подобраться??
я бы сам хотел его найти.
Попробуйте сначала сделать без пинга чтобы он входил и выходил из режима а потом добавьте пинг.
 

warl0rd

New member
@nikolz, так как это режим Light, то ядро останавливается, и для пробуждения нужна внешняя периферия, таковой в данном случае выступает RTC и его прерыванием ядро и будится. Поэтому, как такового программного таймера включения/выключения радиочасти может и не быть. Нужно ядру заснуть на бикон-интервал, взводится RTC и модуль спит. В моём случае - этого не происходит, видимо что-то мешает уснуть, но вот что, это большой вопрос.

>>Попробуйте сначала сделать без пинга чтобы он входил и выходил из режима а потом добавьте пинг.
Если пинги с ПК на модуль не посылать - то режим работает, я оставлял и наблюдал с пяток часов. Стоит только зарядить с ПК серию пингов - что-то щёлкает - и режим ломается, тоже оставлял на несколько часов, думал - выправится - не помогает. Только если выключить точку доступа и снова включить - то модуль перецепившись - начинает хранить энергию...
 

nikolz

Well-known member
@nikolz, так как это режим Light, то ядро останавливается, и для пробуждения нужна внешняя периферия, таковой в данном случае выступает RTC и его прерыванием ядро и будится. Поэтому, как такового программного таймера включения/выключения радиочасти может и не быть. Нужно ядру заснуть на бикон-интервал, взводится RTC и модуль спит. В моём случае - этого не происходит, видимо что-то мешает уснуть, но вот что, это большой вопрос.

>>Попробуйте сначала сделать без пинга чтобы он входил и выходил из режима а потом добавьте пинг.
Если пинги с ПК на модуль не посылать - то режим работает, я оставлял и наблюдал с пяток часов. Стоит только зарядить с ПК серию пингов - что-то щёлкает - и режим ломается, тоже оставлял на несколько часов, думал - выправится - не помогает. Только если выключить точку доступа и снова включить - то модуль перецепившись - начинает хранить энергию...
Полагаю, если бы было как вы написали то ток потребления упал бы до 20 мка как в deep-sleep, а ток значительно больше при сне
RTC работает в deep-sleep.
Но возможно что вы правы.
В любом случае у меня Ligh работал с активностью от пинов
Попробуйте без пинга
 

warl0rd

New member
@nikolz, на текущий момент я проверил, что отсылка c ПК модулю пачки UDP пакетов ломает режим, от пингов ушёл. Так же я собрал LWIP стек из исходников и прикрутил к проекту. Буду искать в LWIP. Но есть смутное подозрение, что косяк живёт в самом SDK...
 
@nikolz, на текущий момент я проверил, что отсылка c ПК модулю пачки UDP пакетов ломает режим, от пингов ушёл. Так же я собрал LWIP стек из исходников и прикрутил к проекту. Буду искать в LWIP. Но есть смутное подозрение, что косяк живёт в самом SDK...
А вы не пробовали с другими версиями SDK собирать? Скажем у меня проект, который работает с 2.2.1 с 3.0 просто не работает, программа перезагружается на каком-то этапе. Точнее, на этапе SSL подключения к MQTT брокеру.
 

nikolz

Well-known member
А вы не пробовали с другими версиями SDK собирать? Скажем у меня проект, который работает с 2.2.1 с 3.0 просто не работает, программа перезагружается на каком-то этапе. Точнее, на этапе SSL подключения к MQTT брокеру.
версия 2.2.1 отличается от 3.0 принципиально.
хотя на 3.0 смог запустить но пока вернулся на 2.2.1
 

nikolz

Well-known member
@nikolz, на текущий момент я проверил, что отсылка c ПК модулю пачки UDP пакетов ломает режим, от пингов ушёл. Так же я собрал LWIP стек из исходников и прикрутил к проекту. Буду искать в LWIP. Но есть смутное подозрение, что косяк живёт в самом SDK...
Относительно вашей идеи что используется RTC Если бы это было так, то не надо было бы городить огород в deep-sleep с reset.
 

warl0rd

New member
@Dmitry Orlov, спасибо за идею, я собрал:
2.0.0(656edbf) - поведение аналогичное 3.0.0, но ток, при котором режим энергопотребления рабочий - несравненно меньше, чем в 3.0.0 (я вижу числа 5, 19, 30 мА)
2.1.0(116b762) - вообще не отвечает после включения режима и строчки pm open,type:1 0 и практически не потребляет, видимо радиочасть не включается совсем.
2.2.0(f28eaf2) - поведение аналогичное 3.0.0
2.2.1(6ab97e9) - поведение аналогичное 3.0.0

Я теперь в винде запускаю ping -t ip_addr это бесконечный пинг, и как только вижу, что задержка нескольких ответов подряд стала меньше 1 мс, прерываю. Поломка гарантирована.
Код:
Ответ от 172.16.1.12: число байт=32 время=6мс TTL=128
Ответ от 172.16.1.12: число байт=32 время=236мс TTL=128
Ответ от 172.16.1.12: число байт=32 время=161мс TTL=128
Ответ от 172.16.1.12: число байт=32 время=2мс TTL=128
Ответ от 172.16.1.12: число байт=32 время=1мс TTL=128
Ответ от 172.16.1.12: число байт=32 время=1мс TTL=128
Ответ от 172.16.1.12: число байт=32 время=1мс TTL=128
@nikolz, предположу, что deep-sleep это тот режим, выйти из которого можно только подав внешний сигнал на ногу reset. Этот внешний сигнал подаётся блоком RTC, осталось сделать перемычку и вуаля! В то время, как из режима light-sleep можно выйти как по внешнему сигналу на ноге, так и по программному прерыванию от блока RTC. В даташите на NONOS_SDK есть функции аппаратного таймера и сказано, что для работы этого таймера нужно избегать пользования режимом light-sleep. Если аппаратный таймер в режиме light-sleep не работает, то на чём остаётся реализовывать программные таймеры, как не на блоке RTC??
 

nikolz

Well-known member
@Dmitry Orlov, спасибо за идею, я собрал:
2.0.0(656edbf) - поведение аналогичное 3.0.0, но ток, при котором режим энергопотребления рабочий - несравненно меньше, чем в 3.0.0 (я вижу числа 5, 19, 30 мА)
2.1.0(116b762) - вообще не отвечает после включения режима и строчки pm open,type:1 0 и практически не потребляет, видимо радиочасть не включается совсем.
2.2.0(f28eaf2) - поведение аналогичное 3.0.0
2.2.1(6ab97e9) - поведение аналогичное 3.0.0

Я теперь в винде запускаю ping -t ip_addr это бесконечный пинг, и как только вижу, что задержка нескольких ответов подряд стала меньше 1 мс, прерываю. Поломка гарантирована.
Код:
Ответ от 172.16.1.12: число байт=32 время=6мс TTL=128
Ответ от 172.16.1.12: число байт=32 время=236мс TTL=128
Ответ от 172.16.1.12: число байт=32 время=161мс TTL=128
Ответ от 172.16.1.12: число байт=32 время=2мс TTL=128
Ответ от 172.16.1.12: число байт=32 время=1мс TTL=128
Ответ от 172.16.1.12: число байт=32 время=1мс TTL=128
Ответ от 172.16.1.12: число байт=32 время=1мс TTL=128
@nikolz, предположу, что deep-sleep это тот режим, выйти из которого можно только подав внешний сигнал на ногу reset. Этот внешний сигнал подаётся блоком RTC, осталось сделать перемычку и вуаля! В то время, как из режима light-sleep можно выйти как по внешнему сигналу на ноге, так и по программному прерыванию от блока RTC. В даташите на NONOS_SDK есть функции аппаратного таймера и сказано, что для работы этого таймера нужно избегать пользования режимом light-sleep. Если аппаратный таймер в режиме light-sleep не работает, то на чём остаётся реализовывать программные таймеры, как не на блоке RTC??
нет это не так
В deep-sleep все отключается и работает лишь RTC и память RTC. Когда с RTC (GPIO16)придет сигнал на RST то произойдет restart и начнется установка сеанса. Обычно это 4 секунды, мне удалось получить 0.25 сек.
А в в режиме Ligh ответ гораздо быстрее так как рестарта нет. Но и ток больше так как работает система прерываний и еще что-то
 
Сверху Снизу