ESP8266 NodeMCU Прошивка. Робимо WiFi розетку

Содержание

Популярність WiFi-модулів на базі ESP8266 на стільки велика, що крім прошивок для використання ESP8266 у якості WiFi-модуля під керуванням зовнішнього мікроконтролера, існує безліч прошивок для використання його і як мікроконтролера з різними цільовими призначеннями, у тому числі і в сфері Інтернет речей. У цьому циклі статей ми будемо вивчати можливості ESP8266 з прошивкою NodeMCU і познайомимось з мовою програмування LUA.

Що таке ESP8266?

ESP8266 — це мікроконтролер з WiFi інтерфейсом. Його можна використовувати як WiFi модуль, і як мікроконтролер.

Плюси ESP8266: WiFi інтерфейс, 32-розрядний ядро з достатньою продуктивністю, низька ціна.

Мінуси: у порівнянні з іншими 32-розрядними мікроконтролерами досить проста периферія.

ESP8266 ідеально підходить для домашніх проектів та Інтернету речей. ESP8266 програмується через послідовний порт UART, тому для його прошивки не потрібно спеціального програматора. Особливість цього мікроконтролера у тому, що він може виконувати програму, розташовану на зовнішній Flash пам`яті. Це дозволяє виробникові збільшувати обсяг Флеша, що також є плюсом. На базі ESP8266 випускаються різні модулі:

ESP-01
ESP-02
ESP-03
ESP-04
ESP-05
ESP-06
ESP-07
ESP-08
ESP-09
ESP-10
ESP-11
ESP-12S
ESP-12E
ESP-12F

Існують різні версії плат з запаяними модулями ESP8266, стабілізаторами напруги, мікросхемою для забезпечення роботи послідовного порту UART через USB, з розведеними на роз`єми виводами, кнопками тощо. Для роботи з такими платам досить підключити їх до USB порту комп`ютера. Ніякого додаткового обладнання не потрібно. Це дуже зручно. Одні з таких плати — NodeMCU. У прикладах я буду використовувати плату NodeMCU з модулем ESP-12F. Але, Ви цілком можете взяти модуль, скажімо ESP-01, підключити до нього UART-USB перехідник і працювати з ним аналогічним чином. ESP-01 має менше пам`яті і менше виходів, які можна задіяти, але в іншому робота з ним аналогічна.

Що таке NodeMCU?

