[Из песочницы] IP KVM своими руками

Эта статья написана под впечатлением от другой — большое спасибо автору! В этой статье почти удалось сделать собственный IP KVM Switch, и это круто! Но объясню, почему почти. Да, там все работает как и написал автор… До момента перезагрузки в биос — там вся магия рассеивается и сколько не старайся, ничего не происходит.

Решено было исправить это досадное недоразумение и как можно дешевле и компактней. Начнем со стереотипов Raspberry Pi и Arduino, а в следующей статье будет продолжение уже на другом железе.

Итак, что нам понадобится:

1. Плата видеозахвата обязательно с поддержкой UVC драйвера, вроде этой.Вариантов
полно на алиекспрессе и других китайских магазинах.

e2404ba77ae94301b2bb656fa7a2a933.jpg

UVC это стандартизированный открытый драйвер который по умолчанию входит в большинство линукс дистрибутивов, с другими драйверами могут быть проблемы.

2. VGA to AV Конвертер:

0937af93b8524cf296185938bb8380af.jpg
5494d6501cb047d0ae6f6f44b6f851fc.jpg

Обратите внимание! Нужен именно VGA to AV, а не наоборот.

3. Arduino UNO, именно UNO, так как на ней есть чип Atmega16u2, он нас интересует в первую очередь. Вот он рядом с USB портом, так же бывают ардуины с чипом Atmega8u2 подойдут и с тем и с тем.

6f4d4066d1ad418082cd4c506c205141.jpg

4. Ну и конечно Raspberry Pi, у меня был версии 2 b поэтому все написанное в этой статье актуально именно для него, но в целом думаю не должно возникнуть особых сложностей и с другими моделями малины.

Заливаем дистрибутив


Что ж вводные данные даны, пожалуй приступим.Я использовал дистрибутив 2015–05–05-raspbian-wheezy, вероятно это не принципиально, дальнейшие манипуляции должны подойти для любого дистрибутива основанного на Debian.

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

Переходим в консоль, обновляем пакеты:

sudo apt-get update && sudo apt-get upgrade –y

Передача видео
Проверяем определилась ли плата:
ls /dev/video*

Должно выдать что-то вроде: /dev/video0.

Устанавливаем Motion, трансляцию захваченного изображения будем вести именно через него:

sudo apt-get install motion -y

Редактируем конфиг автозапуска:
sudo nano /etc/default/motion

В строке start_motion_daemon ставим «yes». Сохраняем изменения Ctrl + x, y, Enter.

Редактируем конфиг самого motion (а):

sudo nano /etc/motion/motion.conf

Меняем значения параметров как указано далее:

Параметр определяет запуск приложения в качестве службы:

daemon on

Эти параметры определяют разрешение передаваемого изображения, смысла ставить большее разрешение нет, т.к. захват видео ограничен стандартами PAL или SECAM, разрешение коих 720×576. Это кстати досадный недостаток, но об этом позднее.
width 800
height 600

Частота захвата кадров:
framerate 25

Отключаем сохранение скриншотов:
output_normal off

Качество передачи изображения:
webcam_quality 100

Частота передачи кадров:
webcam_maxrate 25

Отмена ограничения на подключение с других ip
webcam_localhost off

Сохраняем изменения Ctrl + x, y, Enter.

Перезагружаем распберри:

sudo reboot

Ждем пару минут если все сделали правильно должен загореться светодиод на плате видео захвата.

Подключаемся браузером к порту 8081 распберри и видим серый или синий прямоугольник с бегущим снизу временем.

298b9e040b2b4dffaeb67d62d4771339.jpg

Процесс пошел, ищем жертву для захвата сигнала с VGA порта, подключаем к порту «VGA IN» конвертера, а плату видеозахвата к «VIDEO OUT». Должна получиться примерно такая картинка, не пугайтесь у меня плохой кабель поэтому изображение «двоит», пробовал с другим изображение было лучше, но разрешение не изменить. 720×576 это ограничение конвертера и платы видео захвата, которое при всем желании не преодолеть.

