Термометр, джойстик и ноутбук в одном шкафу, не считая ардуино

в 2:15, , рубрики: arduino, diy или сделай сам, метки:

С чего всё началось

Однажды давным давно стоял у меня в шкафу в прихожей домашний сервер под дебианом. Работал круглосуточно, поддерживал вторичный DNS, бэкапы делал, торренты покачивал, служил медиасервером, и прочее, и прочее (ну вы сами знаете для чего бывает нужен домашний сервер). В то же самое время охота мне было иметь указатель погоды на улице, чтобы перед выходом из дома нужной тёплости штаны надевать. Термометр за окном на эту роль не годился — из-за всяких паразитных воздушных потоков у стен многоэтажки показывал он что попало, да и кроме температуры для правильного выбора штанов интересно знать ветер и влажность. В итоге у сервера появился монитор на наружной поверхности шкафа. А сам сервер научился забирать сведения о текущей погоде в формате METAR из ближайшего аэропорта (он относительно недалеко, и его метеосводка очень близка к тому, что за дверью), а сведения о прогнозе на ближайшие сутки в XML с gismeteo.ru. Все это через простекций веб-интерфейс показывалось автоматически стартовавшим при загрузке сервера браузером. Потом на страничку добавились сведения о загруженности канала в интернет, текущем состоянии торрентов (у rTorrent-а есть соответствующий программный интерфейс для этого), изображение камеры видеонаблюдения за дверью, что-то ещё… Выглядело это примерно так:
image
Через некоторое время стали очевидными два недостатка. Во-первых, чтобы поглядеть, скажем, температуру за бортом приходилось включать монитор (держать его постоянно включенным плохо — и монитор деградирует, и свет от него ночью мешает). А включается монитор не мгновенно, и эти вот несколько (казалось бы!) секунд раздражают. Во-вторых, полное отсутствие устройств управления существенно ограничивает возможности применения этого хозяйства. Сильно, например, не хватало возможности управления камерой наблюдения (она с приводом по курсу и тангажу). А потом вообще все кончилось. Сервер после ряда модернизаций и роста нагрузки стал перегреваться в шкафу, а домочадцам надоел его шум. В конце концов он был сослан за пределы жилых помещений. А потребность в термометре и всём другом осталась…

Ставим задачу

Из опыта прошедшей эксплуатации можно было вынести следующее:

  1. Наличие устройства, которое показывает всякие полезные сведения — не лишнее, и смысл в этом есть.
  2. Наиболее часто востребованные «данные мониторинга» хотелось бы вынести на автономный, постоянно включенный индикатор. Но при этом сохранить монитор для отображения реже востребованных, но более сложных в визуальном плане вещей.
  3. Необходимо наличие устройств управления.

При этом желательно выполнить ряд сопутствующих требований: худо-бедно, но сохранить эстетичность; не потратить лишних денег; не сделать слишком сложно; сделать более или менее универсальное решение.
Поразмышляв, я пришел к следующим выводам. Во-первых, необходимо наличие в шкафу какой-то замены жившему там ранее серверу. Это устройство может обладать минимальной мощностью, лишь бы потянуло полноценный Linux с браузером. При этом должно не шуметь и сильно не греться. К этому устройству подключается монитор и устройство управления. Наличие полноценной стандартной ОС дает возможность не изобретать велосипедов и не ограничивать свои фантазии. Во-вторых, с показом «оперативных» данных вполне справится символьный ЖКИ-дисплей на пару строк. В темное время суток ему, конечно, понадобится подсветка. Желательно чтобы работоспособность дисплея не зависела от компьютера в шкафу. Поэтому неизбежно наличие отдельного контроллера. Основную закадровую работу имеет смысл возложить на сосланный сервер (он же все равно всегда включен, а при таких раскладах возможности «внутришкафного» устройства могут быть практически сколь угодно малыми).
По поводу устройства управления подумать пришлось подольше. Первоначальная идея механически адаптировать для использования на вертикальной поверхности полноценные клавиатуры и мышь была отброшена по причине неэстетичности и явной избыточности целой клавиатуры. Для всех придуманных сценариев было вполне достаточно нескольких клавиш и мышеподобного манипулятора. Вариант этой идеи — купить у китайцев мини-клавиатуру со встроенным тачпадом — тоже был забракован, как требующий дополнительных затрат (пусть и небольших), времени на ожидание доставки (у нас это обычно месяц) и вообще как неспортивный.

Время поскрести по сусекам

