Продолжаем изучать аппаратные возможности расширения Микротик RBM33G

В своей предыдущей статье я рассказал о возможностях расширения «обвеса» Микротик RBM33G и некоторых особенностях этой платы, в частности интегрированном GPIO-интерфейсе. Я не остановился на достигнутом и продолжил свои опыты, чем и хочу поделиться с читателем. Модули реле через GPIO мы уже подключали к роутеру в предыдущей статье, повторяться не буду. Опишу некоторые другие плюшки.
Чтобы использовать GPIO, в предыдущей статье мы отключали его от второго (serial1) последовательного порта RBM33G. Первый (serial0) порт по умолчанию занят консолью для подключений через DB9-разъем на лицевой панели платы. Предлагаю на время вернуть настройку serial1 по умолчанию:

/system routerboard settings set gpio-function=serial1


Чтобы изменения вошли в силу, нужна перезагрузка:

/system reboot

1. Управление Микротиком RBM33G через второй serial-порт

Я задался целью использовать serial1 на контактах GPIO-разъема RBM33G для подключения к роутеру через USB UART TTL переходник. Перед этим я прочитал множество инструкций, в том числе, о подключении через стандартный DB9 serial0, так как раньше мне не приходилось этого делать. Все инструкции на эту тему, болтающиеся в сети, мне лично показались непонятными, не ясно кто их писал или некачественно перевёл. Написанное в официальном руководстве wiki.mikrotik.com/wiki/Manual: System/Serial_Console и wiki.mikrotik.com/wiki/Serial_Port_Usage тоже мне было не вполне ясно (я понял, их смысл, только постфактум). Пришлось до всего, как обычно, доходить самому. Надеюсь, мой опыт избавит читателя от подобных мучений и временных затрат.

image
Рис. 1 Внешний вид платы RBM33G. В центре крайний слева — GPIO-разъем, включающий пины serial1, третий слева фронтально — разъем DB9 (serial0).

Итак, алгоритм наших последовательных действий таков:

1. Приобретаем USB UART serial переходник на чипе CH340 (Рис. 2, средняя стоимость 150р). Есть и другие, но этот, пожалуй, самый популярный или покупаем уже готовый шнур с переходником, чуть дороже, но, возможно, гораздо удобнее. Единственный минус готового — Вы не видите индикаторов питания и передачи данных (когда всё заработает, они, как правило, уже и не нужны).

image
Рис. 2 USB UART TTL serial переходник на чипе CH340 (слева) и он же в корпусе с готовым шнуром подключения (справа).

2. Снимаем перемычку с usb-serial-переходника, замыкающую VCC и один из контактов питания +3,3V или +5V (см. Рис. 2), нам это не нужно.
3. Устанавливаем в Windows драйвер CH340 для виртуального COM-порта.
4. Если покупали переходник без шнура, то делаем трехпроводный шнур. Можно использовать витую пару с клеммниками под микро пины.
5. Соединяем контакты купленного или изготовленного шнура с Микротик и переходником по следующей схеме TX-RX; RX-TX; GND-GND. При этом на переходнике контакты подписаны, на GPIO Микротик Pin12 соответствует RX, Pin13 — TX, ближайшая GND — Pin14. Получаем сборку как на Рис. 3
6. Соединяемся c роутером по Ethernet через Winbox и проверяем, что у Вашей RBM33G в /port print есть два последовательных порта: serial0, как обычно, и наш serial1
* Внимание! Порт serial1 не появляется на старых прошивках Роутер ОС, нужна прошивка выше 6.45

image
Рис. 3. RBM33G c подключенным к GPIO serial1 адаптером USB-serial TTL CH340 для подключения к ПК.

7. проверяем, что 

:put [/system routerboard settings get gpio-function] 

выдает:
serial1

если нет — устанавливаем (мы это уже делали Выше, так что потребоваться не должно):

/system routerboard settings set gpio-function=serial1
/system reboot


8. добавляем консоль для порта serial1
Вот это очень важный момент, о котором нигде не пишут, в том числе в руководствах и на форумах. А ведь это очевидно — у нас появился новый serial-порт и если мы хотим иметь для него консоль — её нужно создать:

/system console add port=serial1


Теперь у нас в системе две консоли console0 и console1, каждая для соответствующего serial-порта.

9. устанавливаем скорость передачи данных для serial1 115200 (она должна быть, вероятно, но не факт, такая же, как для самой RB в /system routerboard)

