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

Перестал выходить из light sleep mode после прикручивания i2c и oled 0.96 на ssd1306

Slacky

Member
Выходил по прерыванию на двух ногах GPIO4, GPIO5. I2C повесил на GPIO2 - SDA, GPIO0 - SCL. Все работает, дисплей выводит. Но как только ушли в light sleep - все. На сигналы на GPIO4 и 5 не реагируем. Если взять код этот и вычистить от I2C - то все прекрасно работает и засыпает и просыпается.

Программлю под UDK ...

Есть мысли, в какую сторону смотреть?

Спасибо.
 

pvvx

Активный участник сообщества
В light sleep в SDK Espressif не работают таймеры и прочее. Т.е. фигово работают, а так-же возможны всевозможные переполнения у LwIP - его таймеры Espressif переключает на пониженную частоту в сотни раз, а по ним он отрабатывает многие процедуры очистки, слежения за TCP стеком и прочими сокетами...
Процессор работает импульсно и большую часть времени отключен - типа спит. Т.е. прерывается работа ваших процедур и слежение за прерываниями по GPIO отключено.
 

Slacky

Member
В light sleep в SDK Espressif не работают таймеры и прочее.
Это все конечно понятно, что не идеал. Но! Без конфигурирования двух GPIO под работу I2C все работает нормально.

Тогда глупый вопрос - как сбросить состояние этих GPIO, как было до включения I2c?
 

pvvx

Активный участник сообщества
Это надо глядеть конкретную программу и какой у вас алгоритм опроса...
Общие вопросы = общие ответы :p
I2C на ESP программный и от него можно ожидать что угодно, особенно в Arduino...
 

pvvx

Активный участник сообщества
#define I2C_MASTER_SDA_GPIO 2
#define I2C_MASTER_SCL_GPIO 0

Pin number:
-----------
Pin 0 = GPIO16
Pin 1 = GPIO5
Pin 2 = GPIO4
Pin 3 = GPIO0

#define D0 0
#define D1 1
#define D2 2
#define D3 3

/* Define pin name */
#define HOT_PIN D1 /* Pin of hot water */
#define COLD_PIN D2 /* Pin of cold water */
#define EXT_POWER_PIN D0 /* Pin of monitoring external power */

wifi_fpm_set_sleep_type(LIGHT_SLEEP_T); //light sleep mode
gpio_pin_wakeup_enable(GPIO_ID_PIN(pin_num[HOT_PIN]),
GPIO_PIN_INTR_LOLEVEL); /* Set the interrupt to look for LOW pulses on HOT_PIN */
gpio_pin_wakeup_enable(GPIO_ID_PIN(pin_num[COLD_PIN]),
GPIO_PIN_INTR_LOLEVEL); /* Set the interrupt to look for LOW pulses on COLD_PIN */
wifi_fpm_open();
 

Slacky

Member
#define I2C_MASTER_SDA_GPIO 2
#define I2C_MASTER_SCL_GPIO 0

Я наверно понял, на что Вы указываете, но мне кажется, что противоречия нет. В данном случае случае 2 - это именно GPIO2
Pin number:
-----------
Pin 0 = GPIO16
Pin 1 = GPIO5
Pin 2 = GPIO4
Pin 3 = GPIO0

#define D0 0
#define D1 1
#define D2 2
#define D3 3
Тут же, D2 -> 2 -> Pin2 - это все GPIO4
#define HOT_PIN D1 /* Pin of hot water */
#define COLD_PIN D2 /* Pin of cold water */
#define EXT_POWER_PIN D0 /* Pin of monitoring external power */
И получается, что D1 - это Pin1 и GPIO5, а D2 - это Pin2 и GPIO4
wifi_fpm_set_sleep_type(LIGHT_SLEEP_T); //light sleep mode
gpio_pin_wakeup_enable(GPIO_ID_PIN(pin_num[HOT_PIN]),
GPIO_PIN_INTR_LOLEVEL); /* Set the interrupt to look for LOW pulses on HOT_PIN */
gpio_pin_wakeup_enable(GPIO_ID_PIN(pin_num[COLD_PIN]),
GPIO_PIN_INTR_LOLEVEL); /* Set the interrupt to look for LOW pulses on COLD_PIN */
wifi_fpm_open();
Ошибки не увидел (возможно она есть, я в этом не сильно разбираюсь), но! Счетчик считает, экран отрисовывает. Если бы были какие-то накладки, то что-то бы не работало в обычном режиме. А так все работает, кроме выхода из Light Sleep, как будто прерывания запретили ...
 