В этот день бог послал Александру Яковлевичу:

  • Изрядно уже запылившийся контроллер клон Arduino производства SeeedStudio (на базе Atmega 328) и Ethernet-shield (из давнишних версий, еще без SD-слота) того же происхождения.
  • Переднюю панель от древнего девайса производства Tainet (кажется это было устройство управления ТЧ-модемами, но точно уже не помню). Внутри был двухстрочный ЖКИ-дисплей со встроенной подсветкой, пять кнопок (нормально разомкнутые, общий минус) и линейка из зеленых светодиодов (последняя не пригодилась).
  • Древненький ноутбук с неисправным IDE-контроллером и сильно поцарапанным экраном (из серии «использовать нельзя и выкинуть жалко»), но с живыми USB, VGA и Ethernet (PS/2, bluetooth, wifi в нем отродясь не водились).
  • Провода и прочие аксессуары в ассортименте.
  • Самый главный сюрприз — аналоговый джойстик, о существовании которого я уж и забыл.

Полюбоваться джойстиком

image

И вот, держа в руках пять кнопок и один джойстик, я окончательно понял, как избавиться от крыс… ээ, ну, в смысле, что этого более чем достаточно. Кнопки могут быть использованы для управления автономным контроллером, эмуляции нескольких клавиатурных комбинаций (и даже нескольких их наборов, между которыми можно переключаться) и в качестве кнопок мыши. Саму мышь вполне может изобразить джойстик. К тому же у джойстика есть своя кнопка (срабатывает по нажатию вдоль его вертикальной оси), т. е. кнопок получается уже шесть. Весьма немало.

Контроллер

Сразу предупрежу, что схем и исходников не будет. Смысла в них нет, поскольку описания принципов и упоминания использованных готовых библиотек вполне достаточно, чтобы без трудностей сгородить нечто подобное «под себя».
Возможности ардуино в плане производительности не слишком велики, и заниматься всем одновременно он не может. Поэтому сразу на берегу был определен принцип переключения блоков его функциональности. В каждом цикле программы обрабатывается лишь нажатие клавиш. Для этого используется библиотека Bounce. В ней реализовано подавление дребезга и удобная регистрация событий нажатия/отпускания кнопок.
Алгоритм обработки нажатий клавиш включает в себя функцию включения подсветки на несколько секунд по нажатию любой кнопки, в т.ч. кнопки джойстика (каждое следующее нажатие продлевает время работы подсветки). Если в течение работы подсветки нажать кнопку «меню», то произойдет переход к выбору режима работы. Выбранный режим сохраняется в глобальной переменной, в соответствии со значением которой выполняется та или иная часть остальной программы. В каждом блоке реакция на клавиши и джойстик своя.
На текущий момент блоки такие — автономная (здесь и далее имеется ввиду независимая от внутришкафного ноутбука, но зависимая от сервера) демонстрация текущей погоды, автономная демонстрация краткого прогноза погоды, автономная демонстрация загруженности канала в интернет, управление камерой видеонаблюдения, эмуляция мыши. Две последних функции тоже в техническом плане автономны, но практически без включенного монитора в них нет смысла.
Панель от тайнета отлично вписалась под монитор, ардуино закреплен с внутренней стороны и прикрыт пластиковой коробочкой. Конструкцию хотелось сделать разборной и легко модернизируемой, поэтому использован кусочек макетной платы, на котором распаяны посадочные места для контроллера (у этого клона есть ряд со стандартным шагом дырок) и разъем для шлейфа от передней части. Тут же на макетке помещен транзисторный ключ для управления подсветкой. Монтаж сделан мягким проводом. Сверху нахлобучивается контроллер, а на него шилд. Выглядит как-то так:
image

Макетка без контроллера
image

У контроллера израсходованы все порты. Шесть пинов для обслуживания ЖКИ, шесть для кнопок (в т.ч. джойстика), два для джойстика (из всех только они работают в аналоговом режиме), один для управления подсветкой, остальные для подключения шилда.
Транзистор ключа олдскульный КТ603 в металлическом корпусе. Выбор именно его ничем не обусловлен — просто валялся на виду. Подойдет почти любой n-p-n.
Питание подается от USB-зарядки через двухвостый кабель (второй хвост подключен к ноутбуку, об этом позже).
Джойстик оказался не слишком удобным для монтажа. Крепление у него рассчитано на установку в печатную плату. Порывшись в мусоре, удалось соорудить ему корпус из флакончика от каких-то таблеток, пробки от пластиковой бутылки и кусочка алюминиевого уголка. Уголок закреплен на тайнетовской морде, на уголке пробка, а на пробку туго надевается модернизированный флакончик. Джойстик зажимается между ними и никакого другого крепления не требует (двигается без заметного трения — пластик довольно скользкий). Выглядит так:
image
Не идеал, конечно, но приемлемо.

