• Уважаемые посетители сайта esp8266.ru!
    Мы отказались от размещения рекламы на страницах форума для большего комфорта пользователей.
    Вы можете оказать посильную поддержку администрации форума. Данные средства пойдут на оплату услуг облачных провайдеров для сайта esp8266.ru
  • Система автоматизации с открытым исходным кодом на базе 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 модуль не заработает (вроде, большие пацаны говорили, сам не проверял :)).
 
Сверху Снизу