pvvx

Активный участник сообщества
Везде назначен один и тот-же пин, что на I2C, что и на выход из LIGHT_SLEEP.
 

Slacky

Member
Везде назначен один и тот-же пин, что на I2C, что и на выход из LIGHT_SLEEP.
Хорошо, предположим, Вы правы. Но тогда экранчик бы точно не работал?


Физически Oled двумя контактами подключен к D4 и D3, а "кнопки" через землю на D2 и D1. Как тогда все это работает?
 

pvvx

Активный участник сообщества
Хорошо, предположим, Вы правы. Но тогда экранчик бы точно не работал?
Физически Oled двумя контактами подключен к D4 и D3, а "кнопки" через землю на D2 и D1. Как тогда все это работает?
Надписи на заборе тоже соответствуют описаниям в си хидерах?
У вас в исходниках несколько разнородных конфигураций по названиям пинов. Пока не разгребете этот бардак - ничего и никто не разберет.
 

tretyakov_sa

Moderator
Команда форума
Если есть возможность меняйте пины местами. Я уже писал об этом.Чем быстрее вы задубите о всяких D1 D2 и Pin1 и Pin2 и начнете думать в терминах GPIO тем лучше.
Вот как работает у меня:
Код:
void start_light_sleep() {
pinMode(SW1, INPUT); //#define SW1 0
pinMode(SW2, INPUT); // #define SW2 2
WiFi.mode(WIFI_OFF);
wifi_set_opmode_current(NULL_MODE);
wifi_fpm_set_sleep_type(LIGHT_SLEEP_T);
wifi_fpm_open();
gpio_pin_wakeup_enable(SW1, GPIO_PIN_INTR_LOLEVEL);
gpio_pin_wakeup_enable(SW2, GPIO_PIN_INTR_LOLEVEL);
wifi_fpm_set_wakeup_cb(fpm_wakup_cb); // Set wakeup callback
wifi_fpm_do_sleep(0xFFFFFFF); // sleep until gpio activity.
ESP.restart();
}
void fpm_wakup_cb(void)
{
gpio_pin_wakeup_disable();
wifi_fpm_close(); // disable force sleep function
}
А экран подключается так:
SSD1306Wire display(0x3c, 4, 5, GEOMETRY_128_64);
Я стараюсь придерживаться того, что GPIO4 и GPIO5 в справочниках указаны как SDA SCL, чтоб был хоть какой-то стандарт. GPIO2 и GPIO0 физически подтянуты резисторами к VCC и при таком подключении у вас на всех четырех ногах есть подтяжка, так как резисторы на OLED тоже обычно встроены.
WeMos_D1_mini_pinout.png
 

Slacky

Member
Подниму тему. Не то, что я все это время голову ломал. Просто переписал код и выяснил, что проблема никуда не ушла за это время.

Вот тут упрощенный вариант, который дает возможность нажимать на "кнопку" на GPIO5 через землю. И через 10 секунд переводит модeль в режим light_sleep.

Все работает, пока не раскомментируешь строчку инициализации i2c (повешенный на GPIO0 и GPIO2). Вот тут модуль ни в какую не выходит из спящего режима.

Если кому интересно поэкспериментировать - https://github.com/slacky1965/test_light_sleep

P.S. Да, не менял местами, но не потому, что лень. Просто система подразумевает возможный старт, когда кнопка будет в нажатом состоянии. А при массе на GPIO0 или GPIO2 модуль не заработает (вроде, большие пацаны говорили, сам не проверял :)).
 
Сверху Снизу