Огляд C-модулів у складі прошивки NodeMCU з LUA. Частина 1

Ви читаєте першу частину публікації, що присвячено огляду модулів прошивки NodeMCU. У цій частині ми розглянемо типи модулів і їх класифікацію.

Станом на травень 2020 року маємо майстер-версію 3.0-master_20190907 прошивки NodeMCU.

Багато хто сприймає модуль ESP8266-12 та плату NodeMCU на базі однойменного чіпу, як лише WiFi модем, тобто лише як доповнення до широко розкручених і популярних платформ Arduino / STM32 та інших подібних наборів розробки розумних пристроїв.

Але, як ви могли помітити, до прикладу, вивчаючи наш сайт, платформа ESP8266 з прошивкою NodeMCU та мовою Lua має надзвичайно широкі можливості як самодостатня система побудови пристроїв у сфері інтернету речей.

До екосистеми прошивки версії 3.0 входить наступний перелік модулів, які на вибір розробника, може бути включено у двійковий файл:

C-модулі:

adc, ads1115, adxl345, am2320, apa102, bit, bloom, bme280, bme680, bmp085, coap, color_utils, cron, crypto, dht, encoder, enduser_setup, file, gdbstub, gpio, hdc1080, hmc5883l, http, hx711, i2c, l3g4200d, mcp4725, mdns, mqtt, net, node, ow, pcm, perf, pwm, pwm2, rc, rfswitch, rotary, rtcfifo, rtcmem, rtctime, si7021, sigma_delta, sjson, sntp, somfy, spi, sqlite3, struct, switec, tcs34725, tls, tm1829, tmr, tsl2561, u8g2, uart, ucg, websocket, wifi, wifi_monitor, wps, ws2801, ws2812, ws2812_effects, xpt2046

Lua-модулі:

bh1750, ds18b20, ds3231, fifo, fifosock, ftpserver, hdc1000, imap, lm92, mp23008, redis, yeelink

Вбудовані модулі, Lua у тому числі:

string, math, table, package.

Примітка 1. Перелік наявних релізів прошивки можна переглянути тут: 3.0-master_20190907

Примітка 2. Актуальна документація для майстер версії релізу прошивки знаходиться тут: NodeMCU Documentation

Примітка 3. Актуальна документація на мову Lua, яку вбудовано до складу NodeMCU, варто читати на офіційному сайті для версії мови 5.1:

Примітка 4. Актуальну документацію виробника мікроконтролера ESP8266EX, рекомендуємо отримувати на сайті компанії Espressif. Оскільки у цій публікації йдеться про версію прошивки 3.0, то і SDK потрібно обирати з відповідним номером версії. Нас цікавить ESP8266 Non-OS SDK 3.0 API Reference: ESP8266 Non-OS SDK API Reference ( V3.0.1 2019.03.20 )

Або ж можна спробувати пряме посилання(може не працювати з часом):

За нашими спостереженнями, дуже багато новачків губиться у цих та подібних списках і щонайменше не знають з чого починати своє теоретичне навчання та практичні експерименти з NodeMCU. І навіть ті з нас, хто вже знає і програмує на Lua, мають також знати про деякі особливості, коли йдеться про вбудований варіант цієї чудової мови.

Тому дозвольте трошки допомогти і спробувати пояснити нюанси, пов’язані з NodeMCU, про які варто знати і всіляко застосовувати.

Почнемо з того, що таке C-модулі. Справа у тому, що з середовища Lua, розробник не має доступу до API Non-OS SDK виробника мікроконтролера, на якому базується прошивка NodeMCU. І саме для того, щоб забезпечити інтерфейс для викликів необхідних функцій з рівня Lua, спільнота розробила спеціальні інтерфейсні C-модулі, викликаючи котрі ми викликаємо функції ESP8266 Non-OS SDK, котрі в свою чергу вже мають реальний доступ до апаратного забезпечення чіпа ESP8266EX.