NodeMCU — відкритий безкоштовний проект на основі скриптової мови програмування Lua. Прошивка досить потужна і дозволяє дуже швидко і просто реалізовувати різні типові проекти. Наприклад, сьогодні, за для знайомства з NodeMCU, ми зробимо WiFi розетку з керуванням з мобільного телефону та з Web-інтерфейсом. Прошивка вміє виконувати Lua-скрипти як з послідовного UART порту (аналогічно AT-командам) так і з внутрішньої flash пам`яті (виконуючи скрипти). Lua скрипти зберігаються у Flash у внутрішній файловій системі. Файлова система плоска, спрощена. Тобто без підкаталогів. Проте — це круто. Варто пам`ятати, що ESP8266 — це тільки мікроконтролер. Скриптами можна отримати доступ до власних файлів, читати і зберігати різну інформацію. NodeMCU модульна. Що з одного боку дозволяє нарощувати функціонал, а з іншого зібрати прошивку тільки з необхідних модулів і не витрачаючи даремно пам`ять.

NodeMCU працює з протоколами обміну даних — HTTP, MQTT, JSON, CoAP.

Підтримуються різні датчики: акселерометри ADXL345, магнітометр HMC5883L, гіроскопи L3G4200D, датчики температури і вологості AM2320, DHT11, DHT21, DHT22, DHT33, DHT44 датчики температури, вологості, атмосферного тиску BME280, датчики температури, атмосферного тиску BMP085, багато дисплеїв, які працюють по шинам I2C, SPI. З можливістю роботи з різними шрифтами. TFT дисплеї ILI9163, ILI9341, PCF8833, SEPS225, SSD1331, SSD1351, ST7735, розумні світлодіоди і LED контролери — WS2812, tm1829, WS2801, WS2812, підтримуються інтерфейси — 1-Wire, I2C, SPI, UART. Також можна задіяти модуль шифрування, планувальник завдань, годинник реального часу, протокол синхронізації часу через Інтернет SNTP, таймери, АЦП канал (один), формувати на виходах ШІМ-сигнал (до 6), використовувати сокети, є підтримка FatFS, тобто можна підключати SD-картки.

Що таке мова Lua?

Де скачати NodeMCU?

Звичайно, можна скачати код NodeMCU (https://github.com/nodemcu/nodemcu-firmware/releases/) і скомпілювати з потрібними параметрами. Але ми не буде так робити. Існує сайт https://nodemcu-build.com, на якому можна зібрати NodeMCU з необхідними Вам модулями. Ви просто відзначаєте ті модулі, які Вам потрібно, вказуєте свій e-mail і натискаєте внизу кнопку "Start ysour build". Спочатку на вказаний e-mail приходить лист, який інформує Вас що збірка почалася. Через декілька хвилин прийде повідомлення про закінчення збірки з посиланнями для скачування integer і float версій. Якщо в своєму проекті Ви не збираєтесь використовувати обчислення з плаваючою комою, тоді качайте "integer". Не варто включати ті модулі, які Ви не плануєте використовувати. У будь-який момент можна зібрати нову прошивку додавши відсутній модуль. Для прикладів я зібрав NodeMCU з наступними модулями:

Як залити NodeMCU на ESP8266?

Тепер, коли ми маємо файл прошивки NodeMCU, його потрібно залити до ESP8266. Перш за все, при підключенні плати NodeMCU до комп`ютера, повинен з`явитися віртуальний Com порт. Як правило, останні версії Windows не вимагають встановлення додаткових драйверів. Ubuntu відразу розпізнає підключений пристрій.

Прошивка NodeMCU під Windows

Заходимо за цим посиланням: https://github.com/nodemcu/nodemcu-flasher. З папки Win32/Release (для 32-бітної Windows), або з папки Win64/Release (для 64-бітної Windows) качаємо файл ESP8266Flasher.exe. Ця програма не вимагає інсталяції. Просто запускаємо її. Переходимо до вкладки "Config", натискаємо "шестірню" щоб вибрати файл прошивки.

Повертаємося до вкладки "Operation", вказуємо порт, і натискаємо кнопку "Flash".

Після натискання "Flash" маємо побачити МАС-адреси і приблизно таку картину.

Чекаємо поки прошивка закінчиться. У нижньому кутку має з`явитися зелена галочка.

Після цього потрібно вимкнути і знову ввімкнути ESP8266. Прошивка закінчена.

