Блог о Gentoo и около-линуксовым штукам

20 марта 2016 г.

Делаем IR приёмник для LIRC (igorplugusb)

16:51 Опубликовал Дмитрий Исаенко , , Нет комментариев
Сегодня будем делать инфракрасный приёмник. В таком качестве мною был выбран распространённый igorplugusb — старая, не лишенная недостатков, но очень простая в создании схема. Прекрасный пример реализации я нашел на сайте JumpTruck, который в свою очередь почти без изменений списан с проекта Дика Стрифланда (Dick Streefland). Но не смотря на это, готовые схемы мне не понравились. Мне хотелось micro-usb штекер и миниатюрную плату, поэтому я решил переделать реализацию под себя. 
Для новой разводки был использован бесплатный (условно) Eagle cad, который прекрасно подходит для разработки небольших схем и обладает огромным набором библиотек компонентов. В конечном итоге у меня получилось следующее (кликабельно):



Скачать их, вместе с прошивкой и самую-малость-кривым-PDF для лазерного утюга можно отсюда: https://cloud.mail.ru/public/CH4D/Sw3D5nLh5

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

Если вы в первый раз используете Eagle (у меня это версия 7.4.0), то после установки и первого запуска он предложит вам создать папку по-умолчанию для проектов и всего-такого-прочего. В неё-то и надо скопировать директории IR3 и lib.

Теперь о том, что касается компонентов (нагло содрано):
Комп. Значение Корпус Описание
C1 27pf 0603 Керамический конденсатор
C2 27pf 0603 Керамический конденсатор
C3 0.1uf 0603 Керамический конденсатор
C4 4,7uf 0603 Конденсатор (тут у автора была ошибка - нужен именно 4,7uf)
C5 100uf E2,5-6 Электролит. конденсатор
D1 3,6V SOD80C Стабилитрон 3.6V
D2 3,6V SOD80C Стабилитрон 3.6V
IC1 ATtiny2313 DIL20 ATTINY2313-20PU
LED1 LED3MM 3mm LED (синенький)
Q1 12MHz HC49U70 Кварц
R1 68 0805 (или 0603) 68Ом резистор
R2 1k5 0603 1,5КОм резистор
R3 68 0805 (или 0603) 68Ом резистор
R4 330 0603 330Ом резистор
R5 22k 0603 22КОм резистор
R6 100 0603 100Ом резистор
R7 4,7КОм 0603 4,7КОм резистор
U$1 TSOP4838 782-TSOP4838 IR приёмник 38kHz
X1 Micro-usb USB-MICRO-SMD micro-usb разъём

Теперь несколько слов о прошивке. Я использовал, как и Jumptruck, прошивку main.hex из папки IR из пакета 1,4. Сейчас на сайте доступен для скачивания архив 1.7 — что там внутри и как оно работает я не знаю. Если есть желание проверить, то пожалуйста.

Прошивал я своим программатором usbasp через avrdude. Тут проблем у вас возникнуть не должно. Как настроить окружение я писал в одной из предыдущих публикаций. Тут же традиционно показываю выкладку:
 # avrdude -c usbasp -pt2313 -U flash:w:main.hex                     

avrdude: AVR device initialized and ready to accept instructions

Reading | ################################################## | 100% 0.01s

avrdude: Device signature = 0x1e910a
avrdude: NOTE: FLASH memory has been specified, an erase cycle will be performed
         To disable this feature, specify the -D option.
avrdude: erasing chip
avrdude: reading input file "main.hex"
avrdude: input file main.hex auto detected as Intel Hex
avrdude: writing flash (2006 bytes):

Writing | ################################################## | 100% 18.64s


avrdude: 2006 bytes of flash written
avrdude: verifying flash memory against main.hex:
avrdude: load data flash data from input file main.hex:
avrdude: input file main.hex auto detected as Intel Hex
avrdude: input file main.hex contains 2006 bytes
avrdude: reading on-chip flash data:

Reading | ################################################## | 100% 8.66s


avrdude: verifying ...
avrdude: 2006 bytes of flash verified
avrdude: safemode: Fuses OK

avrdude done.  Thank you.

 # avrdude -pt2313 -U hfuse:w:0xdb:m -U lfuse:w:0xef:m -c usbasp

