Хабрахабр

IR интерфейс, Raspberry и LIRC

Исходно эти устройства имеют только IR remote control. Моя задача сейчас — научиться отправлять команды кондиционерам и другим устройствам в доме. В статье можно найти конфиги, команды, советы и немного теории. Для решения этой задачи у меня есть Raspberry Pi и IR transceiver shield. Из софта будут LIRC (Linux Infrared Remote Control) и Python.

В процессе исследования выяснил, что LIRC работает как с передатчиками, так и с приемниками IR сигналов, может декодировать принятый сигнал и выполнять какие-то действия в связи с этим. LIRC я нашел с помощью Гугла. Если будете возиться с LIRC сами, прочтение LIRC Configuration Guide крайне рекомендуется. Сейчас прием сигналов мне не нужен, но в будущем может оказаться полезным.

Конфигурация

apt-get update
apt-get install lirc

# /etc/modules (добавить в конец)
lirc_dev
lirc_rpi gpio_in_pin=18 gpio_out_pin=17

# /etc/lirc/hardware.conf (по умолчанию файла нет, надо создать)
LIRCD_ARGS="--uinput --listen"
LOAD_MODULES=true
DRIVER="default"
DEVICE="/dev/lirc0"
MODULES="lirc_rpi"

# /boot/config.txt (в конце уже есть заготовка секции про lirc, исходно пустая)
dtoverlay=lirc-rpi,gpio_in_pin=18,gpio_out_pin=17

# /etc/lirc/lirc_options.conf (найти и заменить эти параметры)
driver = default
device = /dev/lirc0

reboot
sudo /etc/init.d/lircd status

Запись

Я дальше называю этот файл lircd.conf, но на самом для каждого устройства создается свой файл my_device_name.lircd.conf в каталоге /etc/lirc/lircd.conf.d. Сначала необходимо создать конфигурационный файл с последовательностями данных для всех необходимых команд.

Если есть пульт, то можно записать передаваенмые им сигналы в файл с помощью утилиты irrecord. Формат файла описан здесь.

/etc/init.d/lircd stop
irrecord -d /dev/lirc0 ~/my_device.lircd.conf
mv ~/my_device.lircd.conf /etc/lirc/lircd.conf.d/

В некоторых случаях irrecord терпит неудачу в анализе, поэтому есть возможность сохранить последовательность как она была принята, в "сыром" (raw) виде, для этого есть ключ --force. irrecord анализирует последовательности и пытается определить протокол и временные параметры.

Тогда можно записать последовательности с помощью mode2 и создать файл самостоятельно. Но даже с --force irrecord пытается что-то анализировать, и тоже может потерпеть неудачу.

Длительность измеряется в микросекундах (1e-6 секунды). mode2 печатает последовательно длительности наличия и отсутствия сигнала, из которых и складываются передаваемые данные. Сответственно, всегда должно быть нечетное количество чисел (начинается и заканчивается наличием сигнала — 'pulse'). В raw формате в lircd.conf указыватся эти же длительности, начиная с 'pulse' (ведущий 'space' не нужен).