Якщо після натискання кнопки "Flash" процес прошивки не почався (не з`явилися МАС-адреси), натисніть кнопку "reset" на платі і спробуйте ще раз.

Прошивка NodeMCU під Ubuntu

/Dev/ttyUSB0 — порт на якому висить ESP8266.

The_Path_To_The_NodeMCU_Firmware.bin — шлях до файлу прошивки.

До речі, esptool можна використовувати і під Windows. esptool написаний на Pyton, для роботи під Windows потрібно встановити Pyton.

esptool стане у нагоді для заливки бінарних файлів на файлову систему NodeMCU. Можна заливати будь-які файли в тому числі скрипти. Скрипти можна писати хоч і в Notepad, але я віддаю перевагу ESPlorer.

ESPlorer, init.lua — пишемо перший скрипт

Для написання і заливки скриптів будемо використовувати програму ESPlorer. Це програма написана на Java. Працює так само як під Windows так і під Ubuntu.

Під Windows запускаємо файл ESPlorer.bat

Примітка: далі описана робота з ESPlorer v0.1. Зовнішній вигляд нових версій може мати не принципові відмінності. Вказуємо порт і швидкістю 9600:

І натискаємо "Open". побачимо наступне

У ESPlorer виявилася погана особливість. Він не завжди чітко підключається до NodeMCU. Якщо спробувати надіслати будь-яку команду (кнопкою Send) в консолі пролітає сміття замість нормальної відповіді. Іноді, після декількох повторів все налагоджується. Якщо це Вас турбує, спробуйте поміняти швидкість підключення на 115200.

Створимо перший скрипт на мові Lua. Скрипт з ім`ям init.lua стартує автоматично після запуску NodeMCU. Створимо файл init.lua.

Надрукуємо всього один рядок:

Зберігаємо файл init.lua. Після збереження файл запускається і ми маємо побачити роботу скрипта.

Файл зберігається на диск комп`ютера і заливається на ESP8266.

Тепер про найбільшу неприємності, яка є у NodeMCU. При деяких критичних помилках (це трапляється не так часто, але якщо трапляється, то запам`ятовується на довго) NodeMCU може перезавантажуватися. І найстрашніше що може статися — це циклічне перезавантаження. Це трапляється, якщо допустити критичну помилку в скрипті, який стартує автоматично. NodeMCU стартує, виконує "глючний" скрипт, наривається на критичну помилку і перезавантажується. І так до нескінченності.

Для того, щоб убезпечити себе на етапі вивчення NodeMCU, я використовую описаний нижче прийом. У стартовому скрипті init.lua запускаємо таймер, який спрацює тільки один раз і через зазначений час (в даному випадку через 5 секунд) виконає процедуру запуску іншого скрипта (в даному випадку main.lua). Більше нічого в скрипті init.lua не робимо. Всі операції виконуються в скрипті main.lua. Таким чином, якщо ми допустимо помилку в скрипті main.lua, і NodeMCU піде у циклічне перезавантаження, після перезавантаження у нас буде 5 секунд для того щоб видалити або виправити "глючний" скрипт.

Крім того, такий підхід дозволяє легко включати в автозавантаження любий скрипт, достатньо в файлі init.lua замість main.lua вказати ім`я іншого скрипта. Це дуже зручно коли ви на одній платі тестуєте кілька проектів або кілька версій скрипта.

Підключаємося до Wifi або створюємо свою Wifi точку

Для підключення до WiFi створюємо main.lua і пишемо:

Після успішного підключення модуль отримає IP адресу. Дізнатися її можна за допомогою команди:

Якщо ми хочемо щоб ESP8266 створив свою власну WiFi точку доступу:

Примітка: WiFi не підіймається якщо пароль коротше 8 символів. IP адреса точки, зазвичай 192.168.4.1

IP адресу можна дізнатися командою:

Що таке collectgarbage()? Функція collectgarbage — це збирач сміття. Її слід викликати в кінці кожного скрипта. Зверніть увагу, змінна cfg оголошена як local. Вона буде доступна тільки в поточному скрипті. Якщо local прибрати, то змінна cfg була б глобальної і доступною в інших скриптах.

GPIO. Блимаємо світлодіодом

Для управління реле (пам`ятаєте, ми зібралися робити WiFi розетку) буде потрібно вивчити роботу з GPIO. Поки спробуємо використовувати GPIO у якості виходу і встановлювати високий і низький рівень сигналу. Підключимо світлодіод як показано на схемі.

IO index ESP8266 pin
0 GPIO16
1 GPIO5
2 GPIO4
3 GPIO0
4 GPIO2
5 GPIO14
6 GPIO12
7 GPIO13
8 GPIO15
9 GPIO3
10 GPIO1
11 GPIO9
12 GPIO10

D0(GPIO16) can only be used as gpio read/write. No support for open-drain/interrupt/pwm/i2c/ow