/port set number=1 name=serial1 baud-rate=115200


Здесь number=1, что соответствует нашему порту. Параметр name=serial1 в данном случае, но имя порта может быть любым, и система ориентируется именно на «number», а не на «name».
10. и только тогда активируем созданную консоль

/system console enable 1


11. После этого подключаем usb-serial адаптер в порт USB нашего ПК c установленным драйвером виртуального com-порта. Запускаем putty, или аналогичную терминальную программу, указав скорость 115200 и COM-порт адаптера. Открываем сеанс и …
… видим черный экран. Не материмся Не пугаемся, а нажимаем «ввод» и только тогда, активировав этим с клавиатуры передачу данных, видим, наконец, приглашение к вводу логина и затем пароля:

Router OS 6.49.10 (long-term)
Login:

Это значит всё в порядке. Если вместо этого, видим абракадабру или переодически появляется таковая, значит, скорее всего, есть несоответствие в параметрах порта в настройках ПК, putty или Микротик. Устраняем несоответствие и всё должно работать на максимальной скорости 115200. Если закрыть сеанс или вообще саму программу putty, а потом открыть снова, то вводить логин и пароль повторно не нужно — доступ остается открытым. Если хотите действительно выйти из сеанса с Микротиком и закрыть его нужно набрать в терминальном окне команду для выхода:

/quit


Не вводите из окна putty команду типа /system console disable 1 — вы деактивируете консоль на этом порту и не сможете ничего вводить отсюда, это не страшно, можно восстановить, если у Вас есть другая связь с роутером и придется снова активировать консоль, например, через Winbox.
Можно навсегда было бы оставить подключенным шнур с переходником СH340 к GPIO RBM33G, выведя его через корпус роутера наружу. Но, это немного неудобно. Так «навсегда» занимаются Pin12 и Pin13, которые могут использоваться как линии ввода/вывода GPIO. Далее, я покажу, что придумал, чтобы обойти это неудобство и вообще реализовать вывод GPIO-разъема за пределы корпуса (если RBM33G установлена в корпус).

2. Подключение пульта дистанционного управления к Микротик

Представляете: да, такое без всяких костылей возможно на RBM33G! Например, Вы нажимаете кнопку брелока и у ребенка (и только у него) выключается Интернет. Или нажимаете другую и перезагружается модем, или отключается/включается wifi…. Или Вы крутой админ и из кабинета шефа, не включая компьютер и не пользуясь никакими программами, то есть магически, пользуясь только «силой» (из кармана брюк) на глазах у начальника выключаете Интернет всему офису, чтобы не повадно было Вас не уважать. Да, что угодно … можно «запрограммировать» любое действие или исполнение целого сценария (скрипта). А теперь по порядку …
Покупаем на AliExpress приёмник сигнала 433Мгц (можно 315 или 816 Мгц, стоит копейки — около 100р, Рис. 4) и пульт дистанционного управления (Рис. 5), подходящий к нему по частоте и алгоритму кодирования сигнала (100–200р). Ссылки не привожу, так как данные устройства продаются сейчас повсеместно и многочисленно.

image
Рис. 4 Программируемый приемник радиосигнала 433 Мгц.

image
Рис. 5 Пульты управления приемником радиосигнала различного дизайна, в том числе мультичастотные универсальные.

Как правило, они четырёх или двухкнопочные. Сколько Вам нужно кнопок — решайте сами. Чаще всего такие штуки используются для управления шлагбаумом, воротами или наружным освещением. Приемник такого сигнала имеет встроенную антенну, или маленькую проволочную антенну (можете припаять сами, главное, чтобы она имела нужную длинну, толщину и количество витков) и контакты на плате типа VDC, GND, OUT1, OUT2, (OUT3, OUT4).
Устанавливаем пакет iot.npk из extra packages «Вашей» версии Роутер ОС, загрузив его с сайта Микротик, если его у Вас ещё нет.

Настраиваем обратно GPIO, отключая его от serial1 порта:

/system routerboard settings set gpio-function=«»
/system reboot