Втім, так відбувається не завжди, а лише у загальносистемних випадках. Ми можемо навести приклади, коли взаємодія з залізом відбувається майже безпосередньо з рівня Lua. Наприклад, коли ми звертаємося до підпорядкованих пристроїв, що працюють на шині I2C. Тобто можна бачити, що за деяких обставин, особливо коли йдеться про зовнішні (по відношенню до чіпа ESP8266EX та його обов’язки у вигляді мікросхеми flash-пам’яті) апаратні ресурси, цілком можливо програмувати їх з прямим доступом до апаратного рівня засобами мови Lua (але теж через наявні C-модулі, наприклад i2c). Сама по собі мова є лише одним з C-модулів, що глибоко і якісно інтегровано до прошивки.

Саме тому ми бачимо у документації, що користувач-розробник, окрім C-модулів інтерфейсу з SDK, має доступ до модулів мови Lua, а також модулів, що є скриптами, написаними на Lua.

Для зручності розробника, спільнотою всі ці варіанти викликів поєднано у єдиний формат типу module.method().

Приклади:

  1. node.info() — виклик опціонального C-модуля, який має доступ до низькорівневих функцій SDK;
  2. math.floor() — виклик вбудованого C-модуля, який реалізує математичну функцію, як частина мови Lua;
  3. ds3231.init() — виклик опціонального Lua-модуля (скрипта ds3231.lua), який виконується в середовищі NodeMCU як повноцінна бібліотека.

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

Але чого докладно не пояснює документація прошивки NodeMCU, так це як до цього всього відноситься мова Lua. Є лише посилання на мову та її версію, що підтримується.

Тому ми вважаємо за потрібне навести приклади викликів модулів з мови Lua:

  1. print(node.info()) — оператор print() виводить в консоль результати виклику метода info модуля node.
  2. print(math.floor(2.3)) — оператор print() виводить в консоль результати виклику округлення засобами методу floor() вбудованого модуля math. Зверніть увагу, що ніде не буде написано, що модуль math є у прошивці, але він є.
  3. if ds3231.init() then print (‘RTC Init Ok’) else print (‘RTC Init error’) end — в даному прикладі виконуючи порівняння типу <if ds3231.init() == true> ми автоматично запускаємо на виконання метод init() модуля ds3231. І саме за результатами успішності його відпрацювання отримуємо true для конструкції if …then.

Як можна бачити, всі ці модулі в прикладах викликаються з однаковим синтаксисом і можливостями з рівня мови програмування Lua напряму.

Після означення що ж таке C-модулі, тепер ми можемо перейти до огляду їх призначення у прошивці.

Здавалося б, навіщо взагалі задаватися запитанням що роблять модулі. Коли вони будуть нам потрібні, тоді і взнаємо. Так то воно так, але є декілька але.

По-перше, варто мати загальне уявлення про можливості платформи. Від цього залежить наше розуміння що ж ми можемо побудувати:

  • Чи зможемо ми побудувати надійний, функціональний – комерційний продукт?
  • Чи зможемо ми підключити пристрої замовника чи інші електронні компоненти відповідно до власного задуму?
  • Чи здатна платформа відповідати на сучасні технологічні виклики і вимоги користувачів?
  • Чи варто нам вчити Lua і NodeMCU, а може краще взяти іншу прошивку з мовою, яку ми вже знаємо?

Таких питань може бути багато і тому радимо хоча б поверхнево осягнути все розмаїття можливостей. І як наслідок, мати можливість порівняти з можливостями інших платформ.

По-друге, C-модулів, що розроблено для прошивки багато і всі вони не можуть вміститися у один бінарний файл прошивки. Пам’ятаєте? – ми маємо справу з мікроконтролером, а не з сервером і навіть не з ПК. Використовуючи зручний онлайн сервіс зі створення прошивок nodemcu-build.com, ви можете самостійно переконатися, що всі модулі підключити просто неможливо. Цей сервіс дозволяє підключити близько двадцяти модулів одночасно. Цьому обмеженню є цілком логічне пояснення – з одного боку розмір (читай ланцюжок залежностей, тобто dependency) кожного модуля впливає на розмір двійкового файлу для заливки у контролер, з іншого боку, у контролері є обмежений об’єм простору призначений для прошивки.