Примітка: Існує кілька версій плат Nodemcu. Призначення виводів Вашої плати може відрізнятися від зазначеної схеми.

Websocket

Тепер зробимо сервер, котрий буде працювати на зазначеному порту (нехай буде 333). Потім ми за допомогою термінальної програми підключимось до нашого сервера, вказавши його IP, порт і будемо пересилати данні. Скрипт main.lua:

Наш скрипт піднімає Wi-Fi точку, створює сервер, який на порту 333 очікує підключення. У момент підключення сервер відправить клієнту "Hello!", а прийнявши від клієнта дані поверне йому рядок "Recived:" і далі все що він прийняв. Можемо підключитися мобільним телефоном до Wi-Fi точки, яку створив ESP8266. В принципі, створювати точку не обов`язково. Ви можете переписати скрипт і зробити так, щоб ESP8266 підключався до Вашої WiFi мережі. Тоді Вам потрібно дізнатися його IP-адресу, і далі використовувати цю адресу замість 192.168.4.1, яка використовується у прикладі. Але ще потрібна термінальна програма для підключення на IP адресу ESP8266 (192.168.4.1) і зазначений порт (333). На звичайному комп`ютері можна встановити PuTTY. Для мобільних телефонів під Android я використовую JuiceSSH.

Передача даних з мобільного телефону за допомогою JuiceSSH

Встановимо JuiceSSH і створимо підключення на IP 192.168.4.1, порт 333.

Відразу після підключення повинні побачити таку картину:

Відправимо йому радісне "Yes" і повинні отримати відповідь.

Тепер доопрацюємо скрипт таким чином, щоб отримавши "1", ESP8266 вмикав світлодіод, а отримавши "0" — вимикав.

Допрацьована версія скрипта main.lua:

Спробуйте відправити "1" і "0". Світлодіод має загорятися і гаснути. Зрозуміло, вмикати світлодіод через термінальну програму дуже не зручно. Але в подальшому саме термінальна програма зможе Вам допомогти налагоджувати більш складні проекти.

Робота з RoboRemoFree

У Інтернеті можна знайти багато програм під Android, які допомагають не вдаючись до програмування, організувати інтерфейс для такого роду задач. Я покажу як це можна зробити за допомогою RoboRemoFree. Встановлюємо і запускаємо RoboRemoFree

Створюємо підключення до сервера. Бажано щоб мобільний телефон/планшет був підключений до тієї WiFi мережі, де знаходитися сервер. Заходимо в "menu", вибираємо пункт "connect".

Обираємо підключення "Internet (TCP)"

Вказуємо IP і порт

Далі в меню обираємо пункт "interface"

Обираємо інтерфейс. Програма дозволяє створювати кілька інтерфейсів.

Потім переходимо у режим редагування інтерфейсу

Натискаємо на вільному просторі і обираємо що ми хочемо встановити. Ми будемо використовувати кнопки. Обираємо "button".

Після чого на інтерфейс буде встановлена кнопка. Її можна пересувати і змінювати її розміри.

Щоб змінити напис, потрібно натиснути на ній і виконати "Set text"

Потім вкажемо ще один параметр — "set press action". Задамо "1". При натисканні кнопки буде відправлятися зазначений рядок до створеного нами підключення. Тобто, наш ESP8266 отримає символ "1" і ввімкне світлодіод.

Аналогічно створимо кнопку "Off" і встановимо set press action "0".

Наш інтерфейс готовий. Виходимо з режиму редагування, виконавши пункт меню "do not edit ui".