Устанавливаем приемник дистанционного пульта в корпус RBM33G, пока не закрывая крышку. Соединяем проводами клеммники GPIO разъема RBM33G и приемника по следующей схеме (будем для примера использовать Pin3 и Pin5 в качестве линий настроенных на вход):
Pin2 (+5V) — VDC; Pin4 (GND) — GND, Pin3 — OUT1; Pin5 — OUT2
Получаем в данном примере двухканальное управление (предположим, что брелок у нас двухкнопочный). При нажатии на брелоке кнопки 1(А) на линии Pin3 GPIO RBM33G будет появляться логическая 1 (+5В). Аналогично при использовании кнопки 2(B) логическая единица будет появляться на Pin5.
Кстати нужно отметить, что приемник умеет, как правило, работать с различной логикой кнопок: немедленный тип, блокировка, кнопка Y освобождает кнопку X. Логика работы будет зависеть от того, как Вы это установите на приемнике.
Проводим «обучение» пульта по прилагаемой инструкции к пульту и приемнику. Для этого на приемнике есть микро кнопка, которую нужно нажать некоторое количество раз подряд: приемник войдет в режим программирования. Далее выбирается режим кнопки (см. выше). Последним этапом подносите пульт на близкое расстояние к приемнику и нажимаете кнопку, которую хотите ввести в память приемника. Приемник запоминает код пульта, параллельно распределяя код по каналам управления (не для всех типов приемников, для некоторых нужно программировать отдельно каждую кнопку). Теперь нажимая разные кнопки пульта мы получаем логическую 1 на соответствующих выходах приемника и соответственно на IO-линиях GPIO RBM33G, настроенных на вход. При отпускании кнопки состояние линии может возвращаться в логический 0 или оставаться логической 1 до повторного нажатия или нажатия другой кнопки (зависит от запрограммированного режима, как было указано выше). Кстати, Вы можете таким образом привязать к Вашему приемнику несколько пультов (и раздать их кому хотите, только не врагам). Все пульты будут идентичны.
Настроим, для примера, две линии для нашего двухкнопочного пульта. Если Вы хотите, то можно использовать те самые линии pin3 и pin5, не участвующие в serial1, даже когда GPIO на него настроен. Установим режим линий «input»:

/iot gpio digital set pin3 direction=input
/iot gpio digital set pin5 direction=input

Тогда Вы вообще можете не отключать наш шнур/переходник от GPIO RBM33G. Если же у Вас пульт четрых и «более кнопочный» — без отключения не обойтись, так как максимально у RBM33G можно получить только 6 digital io линий.
Проверить работу брелока можно следующим образом. Подаём команду в Терминале:

:put [/iot gpio digital get pin3]
0

Теперь нажимаем кнопку и держим (если настроен режим «немедленного реагирования»), повторяем команду

:put [/iot gpio digital get pin3]
1

Отпускаем кнопку и повторяем проверку:

:put [/iot gpio digital get pin3]
0

После этого осталось дело за скриптами. Можно привязать к любой линии любой скрипт репозитория роутера:

/iot gpio gigital set Pin3 script=myScript

Скрипт будет выполняться каждый раз при смене состояния линии как с 0 на 1 так и с 1 на 0. Это следует учесть при написании логики скрипта.
Примеры скриптов:
Напишем скрипты для двухкнопочного пульта, чтобы его кнопки включали реле 1 и 2 4-х канального модуля реле из моей предыдущей статьи. При этом кнопки пульта будут использовать линии Pin3 и Pin5, настроенные на вход, а реле будет подключено к Pin12 и Pin13, настроенными на выход.
Настраиваем линии pin12 и pin13 на выход:

/iot gpio digital set pin12 direction=output
/iot gpio digital set pin13 direction=output

Настраиваем линии pin3 и pin5 на вход и сразу привязываем к ним скрипты c именами PDUA и PDUB, которые будут выполняться при нажатии на кнопки. Чтобы при отпускании кнопки реле не выключались, предумотрим это в логике скриптов. Скрипты PDUA и PDUB размещаем в репозитории под соответствующими названиями.

/iot gpio digital set pin3 direction=input script=PDUA
/iot gpio digital set pin5 direction=input script=PDUB

* В примере предполагается, что используемые линии активированы.

# скрипт для кнопки A
:global PDUА; :if (!any $PDUА) do={
:do {
     :log info ""
     :log warning "Кнопка A"
     :local Stat1 ([/iot gpio digital get pin12]->"output")
     :if ([:tonum $Stat1]=0) do={[/iot gpio digital set pin12 output=1]; :log error "Включение реле 1"} else={[/iot gpio digital set pin12 output=0]; log warning "Выключение реле 1"}
     :log info ""
     :set $PDUA true
} on-error={}
} else={:set $PDUA}