По-третє, кожен доданий модуль впливає не лише на розмір бінарника прошивки, а і на об’єм доступної для виконання скриптів оперативної пам’яті контролера. Все відбувається навіть складніше, втім не будемо тут заглиблюватися у деталі. Просто уявіть, для прикладу, що наявність підтримки SSL/TLS у прошивці, чи режим debug, або ж підтримка графічною бібліотекою більшої кількості шрифтів – одразу потягне за собою зменшення кількості доступної оперативної пам’яті для ваших скриптів.

Виходячи з трьох попередніх пунктів, розробник архітектури та відповідного програмного і апаратного забезпечення, має свідомо побудувати збалансовану прошивку, що чітко відповідає потребам проекту.

Спільнота розробників, що розвиває програмну платформу NodeMCU, ніяк не класифікує модулі прошивки, крім звісно, явних їх відмінностей: C- / Lua-.

Таблиця 1. Класифікація модулів NodeMCU за документацією

generic C-modulesgeneric Lua-modules

Тож, маємо C-модулі і Lua-модулі, які в релізах прошивки іменуються generic модулями (ми б Lua- модулі так не називали, але нехай). C-модулі прошиваються, Lua-модулі скачуються з Github і заливаються через термінал консолі після прошивки. Але ті й інші модулі, як правило, можливо і бажано класифікувати для себе. Запропонованої нам класифікації явно недостатньо для тих, хто починає працювати з платформою і зі сферою інтернету речей. Наявна класифікація, швидше є властивістю/ознакою (.property), як тип файлу у файлових системах. А нам потрібно розібратися у доменах сфер застосування мікроконтролера, щоб вправно цим користуватися у майбутньому.

У документації на generic модулі цього явно не вказано, але є важлива ознака, за якою можливо класифікувати усі наявні модулі (як C-, так і Lua-):

Таблиця 2. Найпростіша класифікація

Модулі які потребують лише ESP8266Модулі для зовнішніх пристроїв

Прикладом модуля, що потребує лише мікроконтролера ESP8266 може бути C-модуль wifi., чи Lua-модуль fifo. І навпроти, модулем, що призначено для роботи із зовнішніми (периферійними) пристроями, може бути C-модуль adc1115., чи Lua-модуль ds18b20.

Наведемо розподіл за цим принципом:

достатньо лише модуля чи плати на базі ESP8266EX з прошивкою NodeMCUпотрібен периферійний електронний компонент
adc, node, bit, bloom, coap, color_utils, cron, crypto, gpio, encoder, enduser_setup, file, gdbstub, http, mdns, mqtt, net, pcm, perf, pwm, pwm2, rtcfifo, rtcmem, rtctime, sigma_delta, sjson, sntp, sqlite3, struct, tls, tmr, websocket, wifi, wifi_monitor, wps. fifo, fifosock, ftpserver, imap, redis, yeelink. math, string, table, package.ads1115, adxl345, am2320, apa102, bme280, bme680, bmp085, dht, hdc1080, hmc5883l, hx711, i2c, l3g4200d, mcp4725, ow, rc, rfswitch, rotary, si7021, somfy, spi, switec, tcs34725, tm1829, tsl2561, u8g2, uart, ucg, ws2801, ws2812, ws2812_effects, xpt2046. bh1750, ds18b20, ds3231, hdc1000, lm92, mp23008.

Такого поділу вже достатньо для того, щоб запланувати навчання чи побудову проектів. Є маса проектів які можливо побудувати лише застосовуючи внутрішні можливості платформи. З іншого боку, знаючи, якими драйверами для зовнішніх пристроїв є можливість користуватися, ми можемо планувати їх придбання у магазинах електроніки.

Ми ж намагаємося застосовувати свій багаторічний досвід роботи з NodeMCU і рекомендуємо щонайменше наступний поділ:

  • системні компоненти (system components);
  • інтерфейс користувача (user interface);
  • сенсори (sensors);
  • виконавчі механізми (actuators).

Системні компоненти працюють десь “під капотом” і роблять роботу єдиної системи можливою.

