Sl-Alex домашняя лаборатория

AVRLIRC: ИК приёмник для компьютера

Просмотров: 2848Комментарии: 0
Проекты
AVRLIRC: ИК приёмник для компьютера

Как всё начиналось

Когда-то давно, когда пульт управления, подключаемый к компьютеру считался не более чем чудачеством, я решил, что мне такая штука не помешает. Я перепробовал кучу самодельных ИК-приёмников из тех, которые предлагал мне SlyControl и в итоге просто добавил соответствующие возможности к уже завершённому на тот момент проекту Serial LCD Graph, заодно немного его переработав. Так получилась вторая версия индикатора, которая и стояла у меня в системнике не один год.

Но время шло, и однажды я понял, что хочу поставить Linux в качестве своей основной ОС. Пришлось задуматься и о поддержке своих устройств в Linux. Проблему я решил отложить — индикатор мне срочно не был нужен, а вот к дистанционному управлению я настолько привык, что рука то и дело тянулась к временно попавшему в немилость пульту. Я уже слышал о LIRC, но при более близком знакомстве был поражен огромным количеством поддерживаемых ИК-приёмников. Их было ещё больше, чем поддерживал в своё время SlyControl.

Пришлось немного подумать. Во-первых, я сразу отбросил все приёмники, которые подключались на дополнительные линии COM-порта (DCD, например). У меня COM-порта просто не было, а преобразователи USB-COM были не в состоянии обеспечить необходимые тайминги, да и компьютер грузить этим не хотелось. Использовать вход звуковой карты тоже казалось не очень красивым решением (а вдруг буду подключать микрофон и петь караоке?). Единственным вариантом стали устройства на базе микроконтроллеров, подключаемые к USB, как к самой распространённой шине.

Из них я решил выбрать только те, которые были собраны на базе микроконтроллеров AVR фирмы Atmel (ну просто они мне нравятся), отбросив IgorPlug и все, которые были сделаны с использованием программного USB (они у меня даже в идеальных условиях почему-то периодически подвисали). В итоге остался только один вариант. Имя ему — AVRLIRC. Оригинальный проект находится здесь, автор — Paul Fox. Я просто добавил USB-COM преобразователь, сделал под него более-менее культурную печатную плату и убрал из исходников отладочные фрагменты кода. Впрочем, вы можете использовать и оригинальный проект, просто плату сделаете самостоятельно.

Схема и плата

Рисунок 1 — Схема AVRLIRC с подключением по USB.

Рисунок 1 — Схема AVRLIRC с подключением по USB.

Поз. Обозн.НаименованиеКол-воПримечание
C1..C30.13SMD 0805
C4,C512p2SMD 0805
C6,C710.0x6.3V2SMD тантал
R1,R202SMD 0805, в качестве предохранителя
R35101SMD 0805
R410k1SMD 0805
R5681SMD 0805
DD1FT232RL1
DD2ATtiny2313A-20SU1SMD
X1PLS4-R1Каждый второй вывод развёрнут на 180º
HL1RED1SMD 0805
ZQ114.74561HC49-S

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

Рисунок 2 — Печатная плата AVRLIRC.

Рисунок 2 — Печатная плата AVRLIRC.

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

Запускаем железо

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

lsusb | grep 0403

Мы увидим все устройства вендора FTDI, среди которых должно быть и наше. Если всё нормально, наш пульт в итоге должен подключиться в /dev/ttyUSB*, вместо звёздочки — порядковый номер последовательного порта USB. У меня это /dev/ttyUSB0. Вы можете совсем обнаглеть, попробовать ввести "cat /dev/ttyUSB0" и понажимать кнопки на пульте. В консоль при этом синхронно с нажатиями должен идти какой-то мусор. Значит, всё в порядке, можно двигаться дальше. В LIRC нет стандартного драйвера для нашей железки, поэтому Paul Fox написал небольшую программку, которая называется avrlirc2udp и которая скомпилировалась вместе с прошивкой. Вы не компилировали прошивку, а взяли готовую из архива? Ну и ладно, программку можете взять там же. Положите её куда-нибудь, она нам сейчас понадобится. Вообще я у себя завёл в домашней папке папку "scripts" и всякие небольшие скрипты и такие программки держу там, поэтому в дальнейшем буду указывать пути на своей машине.

Запустите avrlirc2udp командой

./avrlirc2udp -t /dev/ttyUSB0 -H -h localhost -p 5000

Приведённая строка означает, что мы запускаем нашу программу для устройства /dev/ttyUSB0 на скорости 115200 (флаг -H), LIRC будет работать на нашем (localhost) компьютере на порту под номером 5000. Вы можете выбрать любой другой порт, либо даже управлять удалённым компьютером.

Запускаем LIRC

Предполагается, что LIRC и irexec у вас уже установлены. Если нет — сделайте это немедленно, мы переходим к настройке LIRC! Для правильной работы LIRC надо указать только две вещи: драйвер (udp) и порт, который он будет слушать (5000). Это нужно прописать в конфиге LIRC, находящегося в "/etс/lirc/hardware.conf", параметры REMOTE_DRIVER и REMOTE_DEVICE соответственно. Там же можно и задать название своего пульта (у меня по умолчанию — REMOTE="Network (UDP)"). Сохраняем конфиг и переходим к прописыванию кнопок. Для этого существует программка irrecord. Более подробную информацию о ней вы всегда сможете прочитать, введя "man irrecord". Для начала записи кнопок запустите avrlirc2udp (если она у вас не запущена), как вы делали это ранее, и введите