fada058022434103844242b324d1f994.jpg

Что ж передавать изображение научились, осталось дело за малым — передать управление.

Передача управления
Для этого, как вы уже догадались, будем использовать ардуину. Выбор пал на Arduino UNO неспроста, там есть очень нужная для наших целей микросхема с названием Atmega16u2, только благодаря ей мне удалось заставить БИОС компьютера определить arduino как USB клавиатуру. По умолчанию в составе платы ардуино эта микросхема выполняет роль USB to Serial конвертера для заливки прошивки в микроконтроллер Atmega328p, большая прямоугольная микросхема на плате ардуино. По сути же Atmega16u2 является то же микроконтроллером, но с важным отличием, она способна напрямую работать с шиной USB. Atmega16u2, при наличии нужной прошивки, может эмулировать практически любое USB устройство. Понимаете к чему я веду? Мы прошьем это чудо инженерной мысли и заставим трудиться на благо общества.

Прошивка Atmega16u2


На просторах интернета была найдена прошивка, которая превращает Atmega16u2 в USB клавиатуру принимающую команды, определенного вида, через Serial Port.

Инструкция в данной статье написана для windows, линуксоиды же могут воспользоваться этой.

И так приступим, для прошивки потребуется утилита от производителя под названием Flip. Качаем, устанавливаем, запускаем и вот перед нами окно программы:

f3c349cba8494a0cafca433486c81678.jpg

Сначала кнопки (галки) не активны, это нормально, подключаем ардуину к компьютеру и замыкаем — размыкаем два крайних контакта со стороны USB порта, RESET и GND.

f9686047f5b7492bab0c65ff04c20331.jpg

В системе должно появиться новое устройство под названием, как ни странно, ATmega16u2 устанавливаем драйвер (в папке с программой), выбираем в программе flip вкладку «Settings» → «Communication» → «USB» → «open», кнопки должны стать активны. На всякий случай можно сделать бэкап прошивки, чтоб можно было все вернуть на место. В меню «File» нажимаем «Load HEX File», программа требовательна к путям, лучше всего положить файл прошивки в корень диска C:, выбираем нужный hex файл с прошивкой, проверяем стоят ли галки «Erase», «Program», «Verify» и нажимаем «Run». Отключаем — подключаем arduino и вуаля… Теперь мы больше не сможем загружать прошивки в ардуино через встроенный USB, зато получили отличную клавиатуру без кнопок.

Не переживайте по поводу прошивки arduino, прошивку можно будет загрузить из Arduino IDE через отдельный USB To TTL адаптер, хотя надо сказать, теперь это будет менее удобно.

Подключаем USB To TTL адаптер, например такой:

0080164058354589bdd703724ab5af75.jpg

Нам понадобятся Белый, зеленый и черный контакты это RX, TX и GND соответственно, подключаем их к пинам с такими же обозначениями на ардуине, только наоборот RX к TX, а TX к RX. Красный контакт использовать не следует!

Подключаем USB To TTL к компьютеру, устанавливаем драйвера, в диспетчере устройств должен появиться новый COM Port. Открываем arduino IDE и выставляем: Плата — Arduino/Genuino Uno, Порт — наш новоиспеченный последовательный порт.

Приступаем к прошивке arduino


Добавим необходимую библиотеку в arduino IDE: Переходим по ссылке github.com/SFE-Chris/UNO-HIDKeyboard-Library нажимаем «Clone or download» → «Download ZIP». далее в arduino IDE выбираем вкладку «Скетч» → «Подключить библиотеку» → «Добавить .ZIP библиотеку» и выбираем только что скачанный zip архив.

Подготовка закончена, переходим непосредственно к прошивке. Копируем мою писанину:

Arduino — Sketch
#include 
HIDKeyboard keyboard;

int sbor;

