В устройство будет залито достаточно много файлов. Познакомимся с ними:
Но… Пока это случится… Очень хочется поиграть с модулем, правда? Проверить как он работает…
Проверка работоспособности устройства.
Легко! Вот вам код. Этот код позволяет вручную отправлять raw команды на модуль и получать от него ответ. Вы уже можете проверить работоспособность устройства, а за одно понять, как работает альтернативный UART.
Можно вручную (с изучением документации от nooLite) привязать к модулю что-то, получить от него информацию, отправить команду.
Но если чтение документации от nooLite вам не доставляет, в коде есть пара примеров.
К сожалению, владельцы ESP-1 пока отдохнут, реализовать то что написано далее на этом модуле хотя и можно, но придется сильно дергать провода… Не стоит оно того.
Итак (или ссылка на форум Амперки, где все это лучше смотрится):
do
sendRAW = {} -- Таблица быть должна, она там, внизу, проверяется
-- Или таблица что ниже - отправляем RAW байты в модуль.
-- Всего - 15 штук. 16й (будет посчитан) и 17й будут дописаны.
-- если оставить таблицу пустой, то ESP ждет прихода информации от MTRF.
- а откуда она там возьмется, если ничего не привязано?
-- привязка на канале 0 старого блока:
-- sendRAW = {171,0,0,0,0,15,0,0,0,0,0,0,0,0,0}
-- установка яркости на канале 0 старого (не F) блока
-- sendRAW = {171,0,0,0,0,6,1,100,0,0,0,0,0,0,0}
-- Пинг-понг с MTRF-64, узнете его адрес
-- sendRAW = {171,4,0,0,0,0,0,0,0,0,0,0,0,0,0}
-- Это блоку F, даже если его у вас нет, разбирайтесь с ответом, ответ будет
-- sendRAW = {171,2,8,0,1,2,0,0,0,0,0,0,0,32,80}
answer = {} -- сюда, в поле answer.raw, пишется стринг ответа от модуля
crcR = 0 -- для подсчета crc
gotRAW = {} -- таблица принятых байт от MTRF
counter = 1 -- (см. перевод)
startUART = false -- Флаг, размахиваем!
function ptrANSW() -- Печать результатов с замедлением
-- ESP нужно время чтобы перенастроить порт
tmr.create():alarm(1000, 0, function()
print(answer.raw) -- Печать стринга
table.foreach(gotRAW, print) -- печать таблицы
end)
end
-- Это главное в нашей жизни
function gotMTRF()
-- Я же говорил - не пользуйтесь ESP-1!!!
uart.alt(1)
uart.setup(0, 9600, 8, uart.PARITY_NONE, uart.STOPBITS_1, 0)
uart.on("data",1,
function(data)
local bt = string.byte(data, 1) or 0
if startUART == true or (startUART == false and bt == 0xAD) then
startUART = true
table.insert(gotRAW, bt)
if counter < 16 then
crcR = crcR + bt
end
counter = counter + 1
end
if counter == 18 then
if gotRAW[1] == 0xAD and gotRAW[17] == 0xAE and (gotRAW[16]) == bit.band(crcR, 0xFF) then
local s = ""
for _, v in pairs(gotRAW) do
s = s.."$"..string.format("%02X", v)
end
answer.raw = s
uart.alt(0)
uart.setup(0, 115200, 8, uart.PARITY_NONE, uart.STOPBITS_1, 1)
ptrANSW()
end
end
end, 0)
-- Если в таблице sendRAW забито 15 байт - они будут отправлены в моудль
if #sendRAW == 15 then
-- Считаем 16 байт
local cr = 0
for i = 1, 15 do
cr = cr + sendRAW[i]
end
cr = bit.band(cr, 0xFF)
-- Пишем 16 и 17 байт в таблицу
sendRAW[16] = cr
sendRAW[17] = 172
-- Отправляем в модуль MTRF-64
for i=1,17 do
uart.write(0, sendRAW[i])
end
end
end
gotMTRF()
--
-- Вам на все 15 секунд, после чего порт возвратится в исходное состояние.
tmr.create():alarm(15000, 0, function()
uart.on("data")
uart.alt(0)
uart.setup(0, 115200, 8, uart.PARITY_NONE, uart.STOPBITS_1, 1)
end)
--]]
end
Пока вы развлекались raw-общением с модулем и наслаждались изучением документации Ноотехники, мое устройство (ESP-201+MTRF-64) успешно отработало двое суток и теперь пора выкладывать его код. Обобщим, закрепим и систематизируем все что вам стало понятно и без меня.
А та программа, что приведена выше? Уверен, она пригодится вам и в том случае, если вы ей сейчас не пользовались. Этот инструмент обязательно поможет вам при доработке устройства под свои нужды, без сомнения.
Структура команд MTRF-64 и привязка.
Структура команд модуля не так страшна, как может показаться после прочтения документации.
В любом случае работы с модулем, мы должны совершить пять шагов:
- собрать ВОСЕМЬ элементов команды — получится 14 байт;
- предварить их числом 171;
- посчитать контрольную сумму пятнадцати байт (включив в подсчет первый байт — 171) и получить 16-й байт;
- добавить 17-й байт — число 172;
- передать команду из семнадцати байт на модуль MTRF-64.
Восемь элементов команды на привязку таковы:
Внимание! Я рисую таблицы как смог понять суть явлений из документации Ноотехники! Если я ошибся — исправляйте, внесу изменения.
Как следует из собственной логики и их документации (хм…), привязка устройства имеет место в трех вариантах, а именно:
- как передатчика команд по новому протоколу F;
- как передатчика команд по старому протоколу;
- как приемника команд по старому протоколу. В настоящий момент не существует (может я что-то просмотрел?) ни пультов, которые управляют по протоколу F, ни датчиков, работающих с этим же протоколом.
Все отразил в таблице выше. Примеры.
Шаг 1. Собранные 8 элементов, они же 14 байт:
0, 0, 0, 17, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0 — Включаем привязку для управления старым силовом блоком на ячейку памяти 17.
2, 0, 0, 24, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0 — Включаем привязку для управления новым силовом блоком на ячейку памяти 24.
1, 3, 0, 19, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0 — Включаем привязку для получения информации по старому протоколу от пульта или датчика на ячейку памяти 19.
Шаг 2. Добавляем в начало 171, первый пример:
171, 0, 0, 0, 17, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0
Шаг 3. Считать контрольную сумму очень просто:
- в цикле складываем все пятнадцать байт;
- выполняем оператор «and» для суммы и числа 0xFF, что в NodeMCU Lua делается так: байт 16й = bit.band(полученная сумма, 0xFF)
Для первого примера:
171 + 0+ 0 + 0 + 17 + 15 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 = 203
Шаг 4. Команда модулю для первого примера:
171, 0, 0, 0, 17, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 203, 172
Структура команд на передачу силовым блокам.
Каша будет вариться так:
Надеюсь, из таблицы понятно многое, за исключением откуда берется адрес блока F. Этот адрес приходит каждый раз, когда MTRF общается с этим силовым блоком любым образом.
Первый раз — при привязке как ответ о том, что все получилось. Можно опросить состояние силового блока — придет не только оное, но и адрес. При подаче команд на включение и выключение в ответе также адрес присутствует.
Единственно, мне не понятно что происходит, когда к одной ячейке привязано два блока типа F — у меня пока один.
Примеры:
0, 0, 0, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0 — включить нагрузку на старом блоке, привязанном к ячейке 1. (171, 0, 0, 0, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 174, 172 — полная команда на MTRF64)
2, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 — выключить нагрузку на блоке F с привязкой к ячейке 19. (171, 2, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 192, 172 — полная команда на MTRF64)
2, 8, 0, 18, 2, 0, 0, 0, 0, 0, 0, 0, 152, 22 — включить нагрузку только конкретному блоку F привязанному к ячейке 18, имеющему адрес 22, 152, 0, 0. (171, 2, 8, 0, 18, 2, 0, 0, 0, 0, 0, 0, 0, 152, 22, 119, 172 — полная команда на MTRF64)
2, 0, 0, 18, 25, 5, 10, 0, 0, 0, 0, 0, 0, 0 — включить нагрузку на 50 секунд (10 х 5) блоку F, привязанному к 18 ячейке. (171, 2, 0, 0, 18, 25, 5, 10, 0, 0, 0, 0, 0, 0, 0, 231, 172 — полная команда на MTRF64). Напомню, что для включения силового блока на время, длительность устанавливается путем умножения 5 секунд на одно или двубайтное число, которое прописывается в пункт 7 таблицы, а в шестом пункте, при этом, будет число 5 (в этом случае) для однобайтного интервала и 6 — для двубайтного.
2, 0, 0, 19, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0 — вопрос блоку F на 19 ячейке о его самочувствии. (171, 2, 0, 0, 19, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 64, 172 — полная команда на MTRF64).
Структура ответов модуля MTRF-64.
MTRF-64 передает в UART тоже 17 байт. Первый и последний — старт и стоп, предпоследний — контрольная сумма. Структура передачи описана в таблице 2 и 3 документации.
Не буду останавливаться на разборе ответов: если пытаешься отправить команду на MTRF-64 и она неверна — модуль молчит как рыба и ты не знаешь что предпринять. Хоть головой об стену.
Если же подана правильная команда (а мы их разобрали), значит модуль ответил — тут уж при помощи таблиц можно разобраться с информацией без моих подсказок.
Весь парсинг ответов, насколько я смог увидеть главное, собран в единственном файле analize.lua, ничего сложного в нем нет — разберетесь. Этот же файл надо править, если вас заинтересует еще что-то, из многословия болтливого MTRF-64.
В частности, в моем варианте вылавливаются команды старых блоков на включение, выключение, изменение состояния силовых блоков, информация с датчиков температуры и влажности, информация о разряде батарейки пультов, ответ блоков F о своем состоянии. Нет парсинга сообщений об увеличение/уменьшение яркости — я просто не знаю что с ними делать дальше: информации о текущей яркости все равно не добыть, а ошибиться включен свет или нет в целом — проще простого.
Кроме того, из модуля на брокер MQTT будет отправляться raw-ответ (чистые 17 байт) MTRF-64, над которым можно будет не спеша помозговать — есть шанс выловить еще что-то полезное.
Заливаем файлы в ESP-8266.
Файлы в устройства будут находиться на GitHub или сайте Амперки в этом посте. В архиве — 11 файлов, testMTRF.lua — тот что приводил выше. Он в рабочее устройство не загружается. Отдельные файлы могут, со временем, обновляться.
Используем ESPlorer, разумеется.
Перед заливкой выводим устройство в сеть, передав ему следующие команды:
wifi.setmode(wifi.STATION)
wifi.sta.config("ВАША_СЕТКА", "ВАШ_ПАРОЛЬ")
wifi.sta.autoconnect(1)
wifi.sta.connect()
tmr.alarm(6,15000, tmr.ALARM_SINGLE, function()
ip = wifi.sta.getip(); print('\n', ip)
end)
Через 15 секунд ESPшка должна отрапортовать об успешном подключении к сети. Делается это так:
- Ввести код для подключения к сети, выделить его,
- Нажать кнопку Bock
- Увидеть ip-адрес ESP-8266 в сетке через 15 секунд.
Распаковываем файлы в папку — будем их загружать.
Перед загрузкой надо бы изменить файл setmqtt.lua в соответствии с вашими настройками. Изменение небольшое, и касается адреса брокера, который вы используете, пароля. В файле эти изменения указаны.
Кстати, вы можете не менять брокер — в этом случае связь устанавливается с открытым брокером iot.eclipse.org. Это замечательная опция для тех, кто твердо уверен, что умный дом это тот, что управляется смартфоном через Интернет.
Раз так, вы можете обойтись без всяких Мажордомов и ОпенХабов — только наше устройство и смартфон. Принцип работы детально раскрыт мной в этой теме.
Тем не менее, чтобы не было пересечений с кем-то, верящим аналогично, в файле main.lua надо будет заменить строку myClient = «noo01» на что-то уникальное и заковыристое, типа myClient = «zzzttemnAO_URAAAAAAnoo01»
Заливку будем осуществлять последовательно файл за файлом через Upload:
Загружаем все, кроме testMTRF.lua и init.lua.
Что же, пора заканчивать эту часть. С тем, как со всем этим управляться разберемся в следующей части.