Визуальное программирование для Sonoff Basic

image
Статья о том, как из дешёвого китайского устройства создать программируемый логический контроллер. Такое устройство найдёт своё применение как в домашней автоматизации, так и в качестве практических занятий по школьной информатике.
Для справки, по умолчанию программа Sonoff Basic работает с мобильным приложением через китайский облачный сервис, после предлагаемой переделки, всё дальнейшее взаимодействие с этим устройством станет возможным в браузере.

Раздел I. Подключение Sonoff к сервису MGT24


Шаг 1. Создание панели управления


Зарегистрируйтесь на сайте mgt24 (если ещё не зарегистрированы) и войдите в систему под своей учётной записью.

Вход в систему
image


Чтобы создать панель управления для нового устройства нажмите на кнопку »+».

Пример создания панели
image


После того, как панель будет создана, она появится в списке ваших панелей.

Во вкладке «Установка», созданной панели, найдите поля «ID устройства» и «Ключ авторизации», в дальнейшем, эта информация потребуется при настройки Sonoff устройства.

Пример вкладки
image

Шаг 2. Перепрошивка устройства


С помощью утилиты XTCOM_UTIL загрузите прошивку ПЛК Sonoff Basic в устройство, для этого вам понадобиться USB-TTL конвертер. Здесь инструкция и видеоинструкция.

Шаг 3. Настройка устройства


Подайте на устройство питание, после того как загорится светодиод, нажмите на кнопку и удерживайте её в нажатом состоянии до тех пор, пока светодиод не начнёт периодически равномерно мигать.
В этот момент появится новая wi-fi сеть с названием «PLC Sonoff Basic», подключите свой компьютер к этой сети.

Расшифровка светодиодной индикации


Откройте интернет-браузер и введите в адресную строку текст »192.168.4.1», перейдите на страницу настроек параметров сети устройства.

Заполните поля следующим образом:

  • «Имя сети» и «Пароль» (для привязки устройства к домашнему wi-fi роутеру).
  • «ID устройства» и «Ключ авторизации» (для авторизации устройства на сервисе MGT24).


Пример настройки параметров сети устройства
image


Сохраните настройки и перезагрузите устройство.
Здесь видеоинструкция.

Шаг 4. Подключение датчиков (опционально)


Текущая прошивка поддерживает до четырёх датчиков температуры ds18b20. Здесь видеоинструкция по монтажу датчиков. По всей видимости, это шаг будет самым непростым, так как потребует от вас прямых рук и паяльника.

Раздел II. Визуальное программирование


Шаг 1. Создание сценариев


В качестве среды программирования используется Blockly, среда проста в освоении, поэтому для создания простых сценариев не нужно быть программистом.

Я добавил специализированные блоки для записи и чтения параметров устройства. Доступ к любому параметру осуществляется по имени. Для параметров удалённых устройств используются составные имена: «параметр@устройство».

Выпадающий список параметров
image

Пример сценария циклического включения и выключения нагрузки (1Гц):
image

Пример сценария синхронизирующего работу двух отдельных устройств. А именно, реле целевого устройства повторяет работу реле удалённого устройства.
image

Сценарий для термостата (без гистерезиса):
image

Чтобы создавать более сложные сценарии можно использовать переменные, циклы, функции (с аргументами) и прочие конструкции. Не буду здесь всё это расписывать подробно, в сети уже есть довольно много обучающего материала о Blockly.

Шаг 2. Порядок выполнения сценариев


Сценарий работает в непрерывном режиме, и как только он доходит до своего окончания он запускается вновь. При этом есть два блока, которые могут временно приостановить работу сценария, «delay» и «pause».
Блок «delay» используется для миллисекундных или микросекундных задержек. Этот блок строго выдерживает временной интервал, блокируя работу всего устройства.
Блок «pause» используется для секундных (можно и меньше) задержек, и он не блокирует выполнение других процессов в устройстве.
Если сценарий внутри себя содержит бесконечный цикл, в теле которого не стоит «pause», интерпретатор самостоятельно инициирует маленькую паузу.
В случае исчерпания выделенного стека памяти, интерпретатор остановит выполнение такого прожорливого сценария (будьте осторожны с рекурсивными функциями).

Шаг 3. Отладка сценариев


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

Сценарий вычисления факториала в отладочном режиме:
image

Инструмент отладки очень прост и состоит из трёх основных кнопок: «пуск», «один шаг вперёд» и «останов» (также не забудем про «вход» и «выход» из режима отладки). Кроме пошаговой трассировки можно установить точку останова на любом блоке (щелчком мыши над блоком).
Чтобы вывести в монитор текущие значения параметров (датчики, реле) используйте блок «print».
Здесь обзорный видеоролик об использовании отладчика.

Раздел для любознательных. А что же под капотом?


Для того чтобы сценарии работали на целевом устройстве был разработан интерпретатор байт-кода и ассемблер на 38 инструкций. В исходный код blockly был встроен специализированный генератор кода, который конвертирует визуальные блоки в ассемблерные инструкции. В дальнейшем эта ассемблерная программа преобразуется в байт-код и передаётся в устройство на исполнение.
Архитектура этой виртуальной машины довольно проста и описывать её особого смысла нет, в сети вы найдёте много статей о проектировании простейших виртуальных машин.
Под стек своей виртуальной машины я обычно выделяю 1000 байт, этого хватает с запасом. Конечно, глубокие рекурсии могут исчерпать любой стек, но вряд ли им найдётся практическое применение.

Итоговый байт-код получается довольно компактным. Как пример, байт-код вычисления того же факториала составляет всего 49 байт. Это его визуальная форма представления:
image

А это его ассемблерная программа:

shift -1
ldi 10
call factorial, 1
print
exit
:factorial
ld_arg 0
ldi 1
gt
je 8
ld_arg 0
ld_arg 0
ldi 1
sub
call factorial, 1
mul
ret
ldi 1
ret

Если ассемблерная форма представления не имеет какой-либо практической ценности, то вкладка «javascrit», напротив, даёт более привычный вид нежели визуальные блоки:

function factorial(num) {
  if (num > 1) {
    return num + factorial(num - 1);
  }
  return 1;
}

window.alert(factorial(10));

Что касается производительности. При запуске простейшего сценария мигалки, на экране осциллографа я получил меандр 47кГц (при тактовой частоте процессора 80МГц).
imageimage
Считаю это неплохим результатом, по крайней мере, эта скорость почти в десять раз быстрее чем у Lua и Espruino.

Заключительная часть


Подводя итог, скажу, что применение сценариев позволяет нам не только запрограммировать логику работы отдельного устройства, но и даёт возможность связать несколько устройств в единый механизм, где одни устройства влияют на поведение других.
Также отмечу, что выбранный способ хранения сценариев (непосредственно в самих устройствах, а не на сервере), упрощает переключение уже работающих устройств на другой сервер, например на домашний Raspberry, здесь инструкция.

На этом всё, буду рад услышать советы и конструктивную критику.

© Habrahabr.ru