Начало работы с Espruino: JavaScript в микроконтроллере
Лёгкий, гибкий, выразительный JavaScript может исполнять не только ваш браузер, но и микроконтроллер. Благодаря open source ядру Espruino и открытой среде программирования, вы сможете создавать сложные электронные устройства действительно просто.
Железо
Iskra JS — флагманская плата Амперки со встроенным интерпретатором JavaScript.
Построена на микроконтроллере Cortex-M4. 168 МГц, оперативная память на 5000 переменных JS, 1 МБ флеш-памяти для хранения программы.
Совместима по компоновке со стандартом Arduino Uno R3: можно использовать модули и платы расширения Arduino.
«Йодо» — набор из Iskra JS, модулей, конструктива и книги. Набор учит собирать и программировать собственные устройства на JavaScript и платформе Iskra JS. Книга включает 25 мини-проектов и необходимую теорию.
Мы выпустили три продолжения «Йодо»:
«Интернет вещей» — 7 экспериментов с WiFi, SD-картридером, мини-реле и сетевыми IFTTT, dweet.io и telegram;
Среда программирования
Espruino Web IDE — штатная среда для программирования, обновления и отладки плат Iskra JS и Espruino.
Работает на всех настольных операционных системах. Устанавливается в 2 клика.
Очередной этап сделайсама: микроконтроллеры + JS
Привет, Хабр! Сегодня мы поговорим о том, как сделать систему управления отоплением в загородном доме своими руками, используя легкодоступные микроконтроллеры и свободное ПО… причем сделать её так, чтобы можно было запрограммировать работу нужных устройств при помощи моего любимого JavaScript. Под катом — разбор трех вариантов решения этой задачи (включая тот самый, который я выбрал), а также масса рассуждений о преимуществах и недостатках данного подхода. Всех любителей сделайсамов и очумелых ручек приглашаю под кат.
Я понимаю, что в некоторых регионах зима уже подходит к концу (а в местах обитания некоторых хабрачитателей она вообще не начинается, если иметь в виду настоящую русскую зиму). Но это никак не отменяет того факта, что у каждого ИТ-шника рано или поздно возникает желание наладить удаленный мониторинг и управление отоплением (а в теории — и другими устройствами), которые работают в загородном доме.
Тут вы можете сразу же сказать, что систем управления умным домом и автоматизации интернета вещей существует великое множество. И совершенно не обязательно изобретать велосипед. Да, это так. Изобретать не обязательно, но очень хочется! К тому же для тех, кому доставляет удовольствие делать все самостоятельно, это сулит значительную экономию бюджета, а также исключительно широкие возможности самостоятельной тонкой настройки всего-чего-угодно. Так что поехали!
Постановка задачи
Есть у моего бати загородный дом. И когда он сидит зимой в своей квартире, ему хочется узнать: «а какая там температура на даче, не перемерзнет ли чего, включился ли обогреватель, когда нужно?» И чтобы сделать это, нужно как-то собирать информацию о температуре в помещении через микроконтроллер и пробрасывать все это через открытый интернет. Так можно издалека оценивать ситуацию и покидать свою уютную квартиру зимой только в случае экстренной необходимости.
В качестве основы проекта выбираем доступный микроконтроллер Arduino с модулем Wi-Fi (все-таки батин дом стоит не в глухой деревне, и интернет у нас подведен, подключение к нему относительно стабильное). Также докупаем совместимый и относительно дешевый датчик температуры/влажности DHT11. Ну и мини ЖК-экран в придачу, чтобы можно было локально вывести/посмотреть состояние в помещении («а почему бы и да», ведь можно дополнительно развлечься с настройкой сего «зоопарка»).
Решить задачу физического подключения контроллера к датчикам температуры/влажности и ЖК-дисплея достаточно несложно — просто втыкай провода в правильной последовательности и позаимствуй со стэковерфлоу какой-нибудь популярный блок кода на языке С (основной ЯП для контроллеров Arduino). Другое дело — попробовать подружить все это с языком JS, добавив возможность общения по открытой сети интернет! Задачка становится интереснее!
Приступаем к делу
Чтобы найти свое решение задачи, я выбрал знакомый мне контроллер Ardiuino Uno + Wi-Fi-модуль ESP8266, потому что с ними у меня уже был опыт базовых экспериментов с лампочками. Мы пробовали программировать как на C, так и на JS их включение/выключение, и выглядело все это очень даже неплохо. Можно сказать, воодушевило на новые эксперименты.
В качестве платформы для передачи данных я решил попробовать Yandex Cloud IoT Core MQTT Broker.
Путь для JS
Далее возникает вопрос: «Как именно добиться возможности использовать JavaScript для программирования этого контроллера и режимов его работы?» Я сознательно выбрал именно его, потому что имею более обширный опыт в данном ЯП, нежели в С, к тому же гуглинг показал, что использование JS в качестве основы является вполне рабочим решением.
Спойлер. в итоге я пришел к выводу, что лучше всё-таки использовать язык С, так как он является более «правильным» инструментом для выполнения моей задачи, но в этом случае рубрика бы не называлась «очумелые ручки» 🙂
1. Протокол Firmata + библиотека Johny-Five npm
Это неплохое решение. Реализованная на С библиотека Firmata позволяет легко общаться с контроллером через ПК. А Johny-Five — это абстракция, которая позволяет общаться с протоколом Firmata уже на JS.
Среди плюсов этого подхода — огромное количество дополнительных утилит, уже реализованная поддержка множества IoT-устройств, а также «наичистейший Node JS» в плане программирования прикладной логики на основе полученных данных от контроллера и настройки разнообразных сценариев. Короче, рай для JS-фуллстеков.
Однако есть и минусы. И самый большой из них — необходимость использовать локальное устройство-брокер для коммуникации с внешним миром, на котором и развернется NodeJS-сервер. Проще говоря, нужен какой-то мини-ПК под боком. В моем случае ничего такого в свободном доступе не нашлось. И мне пришлось просто откинуть этот вариант.
2. Espruino
Если еще не знакомы — знакомьтесь! Espruino — это целая экосистема для программирования микроконтроллеров на JavaScript. У нее, кстати, немало адептов в глобальной сети. В Espruino входит прошивка для микроконтроллеров с интерпретатором JS, а также среда разработки Espruino Web IDE. Еще в интернете можно купить платы Espruino и совместимые с ними устройства. Да и вообще вся документация доступна на www.espruino.com, заходите, не стесняйтесь.
Плюсов у решения поистине множество. В нем используется настоящий интерпретатор JS (да, с ограничениями, но незначительными). Уже создано немало библиотек для самых разных задач, имеется возможность подключения их через CommonJS.require(). Среда разработки IDE удобна и позволяет обновлять скрипты ОТА. Системой поддерживается достаточное количество устройств (хотя и не так много), но самое главное, что построенное на базе Espruino решение может работать автономно, ему не обязательно постоянное соединение с брокером-мастером (в отличие от Firmata). Кстати, стоит добавить, что в данном варианте мы используем как основной «мозг» системы не контроллер Arduino Uno, а конкретно его Wi-Fi-модуль ESP8266 (отсюда и название ESPruino). В моем случае, заказанная плата с aliexpress являлась платой 2 в 1: Arduino UNO + Wi-Fi-модуль ESP8266.
Но, как обычно, есть и подводные камни. Для нашего проекта их было два. Во-первых, нам не удалось подружить напрямую температурный сенсор DHT с ESP8266. И даже при том, что на форумах многие жаловались на эту проблему и были предприняты коллективные попытки что-то с этим сделать, побороть беду так и не вышло. Пришлось «костылить» проброс данных от Arduino UNO в ESP8266 через дополнительный провод. А во-вторых, оказалось, что соединение TLS пока что поддерживается только двумя платами (и, к сожалению, эта проблема оказалась фатальной). Наверное, ситуация скоро изменится, об этом также писали на форуме разработчики…но пока так. Яндекс Cloud IoT работает как раз через TLS, так что пускаем скупую слезу и отбрасываем Espruino тоже.
3. Mongoose OS + библиотека mJS
Это решение отличается от предыдущих и работает немного иначе. Мы устанавливаем специальную операционную систему Mongoose OS (не путать с Mongoose в Node JS для Mongo DB!) для работы с контроллерами низкого энергопотребления. А библиотека mJS позволяет использовать синтаксис JavaScript (хотя и сильно урезанный). Далее написанный код компилируется в С и загружается в Mongoose OS. Исходя из этого также имеется возможность подключать дополнительные модули-библиотеки, написанные на C и использовать их в mJS на основе абстракции интерфейсов FFI (foreign function interface).
Плюсы этого решения очевидны:
- легковесная и модульная система использует мало памяти (постоянной и оперативки);
- поддерживается TLS «из коробки»;
- имеется возможность подключать библиотеки на C и работать с ними через прослойку FFI (foreign function interface);
- кроме этого среда разработки IDE тоже очень удобна: обновления приходят «по воздуху», а автономная работа также возможна без подключения к брокеру;
- имеется удобный плагин для популярной IDE VSCode.
Есть, конечно, и минусы. Так, мне пришлось пошаманить с последней версией ОС, которая не хотела вставать на ESP8266 (в итоге взял более старую, но совместимую). Также нужно было адаптироваться к более «куцому» синтаксису mJS. В нем нет замыканий, деструктуризаций, стрелочных функций, а также базовых утилит, таких как String, Array, Object и так далее. Спасибо, правда, что не вырезали JSON. Впрочем, для базовых операций и нашей конкретной задачи «мангуст» оказался вполне съедобным.
Выбираем №3 и едем
Выбор в пользу третьего варианта с Mongoose OS был предрешен, потому что, как я уже говорил, для варианта №1 я не нашел свободного устройства-брокера и решил не переплачивать за сложности. Второй вариант отпал, потому что Yandex IoT Core поддерживает только MQTTS, что заставило отказаться от Espruino — у меня было устройство, в котором поддержка TLS отсутствовала, не покупать же новое!
На самом деле, я понимаю, что вариантов решения этой задачи существует целое множество, но мне хватило этих трех. К тому же, раз один подходит, зачем копаться дальше? В конце концов, можно было вообще отбросить «танцы с бубном» вокруг JS и использовать стандартный C напрямую. Но это явно менее прикольно!
В результате я реализовал следующую схему:
- Плата Arduino Uno (AT Mega 328P)
- работает на С (собственно, немного кода на С пришлось написать всё-таки для этой связки, но это точно не «rocket science»)
- собирает информацию с датчика DHT11,
- выводит информацию на ЖК-экран,
- отправляет данные на модуль ESP8266 по UART.
- MK ESP8266 WiFi
- работает под управлением Mongoose OS и кодом, написанном на урезанном JS,
- принимает информацию с Arduino Uno,
- отправляет данные по MQTTS в Yandex.Cloud.
Мне удалось создать MVP-прототип, реализовав:
- сбор данных на уровне датчиков и микроконтроллеров;
- подключение к сети интернет посредством Yandex Cloud IoT.
Далее, поток нескончаемых дел, к сожалению, навалился на меня и я так и не успел реализовать фронтальную часть проекта. Однако, успешная реализация «базы» показала мне, что проект вполне может быть доведен до конца. Возможно чуть позже я выпущу обновление статьи, в котором смогу представить «батин умный дом» целиком. А пока вы можете посмотреть, как выглядит микроконтроллер в рабочем состоянии на этом видео.
Спасибо за внимание и до новых встреч! Буду очень рад вашим комментариям.