Якщо з`єднання із сервером (ESP8266) було успішним, можна користуватися. При натисканні кнопки "On" світлодіод повинен загорітися, після натискання кнопки "Off" світлодіод повинен згаснути.

Web інтерфейс

Існує інший шлях — можна зробити Web інтерфейс і керувати світлодіодом ще й через браузер.

Той самий скрипт + Web інтерфейс:

Невеличке пояснення як працює web-сервер взагалі, і наш скрипт зокрема. Стандартний порт для web-сервера — 80. Тобто, коли Ви в браузері набираєте http://192.168.4.1/, браузер підключається до сервера (192.168.4.1) на порт 80 і відправляє запит. Запит виглядає приблизно так:

Нас цікавить перший рядок запиту: "GET / HTTP/1.1". У ньому вказано URL. Якщо в браузера набрати http://192.168.4.1/on, тоді у першому рядку запиту буде "GET /on HTTP/1.1". А якщо у браузері набрати http://192.168.4.1/off тоді буде "GET /off HTTP/1.1". Саме цей рядок і аналізує скрипт і в залежності від отриманого URL вмикає або вимикає світлодіод. Далі скрипт відправляє html сторінку. Після відправки потрібно розірвати підключення. Оскільки відправка займає деякий час, а чекати закінчення відправки технічно нерозумно, на подію "sent" (відправлено) підключимо функцію з рядком sck:close(). Це робиться в рядку: sck:on("sent", function(sck) sck:close() end) після чого виконується відправка html сторінки: sck:send(response). Cкрипт продовжує роботу. Коли відповідь буде відправлено, спрацює sck:close().

Забігаючи на перед скажу, що великого розміру сторінки таким чином відправити не вийде. Вагомий вміст потрібно відправляти шматочками. Детальніше про це буде у іншій статті.

Підключаємо реле з навантаженням

Увага! Напруга понад 40 Вольт небезпечна для життя людини! Будьте уважні і акуратні, збираючи схему і підключаючи побутові прилади. Не торкайтеся до струмоведучих частин. Тепер замість світлодіода підключимо модуль реле, а в якості навантаження — лампу, обігрівач, компресор для акваріума, вентилятор і таке інше.

При підключенні реле можуть бути нюанси. Якщо блок реле з оптичною розв`язкою (з оптопарою), швидше за все, Вам нічого переробляти не доведеться. Якщо блок реле без оптичної розв`язки, як у мене, тоді доведеться переробити роботу з GPIO, оскільки по-перше на такому модулі реле вмикається низьким рівнем, а не високим, а по-друге високий рівень ESP8266 — це 3.3В, для 5-ти вольтового блоку реле цього не достатньо, тому мені довелося налаштувати вихід як OPENDRAIN, після чого все запрацювало як треба.

Фінальна версія скрипта виглядає так:

Тепер ми можемо вмикати і вимикати "розетку" з мобільного телефону за допомогою програми RoboRemoFree або за допомогою браузера. Зрозуміло, зі звичайного комп`ютера через браузер теж можна керувати.

Все це добре, але що далі? Якщо у нас буде 5, 10, 20 подібних пристроїв? Як їх об`єднати щоб не треба було підключатися до кожного пристрою окремо. Для цього існує протокол MQTT, але це буде окрема тема. А поки ми вивчимо можливості ESP8266 і NodeMCU.

Деякі правила роботи з Lua на NodeMCU

1. Не пишіть довгі скрипти. Намагайтеся щоб вони були завдовжки не більше 100 рядків. Розмір пам`яті ESP8266 не нескінченний. Розбивайте програму на функціональні модулі і робіть їх у вигляді окремих скриптів, запускаючи їх за допомогою dofile(). Наприклад, код підключення до Wifi:

можна винести в окремий скрипт "wifi.lua" і виконати його з основного скрипта командою dofile("wifi.lua").

2. Змінні, які використовуються тільки в поточному скрипті оголошуйте як local. В кінці скрипта, коли змінна вже не потрібна, надавайте їй значення nil і явно викликайте збирач сміття collectgarbage()

Забігаючи на перед скажу, що великого розміру сторінки таким чином відправити не вийде. Вагомий вміст потрібно відправляти шматочками. Детальніше про це буде у іншій статті.


Источник: blog.avislab.com