# аналогичный скрипт для кнопки B
:global PDUB; :if (!any $PDUB) do={
:do {
     :log info ""
     :log warning "Кнопка B"
     :local Stat1 ([/iot gpio digital get pin13]->"output")
     :if ([:tonum $Stat2]=0) do={[/iot gpio digital set pin13 output=1]; :log error "Включение реле 2"} else={[/iot gpio digital set pin13 output=0]; log warning "Выключение реле 2"}
     :log info ""
     :set $PDUB true
} on-error={}
} else={:set $PDUB}

Всё. Теперь при нажатии на кнопки A и B пульта (могут называться 1 и 2 или быть обозначены пиктограммами) будет соответственно срабатывать скрипт PDUA или PDUB и включаться/выключаться реле, соединенные с управляющими Pin12 и Pin13, настроенными на выход.
В работе c любыми линиями GPIO, в том числе при присоединении периферических модулей, понимающих простую логику »1» и »0», можно использовать мою универсальную функцию работы с линиями GPIO:

Функция iotLine
# Функция работы линиями GPIO RBM33G; by Sertik 30/10/2023 v.1.2
# соответствие линий GPIO распиновке задаётся в массиве arrayPin (порядок менять нельзя):
# линия    1- pin3 
#                2- pin5
#                3- pin12
#                4- pin13
#                5- pin15
#                6- pin16

# $1 - действие (on/off/direction/info), при info всегда выдается информация по всем линиям
# $2 - номер линии (если не указан действие выполняется над всеми)
# $3 - input/output, используется при $1 direction, если не задан, действие производится над всеми линиями