avrdude: AVR device initialized and ready to accept instructions

Reading | ################################################## | 100% 0.01s

avrdude: Device signature = 0x1e910a
avrdude: reading input file "0xdb"
avrdude: writing hfuse (1 bytes):

Writing | ################################################## | 100% 0.02s

avrdude: 1 bytes of hfuse written
avrdude: verifying hfuse memory against 0xdb:
avrdude: load data hfuse data from input file 0xdb:
avrdude: input file 0xdb contains 1 bytes
avrdude: reading on-chip hfuse data:

Reading | ################################################## | 100% 0.00s

avrdude: verifying ...
avrdude: 1 bytes of hfuse verified
avrdude: reading input file "0xef"
avrdude: writing lfuse (1 bytes):

Writing | ################################################## | 100% 0.02s

avrdude: 1 bytes of lfuse written
avrdude: verifying lfuse memory against 0xef:
avrdude: load data lfuse data from input file 0xef:
avrdude: input file 0xef contains 1 bytes
avrdude: reading on-chip lfuse data:

Reading | ################################################## | 100% 0.00s

avrdude: verifying ...
avrdude: 1 bytes of lfuse verified

avrdude: safemode: Fuses OK

avrdude done.  Thank you.

Перейдём к настройке LIRC. 

Для начала, необходимо правильно сконфигурировать ядро. Для этого включим следующие необходимые фичи через menuconfig.
Device Drivers -> Multimedia Support
  [*]   Remote Controller support
  [*]   Remote controller decoders  ---> 
      <M>   LIRC interface driver
      <M>     Enable IR to LIRC bridge
      <M>   Enable IR raw decoder for the NEC protocol
      <M>   Enable IR raw decoder for the RC-5 protocol
      <M>   Enable IR raw decoder for the RC6 protocol
      <M>   Enable IR raw decoder for the JVC protocol
      <M>   Enable IR raw decoder for the Sony protocol
      <M>   Enable IR raw decoder for the Sanyo protocol
      <M>   Enable IR raw decoder for the Sharp protocol
      <M>   Enable IR raw decoder for the MCE keyboard/mouse protocol
      <M>   Enable IR raw decoder for the XMP protocol
  [*]   Remote Controller devices  --->
         IgorPlug-USB IR Receiver
  Input device support  --->
      <*>   Event interface  (не знаю на сколько это актуально)

После того, как мы настроили ядро и перезагрузились, при подключении устройства в dmesg должно появиться следующее:
[57672.609962] usb 1-5.2: new low-speed USB device number 9 using xhci_hcd
[57672.699435] usb 1-5.2: New USB device found, idVendor=03eb, idProduct=0002
[57672.699438] usb 1-5.2: New USB device strings: Mfr=0, Product=2, SerialNumber=0
[57672.699439] usb 1-5.2: Product: USBtiny IR/LCD
[57672.700146] Registered IR keymap rc-hauppauge
[57672.700217] input: IgorPlug-USB IR Receiver as /devices/pci0000:00/0000:00:14.0/usb1/1-5/1-5.2/1-5.2:1.0/rc/rc0/input20
[57672.700250] rc0: IgorPlug-USB IR Receiver as /devices/pci0000:00/0000:00:14.0/usb1/1-5/1-5.2/1-5.2:1.0/rc/rc0
[57672.700309] input: MCE IR Keyboard/Mouse (igorplugusb) as /devices/virtual/input/input21
[57672.700452] rc rc0: lirc_dev: driver ir-lirc-codec (igorplugusb) registered at minor = 0
Соответсвенно в /dev теперь есть устройство /dev/lirc0.

Теперь самое интересное - заставить всё это дело работать. Версия lirc-0.9.0-r5, которая есть сейчас в portage безумно устарела и, строго говоря, не работает. Поэтому я решил написать ebuild для более свежей, но не последней версии 0.9.3a.

Вот выкладка:
$ cat lirc-0.9.3a.ebuild    
# Copyright 1999-2016 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
# $Id$

EAPI=4

inherit eutils systemd flag-o-matic autotools

DESCRIPTION="decode and send infra-red signals of many commonly used remote controls"
HOMEPAGE="http://www.lirc.org/"