irrecord -H udp -d 5000 lircd.conf

Внимательно читайте всё, что вам говорит программа. Обычно всё, что требуется — это пару раз нажать на Enter, затем понажимать разные кнопки на пульте, пока две линии на экране не заполнятся точками (таким образом программа определяет временные интервалы вашего пульта), затем вводите имя для новой кнопки, нажимаете её на пульте, переходите к следующей, и так до тех пор, пока у вас кнопки не закончатся :). Перед самым выходом программа попросит вас понажимать много раз подряд одну и ту же кнопку. Не подумайте, это не с целью заставить вас позаниматься физическими упражнениями. Таким образом определяется, есть ли в вашем пульте так называемый "toggle bit", бит, который переключается после каждой переданной посылки. Закончив записывать кнопки, ложим полученный файл (lircd.conf) в /etc/lirc. Вы ещё не устали? Уже практически всё. На этом этапе вы уже можете запустить LIRC командой "sudo service lirc start", затем запустить irw и, нажимая на кнопочки, смотреть, как их названия весело мелькают в консоли.

Насмотрелись? Сделаем ещё одно чёрное дело и потом перейдём к настройке программ. Напишем небольшой скрипт, который будет мониторить, запущены ли программы и при необходимости из запускать. Назовём его avrlirc_check.sh

#!/bin/bash
USBTTY="/dev/ttyUSB0"
AVRLIRC2UDP="/home/sl-alex/scripts/avrlirc2udp"
export DISPLAY=:0
if [ `ps ax | grep avrlirc2udp | grep -v grep | wc -l` -eq 0 ]; then 
{
	echo "avrlirc демон не запущен. Запускаем..."
	$AVRLIRC2UDP -t $USBTTY -H -h localhost -p 5000
	exit
}
fi 
if [ `ps ax | grep irexec | grep -v grep | wc -l` -eq 0 ]; then 
{
        echo "irexec демон не запущен. Запускаем..."
        irexec --daemon
        exit
}
fi

Добавьте этот скрипт в список заданий cron c запуском с интервалом в одну минуту. Вот теперь если вы вдруг переподключили приёмник или USB по какой-то причине переинициализировался, пульт максимум через минуту будет работать.

Настраиваем программы

Все действия при нажатии на кнопки пульта прописаны в файле .lircrc, который по умолчанию ищется в домашней папке текущего пользователя. Это обычный текстовый файл с простым синтаксисом следующего вида:

# Управление громкостью
begin
	prog = irexec
	button = KEY_VOLUMEUP
	repeat = 2
	config = xdotool key XF86AudioRaiseVolume
	flags = quit
end
# Запуск программы
begin
	prog = irexec
	button = KEY_PROG1
	config = clementine &
end
# пример передачи команд программе
begin
	button = KEY_FORWARD
	prog = irexec
	repeat = 3
	config = if [ $(ps -eo cmd | grep -c ^clementine) -eq 1 ]; then (clementine --seek-by 5); fi
end
# пример управления vlc через его собственный LIRC-плагин
begin
	prog = vlc
	button = KEY_PAUSE
	config = key-play-pause
	repeat = 0
end

Как мне кажется, эта куча строк всё-таки нуждается в некоторых комментариях. Во-первых, пару слов о xdotool. Это небольшая консольная программка, которая позволяет эмулировать ввод с клавиатуры или мышки и даже управлять окнами в системе. Второй пример - запуск clementine. Но почему в секции PROG опять написано irexec? Дело в том, что ни clementine, ни xdotool, ни многие другие программы, с которыми вам придётся столкнуться, не поддерживают LIRC сами по себе. Чтобы передавать им команды и нужен irexec. И даже для того, чтобы запустить vlc, у которого есть встроенная поддержка LIRC, всё равно нужен irexec. Именно поэтому он всегда должен быть запущен, как настоящий демон. Помните, раньше мы написали скрипт, который мониторит наличие irexec среди запущенных процессов? Так вот, это ещё одна причина, по которой мы его и писали.

Это описание синтаксиса файла .lircrc не претендует на полноту, однако его достаточно для того, чтобы вы могли понять простейшие вещи. В LIRC можно описывать группы действий, которые будут выполняться только после нажатия какой-либо кнопки и делать некоторые другие вещи, но для этого вам нужно будет уже подробнее изучать формат файла, который достаточно подробно описан здесь. Мне, например, хватило и минимального функционала, хотя я и поигрался с различными конфигурациями.

Заключение

В заключение не могу не сказать ещё раз: этой статьи не было бы, если бы не автор проекта AVRLIRC - Paul Fox. Спасибо ему за его разработку! На момент написания этой статьи приёмник уже полгода жил и работал у меня в системнике и, честно говоря, мне пришлось проделать весь путь, всё, о чём я написал, с нуля — настолько я уже всё успел позабыть. Это как нельзя лучше свидетельствует или о моей плохой памяти, или о надёжности устройства. Хочется верить, что с памятью у меня всё в порядке :).