# в глобальной переменной ioLineNONC должно стоять "true" если линия нормально открытая и "false" если нормально закрытая
# по умолчанию (если ioLineNONC не задавать) считается, что линии, настроенные на output нормально открытые (output=1 включает линию, output=0 - выключает)
:global iotLine do={
:global ioLineNONC
:local arrayPin {3; 5; 12; 13; 15; 16}
:local ioLine 6
:local act;

:if ([:len $ioLineNONC]=0) do={:set $ioLineNONC true}

:if ($1="help") do={
         /terminal style varname
         :put ""
         :put "Function works with GPIO RBM33G"
         :put "version 1.0"
         :put "by Sertik 23/10/2023"
         :put ""
         :put "\$1 - action: on/off/enable/disable/direction/info/help"
         :put "\$2 - line number, if not define - all"
         :put "\$3 - input/output for direction"
         :put "\$ioLineNONC - true (or not specified) - line for NO rele/ false - line for NC rele"
         :put ""
         /terminal style none}

 :if ([:len [/system routerboard settings get gpio-function]]!=0) do={
                              :local gpioanswer "Pin 12-16 is not set on GPIO.\n\rPlease reset routerboard gpio-function and reboot Router."
                              :put ("ERROR $0 function"."\r\n"."$gpioanswer")
                              :log error ("ERROR $0 function"."\r\n"."$gpioanswer")
                              :return $gpioanswer}       


     if (($1="info") and ([:len $2]=0)) do={
:local gio [/iot gpio digital print as-value]
:local count 0; local name; :local comment; :local script; :local dir; :local output; :local input;
:foreach i in=$gio do={
                            :set name ($gio->$count->"name")
                            :set comment ($gio->$count->"comment")
                            :set script ($gio->$count->"script")
                            :set dir ($gio->$count->"direction")
                            :set input ($gio->$count->"intput")
                            :set output ($gio->$count->"output")
                            :set count ($count+1)
         :put ("$count "."$name "."$dir "."$output "."$input "."$comment "."$script")
         :log warning ("$count "."$name "."$dir "."$output "."$input "."$comment "."$script")
  }
:return $gio}

:if (($1="info") && ([:len $2]=1)) do={
   :if (([:tonum $2]<=0) or ([:tonum $2]>$ioLine)) do={:return Error}
do {
                  :local state [/iot gpio digital get "pin$($arrayPin->([:tonum $2]-1))"]
                  :put $state
                  :return $state
} on-error={:return Error}
}

:if (($1="enable") and ([:len $2]=1)) do={
  :if (([:tonum $2]<=0) or ([:tonum $2]>$ioLine)) do={:return Error}
do {
                               [/iot gpio digital set "pin$($arrayPin->([:tonum $2]-1))" disabled=no]
                               :local pinSet ([/iot gpio digital get "pin$($arrayPin->([:tonum $2]-1))"]->"disabled")
                               :if (!$pinSet) do={:return "Done"} else={:return "Not set"}
} on-error={:return Error}
}

:if (($1="disable") and ([:len $2]=1)) do={
  :if (([:tonum $2]<=0) or ([:tonum $2]>$ioLine)) do={:return Error}
do {
                               [/iot gpio digital set "pin$($arrayPin->([:tonum $2]-1))" disabled=yes]
                               :local pinSet ([/iot gpio digital get "pin$($arrayPin->([:tonum $2]-1))"]->"disabled")
                               :if ($pinSet) do={:return "Done"} else={:return "Not set"}
} on-error={:return Error}
}

:if (($1="disable") and ([:len $2]=0)) do={
   do {
                  :foreach Xpin in=$arrayPin do={
                  /iot gpio digital set "pin$Xpin" disabled=yes
                   }
        } on-error={:return Error}
:return Done}

:if (($1="enable") and ([:len $2]=0)) do={
   do {
                  :foreach Xpin in=$arrayPin do={
                  /iot gpio digital set "pin$Xpin" disabled=no
                   }
        } on-error={:return Error}
:return Done}


:if (($1="direction") and ([:len $3]=0)) do={
    :if (($2="input") or ($2="output")) do={
        do {
                  :foreach Xpin in=$arrayPin do={
                  /iot gpio digital set "pin$Xpin" direction=$2
                   }
        } on-error={:return Error}
  } else={:return Error}
:return Done}

:if (($1="direction") and ([:len $2]=1) and ([:len $3]>1)) do={
     :if (($3="input") or ($3="output")) do={
       :if ([:tonum $2]>$ioLine) do={:return "Error"}
            :do {
                  /iot gpio digital set "pin$($arrayPin->[:tonum $2])" direction=$3
                } on-error={:return Error}
     } else={:return Error}
:return Done}

     :if (($1="on") && ($ioLineNONC=true)) do={:set act 1}
     :if (($1="on") && ($ioLineNONC=false)) do={:set act 0}
     :if (($1="off") && ($ioLineNONC=true)) do={:set act 0}
     :if (($1="off") && ($ioLineNONC=false)) do={:set act 1}

:if ([:len $act]>0) do={

   :if ([:len $2]>0) do={
           :do {
                  :if (([:tonum $2]<=0) or ([:tonum $2]>$ioLine)) do={:return Error}
# check direction output - error
        :if ([/iot gpio digital get "pin$($arrayPin->([:tonum $2]-1))" direction]="input") do={:return "Error line $2 is set on INPUT"}
                  /iot gpio digital set "pin$($arrayPin->([:tonum $2]-1))" output=$act
                  } on-error={:return Error}
     } else={
                  :foreach Xpin in=$arrayPin do={
#check direction output for group line - sckip input line
         :if ([/iot gpio digital get "pin$Xpin" direction]="output") do={
                  /iot gpio digital set "pin$Xpin" output=$act}
                   }
                } 

 :return "Done"} else={:return "Error"}
}


# Примеры вызова 
# :global ioLineNONC true или не задано - для линий NO типа
# :global ioLineNONC false для линий NC-типа)

# help (выводит информацию только в Терминал)
# [$iotLine help]

# вывести состояние всех линий в терминал и лог
# [$iotLine info]

# запросить состояние линии 3
# :local R3 [$iotLine info 3]

# запросить флаг активности PIN "2"
:put ([$iotLine info 2]->"disabled")

# установить направление ввода/вывода линии 4
# [$iotLine direction 4 output]

# установить направление ввода/вывода всех линий на ввод:
# [$iotLine direction input]

# :log error ("Логическая единица на линии 3 "."$[$iotLine on 3]")
# :delay 2s
# :log warning ("Логический ноль на линии 3 "."$[$iotLine off 3]")

# Логическая единица на  всех линиях
# [$iotLine on]

# Логический ноль на всех линиях
# [$iotLine off]

# Активировать/дезактивировать линию 1
# [$iotLine enable/disable 1]

# Активировать/дезактивировать все линии
# [$iotLine enable/disable]