Чуток покрупнее

Термометр, джойстик и ноутбук в одном шкафу, не считая ардуино

Ноутбук

На ноутбуке Debian, в качестве оконного менеджера dwm. Грузится все это (HDD-то нет) все с того же сервера по сети. К VGA подключен монитор и к USB, как сказано выше, ардуино.

Блоки погоды и загрузки канала в интернет

Тут без особых затей. Сервер по-прежнему получает данные аэропорта, гисметео и выкладывает в виде html c отформатированной соответствующим образом строкой. Для разбора данных METAR используется перловая библиотека Geo::METAR. Ардуино по http строку забирает (используется штатная библиотека Ethernet), парсит и показывает на ЖКИ (используется штатная библиотека LiquidCrystal). Аналогичным образом обрабатываются данные о загрузке канала. Только сведения берутся по SNMP с маршрутизатора. Кнопки используются лишь для переключения между пунктами меню и включения подсветки.

Управление видеокамерой

Безымянная IP-камера китайского происхождения имеет сервоприводы, генерит mjpeg-поток и управляется через встроенный http-сервер. Родной её интерфейс для моих целей неудобен и не используется. Но внимательное разглядывание исходных текстов его страниц позволяет определить URL для получения видео и управления. Видеопоток забирает сервер при помощи софтины Motion. Он же с ним делает, что надо. Внутришкафный компьютер использует уже вторичный поток (motion имеет встроенный http-сервер для этого и разные настройки — частоту обновления, размер изображения, наложение надписей и пр.) и показывает его при помощи ffplay. Управляет камерой контроллер напрямую (делая нужные GET-запросы в соответствии с нажатием клавиш — вверх-вниз, влево-вправо).

Эмуляция мыши и клавиатуры

Тут решение пришло далеко не сразу. Проще всего было бы эмулировать устройства PS/2. Но увы, таких интерфейсов, как уже говорилось, не было. Вторая идея — распотрошить и использовать электронику USB-мыши и клавиатуры — провалилась. Ни один из имевшихся под рукой девайсов не имел маркировку на компонентах, позволяющих их однозначно идентифицировать, найти даташит и использовать. Оставалось одно — штатный FTDI в ардуино и виртуальный ttyUSBx в ноутбуке. Да, в порт можно писать что угодно, но что потом? И желательно без программирования, штатными средствами. Нашел не сразу, но теперь я знаю о существовании замечательного инструмента xdotool. Принимая команды из терминала или из стандартного потока, эта штука производит передвижение мыши, нажатие кнопок мыши и клавиатуры (вывод клавиатуры может быть направлен в нужное окно). Скажем для передвижения мыши передаются команды вида

xdotool mousemove_relative x y

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

xdotool click button

где button — номер кнопки (1 — левая, 2 — средняя, 3 — правая). В моем варианте пять кнопок используются так: левая и правая — соответственно левый и правый клик, верхняя — двойной клик, средняя — при первом нажатии имитирует нажатие левой кнопки мыши, при втором имитирует отпускание кнопки мыши (для выделения текста например). На стороне компьютера команды можно принимать прямо в xdotool. Сначала настроить последовательный порт, скажем так:

stty -F /dev/ttyUSB0 raw ispeed 9600 ospeed 9600 -ignpar cs8 -cstopb -echo

потом направить из него поток:

cat /dev/sttyUSB0 > xdotool - 

Но это не очень гибко, поскольку ограничивает применение связки только управлением мышью и клавиатурой. Лучше использовать специальный скрипт, который читает поток, а потом в зависимости от содержимого направляет его куда надо, в т.ч. и в xdotool. Тем самым можно наладить выполнение чего угодно. Таким образом помимо эмуляции мыши у меня реализовано включение/выключение монитора. Вернее сказать, сам монитор не трогается, а производится включение/выключение режима сна командой xset dpms с параметрами. Работает это так: нажимаешь кнопку джойстика — просыпается, нажимаешь еще раз — засыпает. Не сильно полезно, но забавно.
В итоге получилась простая для реализации конфигурация, которую можно использовать практически в любых сценариях домашнего мониторинга, управления и т.п.
Ну, вот, собственно, и всё. Спасибо за внимание.

Автор: murzin

Источник

* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js