под спойлером). Для автоматизации я сделал скрипт для записи, который спрашивает имя команды, запускает mode2 на 5 секунд, запоминает и в конце печатает результат в формате, готовом для lircd.conf (см.

Скрипт

#!/usr/bin/env python3 import io
import sys
import os r = """begin remote name DEVICE_NAME_CHANGE_ME flags RAW_CODES eps 30 aeps 100 gap 19037 begin raw_codes """ while True: print() print("enter the command name, or just press Enter to finish") a = sys.stdin.readline().rstrip("\n\r") if not a: break first_space = True n = 0 r += " name " + a + "\n" for line in os.popen('timeout 5s mode2 -d /dev/lirc0 2> /dev/null').read().split('\n'): words = line.split() if len(words) < 2: continue if words[0] != 'space' and words[0] != 'pulse': continue if first_space and words[0] == 'space': first_space = False continue if n % 4 == 0: r += "\n " r += words[1] + " " n = n+1 if n > 5: print ("got", n, "values, looks good") else: print ("no signal, something went wrong") r += "\n\n" r += """ end raw_codes
end remote """ print()
print(r)
print()

Не всегда это проходит удачно, не спешите выбрасывать старый файл. Созданный файл можно еще раз попытаться "распознать" с помощью irrecord --analyse. Моя статистика такая: пульт от телевизора LG был понят с легкостью, все кондиционеры и пылесос потребовали ручного создания, пылесос был потом обработан --analyse.

Просто как пример: вот так выглядит файл для моего пылесоса.

Стандартные имена команд

Поэтому по умолчанию от нас требуют, чтобы имена команд в lircd.conf были из стандартного списка. LIRC по своему прямому назначению должен принятый и распознанный IR сигнал превратить в событие Linux input. Можно посмотреть список допустимых имен:

irrecord --list-namespace

Требование к именам можно выключить, добавив при записи параметр: Кондиционеры под этот шаблон не попадают.

irrecord --disable-namespace ....

Отладка

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

/etc/init.d/lircd stop
mode2 -d /dev/lirc0

В особо безнадежных случаях можно менять значение на выходе GPIO и проверять тестером или осцилографом, куда доходит сигнал. Проверить передачу проще всего, если есть другой приемник и запущенная на нем mode2. Команда gpio входит в состав пакета wiringpi.

while sleep 1; do gpio -g toggle 17
done

Посмотреть на логи можно с помощью journalctl, в частности это позволяет увидеть ошибки в файле конфигурации:

journalctl -b 0 /usr/sbin/lircd

Отправка команд

Она же может показать список известных устройств, и список известных команд для каждого устройства. Для передачи записанных команд есть утилита irsend. Обратите внимание на "пустые аргументы" в примере ниже, они там нужны.

выше). irsend — это клиент для lircd, поэтому если что-то пошло не так, заглядывайте в логи (см.

# список устройств
irsend LIST "" "" # список команд для устройства LG_TV
irsend LIST LG_TV "" # отправить команду ON
irsend SEND_ONCE LG_TV ON

Не разбирался. Теоретически, есть еще одна возможность — отправлять команды в lircd через его сокет.

Вызов из Python

Единственная найденная мной библиотека, которая компилирует клиента для API через сокет, не работает на Raspberry (нужна другая версия lircd). Почти все библиотеки являются всего лишь обвесом над irsend. Поэтому смысла в них мало, команду вызвать я могу сам:

import subprocess subprocess.call(["irsend", "send_once", "BEDROOM_AC", "OFF"])

Hardware

IR hat

Гуглить можно как "Raspberry infrared sheild". Я использую готовую плату, их много на Amazon и AliExpress. Она использует GPIO 17 на выход, и GPIO 18 на вход, что видно из конфигов выше.

При использовании двух светодиодов, они подключаются последовательно. На плате есть место для второго (дополнительного) светодиода D2, который по умолчанию не установлен. С удивлением обнаружил, что на всех моих платах перемычка исходно была разомкнута. Поэтому при отсутствии светодиода D2 нужно замкнуть перемычку SJ1. Пришлось доработать паяльником.

Фотография крупнее для желающих поразглядывать

IRDA Hat

Итоги

Работает: сигнал передается, устройства его видят и правильно на него реагируют.

Один неподвижный передатчик не может управлять всеми устройствами в комнате. Многое зависит от положения диода-излучателя, он должен быть точно направлен на приемник. Клонировать решение на базе Raspberry Pi для каждого гаджета дорого, нужно или доработать излучатель для "покрытия большей площади", или найти более дешевую платформу.

Поэтому для него ествественно, что одна кнопка — один код. LIRC исходно создавался для преобразования IR сигналов в стандарнтные линуксовые события устройств ввода. Возможности собирать многокомпонентный пакет на основе нескольких параметров в LIRC нет, поэтому как быстрый инструмент "из коробки" он помогает, но дальше придется искать что-то еще. Для некоторых устройств (болшинства Air conditioner) это не так: при нажатии на любую кнопку пульт передает пакет данных, содержащий полное состояние устройства (включено, режим работы, температура, режимы работы вентилятора, время, таймер и т.д.). Хотя для большинства случаев записанных данных с привычными настройками вентилятора и без экзотических режимов вполне достаточно.

Теги
Показать больше

Похожие статьи

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *

Кнопка «Наверх»
Закрыть