Серед системних компонентів і керування живленням, і обробка подій, і організація сховища даних, і обробка переривань, і ввід-вивід, і змінні оточення, і зв’язок, а також багато інших компонентів: перетворення та обчислення; передача даних; календар; керування пам’яттю; виклики функцій; планувальник завдань; мережна взаємодія; безпека і захист; керування модулями. Абсолютно всі ці компоненти є у будь-якого сучасного пристрою.

Компоненти інтерфейсу користувача дають змогу керувати пристроєм, отримувати та вводити дані.

Серед компонентів інтерфейсу користувача можливо виокремити три великих категорії:

  • “локальне керування” з кнопками, клавіатурами, потенціометрами, енкодерами, перемикачами, розпізнавачами жестів, біометричними зчитувачами.
  • “локальна індикація та сигналізація” з світлодіодами, драйверами світлодіодів, зумерами.
  • а також “візуалізація” зі світлодіодними стрічками, світлодіодними матрицями, дисплеями.

Сенсори – самобутня і величезна категорія компонентів, що надає можливість вимірювати фізичні величини, проводити перетворення і обчислення даних, обробляти пов’язані події, забезпечувати зворотній зв’язок у вигляді коригування чутливості, точності і швидкодії вимірювальної системи.

Серед сенсорів можливо застосувати багато різноманітних класифікацій, але на наш погляд це щонайменше наступні підкатегорії:

  • аналогові сенсори;
  • цифрові сенсори;
  • синтетичні сенсори;
  • аналогово-цифрові перетворювачі;
  • дискретні розширювачі портів вводу-виводу у режимі входу.

Виконавчі механізми – якраз через ці компоненти відбувається вся магія безпосереднього керування власними функціональними блоками пристрою, або підпорядкованими машинами і механізмами, що є зовнішніми по відношенню до. Без виконавчих механізмів, що на заході ще називають актуаторами (actuators), майже ніколи не буває сучасних пристроїв. Є звісно виключення і їх теж багато – але це вже залежить від архітектури і вимог та підходів розробника щодо вирішення поставленої задачі.

Посеред виконавчих механізмів ми зазвичай виокремлюємо:

  • реле;
  • двигуни;
  • магнітні пускачі;
  • клапани і задвижки;
  • цифро-аналогові перетворювачі (PWM);
  • дискретні розширювачі портів вводу-виводу у режимі виходу.

Але завжди пам’ятаємо, що “палиця має два кінці” і здається, що самий головний (очима програміста) виконавчий механізм будь-якого контролера – локальний порт GPIO мікроконтролера, налаштований на дискретний режим роботи у якості виходу, чи вихід ЦАП у режимі PWM (ШІМ). Іноді цього рівня абстракції дійсно достатньо, але у більшості випадків потрібно достеменно знати виконавчий механізм, враховувати протокол керування ним, а можливо і самостійно написати відповідний драйвер на Lua.

Якщо ви звернули увагу, продукти нашого магазину програмного забезпечення, розподілено саме на такі категорії. Продукти що ми розробляємо і пропонуємо Клієнту, добре вкладаються у таку структуру, як і загальнодоступні модулі платформи NodeMCU.

Тепер пропонуємо виконати розподіл модулів NodeMCU на категорії, що ми так старанно описали вище.

Таблиця 3. Запропонована класифікація верхнього рівня

system componentsuser interfacesensorsactuators
node
bit
bloom
coap
color_utils
cron crypto encoder
enduser_setup
file
gdbstub
gpio
http
i2c
mdns
mqtt
net
ow
perf
rtcfifo
rtcmem
rtctime
sjson
sntp
spi
sqlite3
struct
tls
tmr
uart
websocket
wifi
wifi_monitor
apa102
pcm
rotary
tm1829
u8g2
ucg
ws2801
ws2812 ws2812_effects
xpt2046 wps
adc
ads1115
adxl345
am2320
bme280
bme680
bmp085
dht
hdc1080
hmc5883l
hx711
l3g4200d
mcp4725
si7021
tcs34725
tsl2561
pwm
pwm2
rc
rfswitch
sigma_delta
somfy
switec

У цій (першій) частині ми розглянули типи модулів платформи та можливі їх класифікації.

У наступній частині ми розберемо призначення ключових модулів прошивки NodeMCU.

Дякуємо за увагу і бажаємо успіхів!