void setup() {
 keyboard.begin();
}
void loop() { 
  while (Serial.available()) {//запуск цикла при появлении данных
    sbor += Serial.read();//считывание данных, сложение в десятичном виде
      if (sbor == 27){//появление символа управляющей последовательности
        for (int i=0; i<=4; i++ ){//сложение последовательности
          if (sbor == 165) {//для определения F1-F12 на разных терминалах могут быть разные значения
          sbor += sbor;
      }
        sbor += Serial.read();
        delay(1);
  }  
 }
}
  if (sbor > 0) {
    //переход по десятичной сумме последовательности
      switch (sbor){
        case 505: keyboard.pressSpecialKey(F1); break;
        case 506: keyboard.pressSpecialKey(F2); break;
        case 507: keyboard.pressSpecialKey(F3); break;
        case 508: keyboard.pressSpecialKey(F4); break;
        case 509: keyboard.pressSpecialKey(F5); break;
        case 511: keyboard.pressSpecialKey(F6); break;
        case 512: keyboard.pressSpecialKey(F7); break;
        case 513: keyboard.pressSpecialKey(F8); break;
        case 340: keyboard.pressSpecialKey(F9); break;
        case 341: keyboard.pressSpecialKey(F10); break;
        case 343: keyboard.pressSpecialKey(F11); break;
        case 344: keyboard.pressSpecialKey(F12); break;
        case 13: keyboard.pressSpecialKey(ENTER); break;
        case 22: keyboard.pressSpecialKey(ESCAPE); break;
        case 127: keyboard.pressSpecialKey(BACKSPACE); break;
        case 9: keyboard.pressSpecialKey(TAB); break;
        case 32: keyboard.pressSpecialKey(SPACEBAR); break;
        case 26: keyboard.pressSpecialKey(PAUSE); break;
        case 292: keyboard.pressSpecialKey(INSERT); break;
        case 456: keyboard.pressSpecialKey(HOME); break;
        case 295: keyboard.pressSpecialKey(PAGEUP); break;
        case 294: keyboard.pressSpecialKey(END); break;
        case 296: keyboard.pressSpecialKey(PAGEDOWN); break;
        case 182: keyboard.pressSpecialKey(RIGHTARROW); break;
        case 183: keyboard.pressSpecialKey(LEFTARROW); break;
        case 181: keyboard.pressSpecialKey(DOWNARROW); break;
        case 180: keyboard.pressSpecialKey(UPARROW); break;
        case 293: keyboard.pressSpecialKey(DELETE); break;
        case 320: keyboard.pressSpecialKey((CTRL | ALT), DELETE); break; //для вызова ctl+alt+del нажать alt + del 
        case 346: keyboard.pressSpecialKey(ALT, F4); break; //для вызова alt+f4 нажать shift + F4
        
        default:  keyboard.pressKey(sbor); break;
  }
  //Serial.println(sbor);//только для отладки без подключения к usb
  keyboard.releaseKey();
  sbor = NULL;
 } 
}


вставляем в arduino IDE и нажимаем кнопку проверки. Вот сейчас начнется самый ответственный этап, тут самое главное поймать момент, мало у кого получается с первого раза. Нажимаем кнопку загрузки в arduino IDE, сначала побегут белые строчки с логом компиляции, за ними последуют оранжевые, это уже установка соединения с последовательным портом, вот этот самый момент надо поймать и успеть нажать на плате ардуины кнопку RESET. Должна произойти загрузка прошивки, если все удачно вы увидите надпись вроде этой
avrdude: reading on-chip flash data:

Reading | ################################################## | 100% 0.34s

avrdude: verifying ...
avrdude: 2934 bytes of flash verified

avrdude done.  Thank you.

Если после нескольких попыток загрузка прошивки так и не произошла, попробуйте поменять местами контакты RX и TX, а также проверьте надежно ли подключен контакт GND.

Финишная прямая


Открываем консоль на распберри и пишем:
sudo raspi-config