Дальше речь пойдет о подключении некоторых периферических модулей от Ардуино, как самых многочисленных и дешевых из существующих.

3. Подключение модуля бипера

Как известно, RBM33G не имеет динамика — это совсем «тихий» роутер. Модуль «пищалки», конечно не заменяет штатного модуля динамика Микротик, который может управляться программно и проигрывать ноты заданной частоты и длительности, но всё же позволяет хоть как-то «озвучить» роутер. Стоимость модуля минимальна — 26 рублей на AliExpress, наши продаваны, конечно отдают в 10 раз дороже (Рис. 6).

image
Рис. 6 Активный модуль динамика для Aрдуино: слева — вид модуля; справа — монтаж и подключение к GPIO RBM33G (не обращаем внимания на провода также подключенного UART serial USB переходника).

Его подключение «не накладно» и требует всего одной линии управления от GPIO RBM33G, не считая проводов питания +5В и «земли». Модуль бипера имеет малые размеры и отверстие в центре, так что я даже умудрился «приколхозить» его в одно из штатных отверстий RBM33G на резьбовую заклепку, не мешая никаким другим устройствам (Рис. 6 справа). Управление самое простое — «HIGH LEVEL», то есть подаём на линию управления GPIO RBM33G, настроенную на выход, логическую единицу — модуль пищит, подаём »0» — замолкает. С помощью скриптов понятно можно «пропищать» несколько раз с регулируемыми задержками между «писками». Тональность задавать нельзя, она одна и установлена в активном бипере «аппаратно». Бипер можно использовать для озвучивания старта роутера, перезагрузки и т.п…, жаль, что звук у него всё же дохлый какой-то и напоминает писк комара. Могли бы зуммер и поагрессивнее сделать.
Вот пример маленького скрипта, играющего на таком бипере «хоккейный марш» (контакт I/O бипера подключен к Pin5 GPIO):

/iot gpio digital set pin5 direction=output

:local beepGpio do={ 
        /iot gpio digital set pin5 output=1
        :if ([:len $1]!=0) do= {:delay $1} else={:delay 100ms}
        /iot gpio digital set pin5 output=0
        :if ([:len $2]!=0) do= {:delay $2} else={:delay 70ms}
        }

$beepGpio 200ms 100ms
$beepGpio 200ms 100ms
$beepGpio
$beepGpio
$beepGpio 100ms 270ms
$beepGpio 150ms 200ms
$beepGpio
$beepGpio 100ms 270ms
$beepGpio 150ms
$beepGpio 150ms

Остальное описывать детально смысла нет, всё просто и понятно.

4. Говорящий микротик — подключение модуля записи/воспроизведения голоса

Это уже немного поинтереснее. Голосовой модуль ISD1820 для Arduino (Рис. 7) позволяет записать «в себя» несколько голосовых сообщений или других звуков, сохраняя их во флеш-памяти. Каждое сообщение не может быть длиннее 10 секунд воспроизведения, но этого вполне достаточно. Любое сообщение можно воспроизвести в отдельности на наушники (это нам не интересно) и на динамик подавая логическую »1» на определенные пины «модуля голоса» с программируемых пинов GPIO Микротик, настроенных на «выход». Таким образом, при желании можно озвучить несколько событий для роутера «своим» голосом.

image
Рис. 7 Модуль записи/воспроизведения голоса ISD1820.

5. Управление serial MP3 Player через Laurent-5G

Есть более продвинутый модуль воспроизведения, например serial MP3 Player от Catalex и его клоны (Рис. 8).

image
Рис 8. Клон Serial MP3 Player YX5300 Catalex (слева) и аналог c подключенным динамиком 8 Ом 0,5 Вт (справа).

