Декодирование сигналов инфракрасного пульта дистанционного управления

    Введение

   Однажды мне понадобилось управлять устройством с помощью пульта дистанционного управления. Дистанция требовалась небольшая (до 10 метров) и я решил использовать для этих целей ИК приемник и инфракрасный пульт от бытовой аппаратуры. 
   Для инфракрасных пультов дистанционного управления (ИК ПДУ) существует несколько протоколов передачи данных. Они отличаются способами кодирования битов,  длительностями сигналов, несущей частотой и количеством передаваемых данных. Один из самых распространенных протоколов, судя по интернету,  – это RC5.  Изначально я думал, что придется разбираться с ним, но ни одного пульта с таким протоколом у меня под рукой не оказалось. Зато нашлись три пульта от DVD плееров, использующих протокол фирмы NEC. 

Схема

   Принцип передачи ИК сигналов заключается в следующем - электрический сигнал несущей частоты модулируется передаваемыми данными и с помощью инфракрасного светодиода излучается в пространство. 
   Передача сигнала уже реализована в пульте, этот вопрос мы не затрагиваем, хотя ничего сложного там нет.
   Для приема сигнала используется специальная микросхема, объединяющая в себе фотодиод, усилитель с полосовым фильтром, настроенным на определенную несущую частоту, и детектор, выделяющий огибающую сигнала. Как правило, микросхема имеет три вывода – два питающих и один сигнальный. Последний подключен к коллектору выходного транзистора микросхемы, из-за чего сигнал на выходе оказывается инвертированным. 
   Микросхемы этого семейства объединены общей аббревиатурой— TSOP.

   Для того чтобы узнать, какой протокол используется в пульте дистанционного управления, нужно собрать схемку с  ИК приемником,  снять осциллограмму сигнала и сравнить ее с известными протоколами. 
   Правда есть один момент, ИК приемник рассчитан на работу с одной несущей частотой, а в некоторых протоколах значения несущих частот отличаются - одни используют 38 кГц (например, протокол фирмы Nec),  другие 36 или 40. Поэтому одна и та же схема не сможет работать со всеми без исключения ИК пультами дистанционного управления.
   Схема, которую я использовал при написании программы, приведена на рисунке ниже. Прием ИК сигналов осуществлялся микросхемой TSOP2138, рассчитанной на частоту 38 кГц. 
 
Подключение ИК приемника к AVR
 

Описание протокола Nec

   Для передачи данных используется несущая частота 38 кГц. Посылка состоит из стартового импульса и четырех байтов данных – адрес, инвертированное значение адреса, команда, инвертированное значение команды.  Адрес и команда передаются дважды для повышения надежности. 
   Данные передаются младшим битом вперед. Каждый бит начинается с пачки импульсов несущей частоты. Длительность пачки равна 560 мкс.  Путем изменением временного интервала между пачками импульсов осуществляется кодирование нулей и единиц. При передаче логической единицы интервал от начала текущей до начала следующей пачки импульсов составляет 2.25 мс, а при передаче логического нуля – 1.12 мс.   

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

Посылка, содержащая адрес и команду передается однократно, но при удержании кнопки пульта дистанционного управления через каждые 110 мс излучается код повтора – пачка импульсов несущей частоты длительностью 9мс, пауза в 2.25 мс и пачка импульсов длительностью 560 мкс.
 

Существует расширенная версия протокола Nec, в которой используется 16-ти разрядные адреса.

Алгоритм декодирования сигналов ПДУ

   Для декодирования ИК сигналов, соответствующих протоколу Nec, требуется измерять время между передаваемыми пачками импульсов. Для этого можно использовать схему захвата,  внешнее прерывание или банальный опрос вывода микроконтроллера. Я остановил свой выбор на схеме захвата.
   Рассмотрим алгоритм работы программы, декодирующей сигналы ПДУ. (Код не привожу, чтобы не загромождать описание.)
  В начале функции main() выполняется инициализация таймера Т1 -  разрешается прерывание по событию «захват», устанавливается работа схемы захвата по спадающему фронту (потому что сигнал на выходе ИК приемника инвертированный), нормальный режим работы таймера и коэффициент предделителя, позволяющий вычислять длительность между пачками импульсов без многократных переполнений счетного регистра. Инициализируется lcd дисплей, используемый для отладки. Устанавливается флаг глобального разрешения/запрещения прерываний.
   Далее микроконтроллер «попадает» в бесконечный цикл while, в котором вызываются функции обработки и вывода данных – TIM_Handle() и TIM_Display() соответственно.   
   Параллельно выполнению основного кода, работает таймер Т1 и его схема захвата. Как только логический уровень вывода ICP(PD6) меняется с «1» на «0» выполнение основного кода прекращается и вызывается обработчик прерывания. В обработчике микроконтроллер сохраняет текущее и предыдущее значение счетчика таймера и устанавливается флаг, сигнализирующий функции TIM_Handle() о захвате нового значения.
   Функция TIM_Handle() представляет собой конечный автомат с двумя состояниями – IDLE(ожидание) и RESEIVE(прием). В начале функции проверяется установка программного флага и в случае выполнения условия, вычисляется длительность временного интервала и выполняется код автомата.
   Начальное состояние автомата –IDLE. В этом состоянии автомат ожидает появление стартового импульса или кода повтора. Если длительность временного интервала меньше максимально возможного значения, но больше порогового - принят стартовый импульс. Автомат инициализирует переменные и меняет свое состояние на RESEIVE. Если значение меньше порогового – принят импульс повтора, выполняется инкремент счетчика  повторов (пятый байт массива buf[]).
 
   Переменные, используемые автоматом:
currentState – текущее состояние автомата,
period – длительность временного интервала,
data – приемный «сдвиговый регистр», 
countBit – счетчик принятых битов, 
countByte – счетчик принятых байтов,
buf[] – пяти байтовый массив данных  - адрес, инвертированное значение адреса, команда, инвертированное значение команды, количество повторов
 
   В состоянии RESEIVE автомат сравнивает длительность временного интервала с максимально возможным значением и с пороговым. Если интервал больше порогового значения – значит, принята единица, если меньше – то ноль. 
   В случае приема единицы в переменной data устанавливается 7 разряд. Далее  проверяются счетчики битов и байт, с помощью которых контролируется «укладка» битовой последовательности в массив. 
   Как только будет принято четыре байта, автомат установит флаг RESEIVE_OK и сменит состояние на IDLE. 
    Флаг RESEIVE_OK сигнализирует функции TIM_Display() о выводе принятых данных на символьный lcd. В данном проекте дисплей использовался исключительно в целях отладки.

Файлы

Ссылки

У вас недостаточно прав для комментирования.