Откроется меню настройки распберри, выбираем «Advanced Options» → «Serial» и выбираем «No».

Возможно эти манипуляции и не понадобятся, так, перестраховка. Этот параметр определяет, будет ли ОС на малине взаимодействовать с serial портом, это взаимодействие нужно в основном для отладки, так что смело отключаем, нам оно будет только мешать, т.к. с ардуиной мы будем общаться именно через этот порт, а система будет засорять эфир.

Устанавливаем программу minicom.

Minicom — простенькая программа для работы с serial портом.

sudo apt-get install minicom -y

Задаем права на доступ к устройству, /dev/ttyAMA0 — это тот самый сериал порт.
sudo chown pi /dev/ttyAMA0
sudo chmod 744 /dev/ttyAMA0

Запускаем minicom:
sudo minicom -s

Откроется меню программы, выбираем пункт «Serial port setup», откроется еще одно меню, выбираем «Serial Device» нажатием на клавишу A, прописываем /dev/ttyAMA0, нажимаем Enter, далее выбираем пункт Bps/Par/Bits под буквой E, появляется очередное меню нажимаем C и Q строчка Current: должна выглядеть вот так »9600 8N1» нажимаем Enter. Убедимся что в строчках F — Hardware Flow Control: и G — Software Flow Control: стоит No, в общем все должно быть как на скриншоте ниже, нажимаем Enter.

f1afa78cd6484ca38e8f1e176720a07c.jpg

Сохраним эти настройки как настройки по умолчанию «Save setup as dfl» и закрываем «Exit from Minicom».

Подключение


Едем дальше, теперь у нас практически все готово, осталось только подключить ардуину к serial порту малины, вот как-то так:

be20aedade1b486d86a89b74244f79ca.jpg

Здесь есть один момент, у ардуино и распберри разные уровни напряжения и по идее их нужно согласовать, советую ознакомиться со статьей.

Хотя у меня все заработало напрямую без согласования, не следует подражать плохому примеру и приобрести преобразователь логических уровней, самый простой выглядит так:

3083ef65692a46e5841793c8266704b7.jpg

Или хотя бы собрать делитель напряжения на резисторах.

d8496b1d26e54814992b36393e1ae6a8.jpg

Запуск
Все готово, можно начинать.

Проверяем все соединения, вкючаем raspberry pi, переходим в консоль малины. Сразу оговорюсь я подключался к малине через ssh, в качестве клиента использовал KiTTY (модифицированную версию PuTTY), это важно т.к. с другими терминалами значения передаваемых клавиш могут быть иными и соответственно нужно будет сделать поправку на ветер — поменять номер перехода switch case.

В общем передаю вам в руки как говорится «as is». Что ж на этом пожалуй закончу, самодельный IP KVM готов.

P. S.


На последок опишу что получилось в сухом остатке.

Плюсы:


 — Цена
 — Устройство получилось относительно недорогим
 — Raspberry Pi: примерно 2700 руб.
 — Arduino UNO: примерно 400 руб.
 — VGA to AV конвертер: примерно 700 руб.
 — Плата видеозахвата: 500 руб.
 — Итого: 4300 руб.

 — Тонкая настройка
Можно перехватывать практически любые комбинации и назначать на них практически любые клавиши вплоть до KEYBOARDPOWER и VOLUMEUP, кстати возможные значения можно посмотреть в заголовочном файле HIDKeyboard.h, а можно и добавить свои.

Минусы:


 — Торможение как видео, так и передачи нажатий
 — Второй и самый большой это качество изображения, здесь просто необходим грустный смайлик, оно ужасно, даже если убавить разрешение на целевом компьютере до минимума, максимум что можно будет сделать, это настроить БИОС и выбрать пункт в загрузчике. Но разве собственно не для этого нужен KVM?… А для всего остального существует радмин и ему подобные.

To be continued…

Комментарии (0)

© Habrahabr.ru