Модуль имеет UART и слот для микро SD, управляется простыми HEX-командами, позволяя воспроизводить mp3-файлы из папок, заранее записанных на SD-карту, регулируя громкость и другие параметры воспроизведения. К сожалению, этот модуль напрямую Микротиком управляться не может, так как Роутер ОС не имеет клиента RFC-2217, а очень жаль. Это означает, что не получиться из консоли или скрипта отправить данные на устройство, подключенное к serial или USB-порту роутера. Одним из обходных путей является создание /interface/ppp-client с портом, установленным для последовательных устройств, тогда команды могут быть отправлены через /ppp-out1 at-chat input=, но это работает только с последовательными устройствами, у которых есть набор AT-команд. Если бы «чат» был более гибким и имел бы опцию /port/remote-access для вставки данных в общие порты, понятно было бы лучше. С устройствами, не поддерживающими AT-команды такое не прокатит, им порт система предоставляет, а способа обмена данными нет (подробнее здесь). Разработчики Микротик пока не устранили эту недоработку, хотя есть возможность обойти её при использовании Docker, но только на Роутер ОС 7, да это и не так просто.
Я нашёл для себя возможность решить эту проблему по-другому: поставив между RBM33G и serial MP3 Player мой любимый модуль Laurent (www.kernelchip.ru), который и без того у меня широко используется во многих проектах.
Laurent имеет всё необходимое для обмена данными с RS 232. В том числе он имеет набор $KE-команд, позволяющих напрямую отправлять шестнадцатиричные данные в свой serial-порт — как раз то, что нужно. А сами данные можно либо заранее поместить в скрипты Laurent либо засылать http-запросами с Микротика.

6. Подключение Arduino к Микротик (через USB) с пробросом порта из сети на USB

В конце концов чего уж мелочится — можно подключить к Микротик не модули от Ардуино, а сам Ардуино со всем зоопарком его модулей и управлять из консоли Микротик всем этим зверинцем. Такое причём уже делалось нашим уважаемым Chupaka и весьма давно (он описал это здесь).

image
Рис 9. Arduino Mega 2560 ATmega16U

Ссылаясь на его статью проброс TCP-порта на USB на Микротике описывать не буду, в первоисточнике всё описано. Современный аналог Arduino Mega 2560 с чипом ATmega8U2 — аналогичная плата с чипом ATmega16U (Рис. 9) имеет 4-ре! UART и целых 54! линии GPIO. Пробросив порт мы можем «заходить» из Терминала Микротик или терминальной программы ПК прямо в serial-консоль Ардуино-платы. Только вот в статье Чупакабры есть ошибка (цитирую): «Кроме того можно, в принципе, слать команды в Arduino-терминал и из скриптов RouterOS Mikrotik». Вот это как раз пока и не получится ни в принципе ни на практике, так как это станет возможным только тогда, когда в Роутер ОС появится клиент RFC-2217. Тогда можно будет управлять Arduino и всей его периферией из скриптов Микротик. Ну, а управление нагрузками методом, предложенным в статье от Chupak`s, конечно устарело, когда теперь у RBM33G есть GPIO и можно обойтись без костылей и палок.

Вот, пожалуй и всё, что я хотел рассказать….

Ах, да забыл, что обещал ещё написать, как я придумал вывести GPIO Микротик наружу, на корпус, ведь всё время раскручивать таковой и лазить внутрь не хочется.

7. Установка GPIO разъема на корпус

Просмотрев множество Интернет-сервисов я никак не мог, представляете себе, найти маленького, изящного разъема хотя бы на 8–10 контактов. Производители, при нашем-то изобилии товаров, делают либо каких-то доисторических монстров типа DB9 (кстати, до сих пор не могу понять, почему бы разработчикам Микротик не заменить DB9 для serial-порта на тот же RJ45 у всех RB, а не только у некоторых) и тому подобное, либо разъемы без крепления на корпус. В конце концов, я наткнулся на POGO-разъемы и их магнитоконтактные модификации, которые мне очень понравились. В результате взял вот такой с 12 «подпружиненными» pin (для наших целей более чем достаточно, часть Pin-ов остаются резервными):

image
Рис. 10 Pogo магнитоконтактный разъем 12pin.

Его можно аккуратно поставить на боковую или заднюю (ниже антенн) стенку штатного CA433U корпуса Микротик RBM33G (у других корпусов лучше на боковую). У ответной части разъема боковые массы с винтовыми креплениями можно аккуратно срезать и зашлифовать. Перепутать сторону при подключении невозможно, так как они имеют разную конфигурацию контактной поверхности. Хвосты проводов у разъемов убираем в термоусадки. Получается весьма неплохо, разъем стабильный и быстросъемный, если подключение к GPIO не нужно. Прямо ноу-хау! Такой разъем или подобный к RBM33G мог бы поставлять и сам производитель.

На этом точно пока всё. Просьба не кидать в меня грязными тряпками к тем, кто не любит Микротик в принципе и не понимает людей, которые любят эти устройства и используют их иногда не только как роутеры.

© Habrahabr.ru