Показ дописів із міткою детектор руху. Показати всі дописи
Показ дописів із міткою детектор руху. Показати всі дописи

вівторок, 3 жовтня 2017 р.

ESP8266: Вихід з режиму deep-sleep як по RTC так і по зовнішньому перериванню

Передмова

При розробці одного пристрою IoT на ESP8266, виникла необхідність живити цей пристрій від батарейок. Щоб забезпечити довге життя батарейкам потрібно вводити ESP8266 в режим глибокого сну (deep sleep), а прокидатись по зовнішній події, наприклад в моєму випадку це спрацювання сенсору присутності людини "Human detector sensor". Що ж, режим deep-sleep у чипа ESP8266 в наявності, а також в наявності штатні способи виходу зі сну, як по внутрішньому RTC, так і по зовнішньому перериванню. Для пробудження по RTC достатньо з'єднати піни GPIO16 і RST. І тоді, наприклад, по команді:
ESP.deepSleep(10e6);
ESP8266 увійде в режим глибокого сну, а через 10 секунд прокинеться і почне виконувати код з самого початку.
Якщо потрібно пробудження по зовнішньому перериванню то потрібно забезпечити короткий імпульс логічного нуля на виводі RST чипу ESP8266. І тоді відправивши чип у глибокий сон "навічно":
ESP.deepSleep(0);
Можна кнопкою "Reset", яка під'єднана до виводу RST чипу і до GND схеми, вивести з режиму глибокого сну, або замість кнопки буде якийсь датчик чи сенсор, який при спрацюванні буде давати короткий імпульс логічного нуля.
Наче нічого складного. Але є одне але.

Чому не все так просто

Наприклад, в моєму випадку з PIR сенсором:
HC-SR501 Infrared PIR Motion Sensor Module
Цей сенсор, при спрацюванні має на виході стійку логічну одиницю протягом від декількох секунд до декількох хвилин. В залежності від налаштувань сенсора. А нам потрібен короткий імпульс логічного нуля. Бо чип ESP8266 не перезавантажиться поки на сенсорі PIR буде логічна одиниця. Значить потрібна схема не тільки інвертору , яка з логічної одиниці перетворить сигнал на логічний нуль, а ще й сформувати короткий імпульс логічного нуля по фронту що наростає на вході.
Це добре, є такі схеми, але ж хочеться мати і пробудження по внутрішньому RTC (а раптом при подальшій розробці пристрою захочеться розширити функціонал?). Здавалося нічого складного, з'єднав GPIO16 з RST і користуйся. Але так не можна робити, бо в нас крім GPIO16 до RST буде під'єднано, як кнопку "reset" для ручного перезавантаження ESP8266, так і "формувач короткого імпульсу". Потрібно GPIO16 з'єднати з RST через струмообмежувальний резистор близько 470 Ом. Спробувавши з'єднання через резистор, мій ESP8266 так і не зміг прокинутись за допомоги внутрішнього RTC. Додавши між GPIO16 та RST "буферний емітерний повторювач", чип ESP8266 чудово і безвідмовно прокидався через назначений час. Добре, додамо до схеми і емітерний повторювач. Готового рішення в інтернеті я не знайшов, хоч по всіляким форумам люди шукають рішення. Наведені схеми не робочі, або взагалі не мають ніякого логічного сенсу. Тож втілимо своє рішення-схему самі.

Схемна реалізація виходу з режиму DEEP-SLEEP


Коли спрацьовує PIR Sensor на його виході йде перемикання стану з "0" на "1". Конденсатор C1 за короткий час заряджається і на короткий час відкривається транзистор Q1, а також на короткий час відкриється буферний емітерний повторювач на транзисторі Q2. Забезпечивши короткий імпульс логічного нуля на виводі RST чипу ESP8266, саме під час перекидання стану виходу PIR sensor з 0 на 1. Подальша поведінка PIR sensor не впливає на чип поки сенсор не перемикнеться в початковий стан, а для програмного контролю, чи спрацював PIR сенсор, чи вже скинувся в початковий стан можна контролювати на якомусь вільному виводі GPIO чипу ESP8266. В мене на схемі це "D1" для NODE MCU, або "GPIO5" для ESP8266.
Щоб мати можливість прокидатись і по внутрішньому RTC, під'єднаємо на вхід буферного емітерного повторювача вихід "D0" для NODE MCU, або "GPIO16" для ESP8266, через резистор на сотні Ом (в мене під рукою був 330 Ом, але підійде мабуть будь який в межах 200 Ом - 10 кОм).
До виходу схеми під'єднаємо кнопку "Reset", для ручного скидання чипу і сам пін "RST" чипу "ESP8266".
Схема пройшла випробування і реально працює. Радіймо!

Модифікація схеми

При подальшому розвитку проекту, відпала необхідність контролювати стан PIR сенсору мікроконтролером. Плюс необхідно було передбачити неможливість перезавантаження пристрою від PIR сенсору, коли пристрій "пробуджений" і працює. Схему переробив і виконав на мікросхемі дрібної логіки 74HC00 з 4-ма елементами 2І-НІ.
Схема виходу з режиму deep-sleep як від внутрішнього RTC так і від зовнішнього переривання
Коли пристрій "спить" на виході D1 немає ніякого сигналу, але вхід логічного елементу D1.3 (інвертор) підтягнуто до загального дроту і має на вході логічний нуль. Цей нуль інвертується в логічну одиницю на виході і подається на один з входів елементу D1.1. Ця одиниця виконує роль дозволу на перезавантаження пристрою як від PIR сенсору, так і по RTC (короткий імпульс логічного "0" на D0). Коли PIR сенсор спрацює і на його виході буде логічна "1", конденсатор почне заряджатись і на короткий час на іншому вході елементу D1.1 з'явиться "1". І на цей короткий час на виході елементу D1.1 з'явиться логічний "0" і NodeMCU перезавантажиться, та почне виконувати програму. Достатньо на початку програми вихід D1 плати NodeMCU встановити в високий стан (логічна "1") і маємо на виході елементу D1.3 логічний "0", який буде виконувати роль "заборони" перезавантаження поки NodeMCU працює. Тоді незалежно від того який стан на іншому вході елементу D1.1 на його виході буде постійно логічна "1". Щоб працювало пробудження по таймеру, а це короткий логічний "0" на виводі D0 плати NodeMCU, в нашому випадку, треба його інвертувати до короткої логічної "1" елементом D1.2, та через діод в прямому напрямку подати на вхід елементу D1.1, там де вже під'єднано PIR сенсор. Така собі "імітація" спрацювання PIR сенсора. Діод виконує роль елементу АБО. Функцію іншого діода виконує конденсатор. Так що коли NodeMCU "спить", то короткий імпульс логічного "0" на D0, "АБО" перепад з "0" на "1" на PIR сенсорі - пробудить пристрій.