MY_P=${PN}-${PV/_/}

if [[ "${PV/_pre/}" = "${PV}" ]]; then
        SRC_URI="mirror://sourceforge/lirc/${MY_P}.tar.bz2"
else
        SRC_URI="http://www.lirc.org/software/snapshots/${MY_P}.tar.bz2"
fi

LICENSE="GPL-2"
SLOT="0"
KEYWORDS="amd64 ppc ppc64 x86"
IUSE="doc static-libs X audio irman ftdi inputlirc iguanair"

S="${WORKDIR}/${MY_P}"


REQUIRED_USE="
        iguanair? ( irman )
"
DEPEND="
        doc? ( app-doc/doxygen )
"

RDEPEND="
        X? (
                x11-libs/libX11
                x11-libs/libSM
                x11-libs/libICE
        )
        audio? ( 
                >media-libs/portaudio-18 
                media-libs/alsa-lib
        )
        irman? ( media-libs/libirman )

        iguanair? ( app-misc/iguanaIR )

        ftdi? ( dev-embedded/libftdi:0 )

        inputlirc? ( app-misc/inputlircd )
"

pkg_setup() {

        # set default configure options
        LIRC_DRIVER_DEVICE="/dev/lirc0"

        filter-flags -Wl,-O1
}

src_prepare() {
        # Rip out dos CRLF
        edos2unix contrib/lirc.rules
}

src_configure() {
        econf \
                $(use_enable static-libs static) \
                $(use_with X x)
}


src_install() {
        emake DESTDIR="${D}" install

        newinitd "${FILESDIR}"/lircd lircd
        newinitd "${FILESDIR}"/lircmd lircmd
        newconfd "${FILESDIR}"/lircd.conf.4 lircd

        insinto /etc/modprobe.d/
        newins "${FILESDIR}"/modprobed.lirc lirc.conf

        newinitd "${FILESDIR}"/irexec-initd irexec
        newconfd "${FILESDIR}"/irexec-confd irexec

        systemd_dounit "${FILESDIR}"/irexec.service
        systemd_dounit "${FILESDIR}"/lirc.service
        systemd_dounit "${FILESDIR}"/lircm.service

        if use doc ; then
                dohtml doc/html/*.html
                insinto /usr/share/doc/${PF}/images
                doins doc/images/*
        fi

        keepdir /etc/lirc
        if [[ -e "${D}"/etc/lirc/lircd.conf ]]; then
                newdoc "${D}"/etc/lirc/lircd.conf lircd.conf.example
        fi

        use static-libs || rm "${D}/usr/$(get_libdir)/liblirc_client.la"
}

pkg_preinst() {

        local dir="${EROOT}/etc/modprobe.d"
        if [[ -a "${dir}"/lirc && ! -a "${dir}"/lirc.conf ]]; then
                elog "Renaming ${dir}/lirc to lirc.conf"
                mv -f "${dir}/lirc" "${dir}/lirc.conf"
        fi

        # copy the first file that can be found
        if [[ -f "${EROOT}"/etc/lirc/lircd.conf ]]; then
                cp "${EROOT}"/etc/lirc/lircd.conf "${T}"/lircd.conf
        elif [[ -f "${EROOT}"/etc/lircd.conf ]]; then
                cp "${EROOT}"/etc/lircd.conf "${T}"/lircd.conf
                MOVE_OLD_LIRCD_CONF=1
        elif [[ -f "${D}"/etc/lirc/lircd.conf ]]; then
                cp "${D}"/etc/lirc/lircd.conf "${T}"/lircd.conf
        fi

        # stop portage from touching the config file
        if [[ -e "${D}"/etc/lirc/lircd.conf ]]; then
                rm -f "${D}"/etc/lirc/lircd.conf
        fi

}

pkg_postinst() {

        # copy config file to new location
        # without portage knowing about it
        # so it will not delete it on unmerge or ever touch it again
        if [[ -e "${T}"/lircd.conf ]]; then
                cp "${T}"/lircd.conf "${EROOT}"/etc/lirc/lircd.conf
                if [[ "$MOVE_OLD_LIRCD_CONF" = "1" ]]; then
                        elog "Moved /etc/lircd.conf to /etc/lirc/lircd.conf"
                        rm -f "${EROOT}"/etc/lircd.conf
                fi
        fi

        einfo "The new default location for lircd.conf is inside of"
        einfo "/etc/lirc/ directory"
}

Ну и листинги всего остального, что есть в папке (чего уж мелочиться):
$ ls 
files  lirc-0.9.3a.ebuild  Manifest  metadata.xml

$ cat metadata.xml 
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE pkgmetadata SYSTEM "http://www.gentoo.org/dtd/metadata.dtd">
<pkgmetadata>
  <maintainer type="project">
    <email></email>
  </maintainer>
  <use>
    <flag name="audio">Build alsa-lib and portaudio required for some receivers</flag>
    <flag name="ftdi">Build libftdi required by FTDI driver</flag>
    <flag name="iguanair">Build libiguanair required by iguanaIR</flag>
    <flag name="inputlirc">Build inputlirc</flag>
    <flag name="irman">Build libirman required by Irman</flag>
  </use>
</pkgmetadata>
$ cat files/irexec-confd
# Options to pass to the irexec process
IREXEC_OPTS="/etc/lircrc"

# User to execute irexec as.
# Warning: Running irexec as root can open security holes
#IREXEC_USER="root"

# Use this to disable the warning printed when starting irexec as root
# IREXEC_DISABLE_ROOT_WARNING=yes 
$ cat files/irexec-initd 
#!/sbin/runscript
# Copyright 2003 Martin Hierling <mad@cc.fh-lippe.de>
# Distributed under the terms of the GNU General Public License v2
# $Id$

: ${IREXEC_USER:=root}

depend() {
        need lirc
}

start() {
        if [ "x${IREXEC_USER}" = "xroot" -a "x${IREXEC_DISABLE_ROOT_WARNING}" != "xyes" ]; then
                ewarn "Warning: Running irexec as root can open security holes"
        fi

        ebegin "Starting irexec"
        start-stop-daemon --start --chuid ${IREXEC_USER} --user ${IREXEC_USER} --chdir / \
                --exec /usr/bin/irexec -- --daemon ${IREXEC_OPTS}
        eend $? "Failed to start irexec."
}

stop() {
        ebegin "Stopping irexec"
        start-stop-daemon --stop --exec /usr/bin/irexec --user ${IREXEC_USER}
        eend $? "Failed to stop irexec."
}
 $ cat files/irexec.service 
[Unit]
Description=IR Exec
After=lirc.service
Wants=lirc.service

[Service]
ExecStart=/usr/bin/irexec

[Install]
WantedBy=multi-user.target
$ cat files/lircd
#!/sbin/runscript
# Copyright 1999-2014 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
# $Id$

PIDFILE=/var/run/lirc/${SVCNAME}.pid
: ${LIRCD_SYMLINKFILE:=/dev/lircd}
: ${LIRCD_SOCKET:=/var/run/lirc/lircd}

depend() {
        need localmount
        use modules
        provide lirc
}

start() {
        local retval

        ebegin "Starting lircd"

        for retval in ${LIRCD_SET_SYSCLASSRCS} ; do
                if [ -e /sys/class/rc/${retval}/protocols ] && \
                grep -qs 'lirc' /sys/class/rc/${retval}/protocols ; then
                        einfo "Setting lirc protocol active for ${retval}"
                        echo lirc >/sys/class/rc/${retval}/protocols
                fi
        done

        checkpath -q -d -m 0755 -o root:root /var/run/lirc
        rm -Rf ${LIRCD_SOCKET} && ln -s ${LIRCD_SOCKET} ${LIRCD_SYMLINKFILE}
        if [ $? -ne 0 ]; then
                eend $? "Unable to create symbolic link ${LIRCD_SYMLINKFILE}"
                return 1
        fi

        start-stop-daemon --start --quiet --pidfile "${PIDFILE}" --exec /usr/sbin/lircd -- \
                -P "${PIDFILE}" ${LIRCD_OPTS}
        retval=$?

        if [ ${retval} -ne 0 ]; then
                rm -Rf ${LIRCD_SOCKET}
        fi

        eend ${retval}
}

stop() {
        ebegin "Stopping lircd"
        rm -f ${LIRCD_SYMLINKFILE}
        start-stop-daemon --stop --quiet --pidfile "${PIDFILE}" --exec /usr/sbin/lircd
        eend $?
}
 $ cat files/lircd.conf.4 
# Options to pass to the lircd process

# for devices with lirc-kernel-module
#LIRCD_OPTS="-d /dev/lirc0"
#LIRCD_OPTS="-d /dev/lirc"

# for devices using the input-layer
#LIRCD_OPTS="-H devinput -d /dev/input/by-path/pci-0000:00:0a.0--event-ir"
# This should work, Bug #235107
#LIRCD_OPTS="-H devinput -d name=*DVB*"

# set default protocol to 'lirc' for in-kernel IR decoding
# for the following entries in /sys/class/rc/
# (space-separated list if there is more than one)
LIRCD_SET_SYSCLASSRCS="rc0"

# If running mulitple instances of lircd, the following
# can be used to override the default socket path and
# socket symlink
#LIRCD_SOCKET="/var/run/lirc/lircd"
#LIRCD_SYMLINKFILE="/dev/lircd"
$ cat files/lircmd 
#!/sbin/runscript
# Copyright 1999-2004 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
# $Id$

depend() {
        need lircd
}

start() {
        ebegin "Starting lircmd"
        start-stop-daemon --start --quiet --exec /usr/sbin/lircmd
        eend $?
}

stop() {
        ebegin "Stopping lircmd"
        start-stop-daemon --stop --quiet --exec /usr/sbin/lircmd
        eend $?
}
$ cat files/lirc.service 
[Unit]
Description=Linux Infrared Remote Control
After=network.target

[Service]
ExecStart=/usr/sbin/lircd --nodaemon --driver=default --device=/dev/lirc0

[Install]
WantedBy=multi-user.target
$ cat files/modprobed.lirc 
#
# For first serial receivers:
#
#options lirc_serial irq=4 io=0x3f8
#options lirc_sir irq=4 io=0x3f8

#
# Detach first serial port from serial-driver.
# Use this when you have your serial-port-driver statically
# compiled into your kernel, or as a module but loaded before
# the lirc-module.
# 
#install lirc_serial setserial /dev/ttyS0 uart none; modprobe --ignore-install lirc_serial
#
#install lirc_sir    setserial /dev/ttyS0 uart none; modprobe --ignore-install lirc_sir


#
# For parallel receivers:
#
#options lirc_parallel irq=7 io=0x3bc

Таким образом, всё что вам нужно сделать - так это добавить ебилд в локальный репозиторий, выполнить repoman manifest и установить пакет.
# emerge lirc

Скачать zip можно отсюда: https://cloud.mail.ru/public/2Mdy/yGnm7BVgX
Да, я тут подумал, что так жить нельзя, и решил завести себе аккаунт на GitHub. Так что теперь ебилды можно будет качать и отсюда: https://github.com/developersu/loperOverlay

Теперь добавим демон lircd в автозагрузку:
# rc-update add lircd default
И запустим его:
# /etc/init.d/lircd start
 * Starting lircd ...
 * Setting lirc protocol active for rc0        [ ok ]
Проверить, что всё работает как надо можно коммандой mode2. Когда она запущена нужно поклацать пультом и диод замигает, а в консоли вы увидите примерно следующее:
# mode2 
Using device: /dev/lirc0
Using device: /dev/lirc0
Warning: Running as root.
pulse 9045
space 4607
pulse 511
space 1706
pulse 511
space 597
pulse 597
space 511
pulse 597
space 511
pulse 597
space 511
pulse 597
space 597
pulse 597
space 511
pulse 597
space 511
pulse 597
space 511
pulse 597
space 1621
pulse 682
space 1706
pulse 597
space 511
pulse 597
space 597
pulse 597
space 1706
pulse 597
space 1706
pulse 597
space 1621
pulse 682


О том, как настроить конкретный пульт для управление системой в KDE мы поговорим в следующий раз.

На этом у меня всё.

Источники:
https://dicks.home.xs4all.nl/avr/usbtiny/
http://jumptuck.com/2008/10/26/usb-ir-receiver/
http://gentoo-en.vfose.ru/wiki/LIRC

0 коммент.:

Отправить комментарий