Работаем с ИК пультом


Анализ сигналов ИК-пульта
Первым делом проверил “какие” сигналы генерирует имеющийся у меня пульт. Для анализа очень удобно и просто записать сигналы с помощью звуковой карты ПК. Как это сделать читаем тут Запись сигналов IR-пульта на звуковую карту.
Вот что у меня получилось:

Больше всего формат посылок похож на Extended NEC protocol:

ИК-приемник
Долго мудрить не стал, выбрал самый дешевый и способный работать при низком напряжении питании (от 2,5 до 5,5 В) TSOP31326 (26 рублей):

Пришел только вчера, ждал почти три недели :(
Прием и обработка сигналов
Самый простой алгоритм анализа сигнала на мой взгляд является измерение длительности импульсов.
Из доступной периферии для измерения длительности лучше всего использовать 16-ти битный таймер общего назначения, в связи с наличием его во всей линейке STM8 (и STM32), что позволит в дальнейшем использовать один и то же код.
Можно было бы использовать и расширенный таймер, но он слишком “вкусный” для такой простой задачи. А восьми битные таймера не имеют внешних входов.
Как правило таймер общего назначение реализован под номером 2 (TIM2).
Проанализировав все доступные режимы работы таймера я выбрал режим “PWM input signal measurement”.
Данный режим работы предназначен для измерения длительности импульса и периода ШИМ сигнала.
В этом режиме к одному внешнему входу подключены два канала “захвата”. Каналы настроены на выделение разных фронтов входного сигнала (нарастающий и спадающий). В примере на рисунке ниже, канал IC1 настроен на выделение нарастающего фронта сигнала, канал IC2 – спадающий фронт:

Так как самый функциональный всегда расширенный таймер 1 (TIM1), а все остальные являются его упрощенными версиями, следовательно описание всех режимов работы дано для таймера 1. Поэтому хоть я и рассматриваю таймер 2 на рисунке выше указанно TIM1.
При детектировании нарастающего фронта происходит запоминание текущего значения (в данном случае это значение является периодом входного сигнала), сброс счетного регистра и одновременное генерирование соответствующего прерывания. Аналогичные действия происходят и при детектировании спадающего фронта во втором канале, за исключением сброса счетного регистра.
Как видим всё довольно просто. Остается только в обработчиках прерываний считывать длительности и анализировать их.
По моему мнению для сигналов моего пульта нет смысла измерять все длительности подряд. Объясню почему.
Можно выделить три пары длительности сигналов:
Сигнал Длительность ИК-излучения, мс Длительность паузы, мс Начало посылки 9 4,5 Логическая единица 0,56 1,69 Логический ноль 0,56 0,56 Как видим информация о длительности пауз достаточно для однозначного определения различных типов сигнала.
Программная реализация Для простоты буду использовать стандартные библиотеки, конечно это не оптимально, но более универсально.
Схему подключения ИК-приемника использовал типовую (см. рисунок выше). Сигнал на выходе ИК-приемника инверсный, т.е. когда нет излучения на выходе всегда высокий логический уровень. Подан на линию TIM2_CH1.
И так настраиваем настраиваем таймер согласно описанному выше режиму:
// разрешаем тактирование CLK_PeripheralClockConfig(CLK_Peripheral_TIM2, ENABLE); // режим работы TIM2_TimeBaseInit(TIM2_Prescaler_64, TIM2_CounterMode_Up, 0xFFFF); TIM2_ICInit(TIM2_Channel_1, TIM2_ICPolarity_Rising, TIM2_ICSelection_DirectTI, TIM2_ICPSC_DIV1, 0); TIM2_ICInit(TIM2_Channel_2, TIM2_ICPolarity_Falling, TIM2_ICSelection_IndirectTI, TIM2_ICPSC_DIV1, 0); TIM2_SelectInputTrigger(TIM2_TRGSelection_TI1FP1); TIM2_SelectSlaveMode(TIM2_SlaveMode_Reset); // разрешаем прерывания TIM2_ClearFlag(TIM2_FLAG_CC2); TIM2_ITConfig(TIM2_IT_CC2, ENABLE); // разрешаем работу TIM2_Cmd(ENABLE);
Собственно всё, теперь только анализировать длительности сигналов. Согласитесь очень просто :)
Пример обработчика (написан на скорую руку, поэтому оптимальностью не пахнет, плюс ошибся в порядке следования битов :)):
volatile uint8_t ir_rx_buffer[4]; volatile uint8_t step; volatile uint8_t number; #define IR_START_LENGTH 120 #define IR_ONE_LENGTH 30 INTERRUPT_HANDLER(TIM2_CC_USART2_RX_IRQHandler,20) { uint8_t i; uint16_t time; if(TIM2_GetFlagStatus(TIM2_FLAG_CC2)) { time = TIM2_GetCapture2(); // детектирование начала посылки if (time > IR_START_LENGTH) { number = 0; step = 1; } else { if (step & BIT(7)) { step <<= 1; if (time > IR_ONE_LENGTH) { step |= 1; } // ir_rx_buffer[number] = step; // if (number < ARRAY_LENGHT(ir_rx_buffer) - 1) { number++; } // step = 1; } else { step <<= 1; if (time > IR_ONE_LENGTH) { step |= 1; } } } // сбрасываем флаг TIM2_ClearITPendingBit(TIM2_FLAG_CC2); } }
Для тестирование выводил данные из приемного буфера на ЖКИ:
while (1) { lcd_2x16_set_position(0, 0); for (i = 0; i < 4; i++) { lcd_2x16_print_hex_xx(ir_rx_buffer[i]); lcd_2x16_print_char(' '); } }
Видео работы:
- +7
- 12 августа 2011, 21:03
- ZiB
полулиба собственного производства, без всяких оптимизаций обычно использую её для отладки, можно взять тут
ziblog.ru/2011/01/09/pervyiy-start-s-stm32-discovery-chast-6-ndash-linii-vvoda-vyivoda/
ziblog.ru/2011/01/09/pervyiy-start-s-stm32-discovery-chast-6-ndash-linii-vvoda-vyivoda/
Пульт для магнитолы FIAST TCD-1123 выдает такую посылку.
В посылке всего 32 бита.
Последовательность предварительная <pre-pulse>: 4,44+4,44=8,88мс.
Последовательность логической единицы: 0,612+1,59=2,202мс.
Последовательность логического нуля: 0,612+0,453=1,065мс.
в конце посылки 0,612+(~9,000)=~9,0612мс. Если кнопка удерживается, то сразу же за
Кнопка Play/Pause: <pre-pulse>10000001/10000001/10000000/01111111<after-pulse>
Кнопка STOP:<pre-pulse><after-pulse>
Кнопка Prew:<pre-pulse><after-pulse>
Кнопка Next:<pre-pulse><after-pulse>
Сигнал повтора кнопки: <pre-pulse>0<after-pulse>
Первая часть посылки, состоящая из 16 бит, похожа на протокол JVC, однако вторая часть из 16 бит меня смущает.
В посылке всего 32 бита.
Последовательность предварительная <pre-pulse>: 4,44+4,44=8,88мс.
Последовательность логической единицы: 0,612+1,59=2,202мс.
Последовательность логического нуля: 0,612+0,453=1,065мс.
в конце посылки 0,612+(~9,000)=~9,0612мс. Если кнопка удерживается, то сразу же за
Кнопка Play/Pause: <pre-pulse>10000001/10000001/10000000/01111111<after-pulse>
Кнопка STOP:<pre-pulse><after-pulse>
Кнопка Prew:<pre-pulse><after-pulse>
Кнопка Next:<pre-pulse><after-pulse>
Сигнал повтора кнопки: <pre-pulse>0<after-pulse>
Первая часть посылки, состоящая из 16 бит, похожа на протокол JVC, однако вторая часть из 16 бит меня смущает.
Пульт для магнитолы FIAST TCD-1123 выдает такую посылку.
В посылке всего 32 бита.
Последовательность предварительная <pre-pulse>: 4,44+4,44=8,88мс.
Последовательность логической единицы: 0,612+1,59=2,202мс.
Последовательность логического нуля: 0,612+0,453=1,065мс.
Последовательность окончательная: 0,612+(~9,000)=~9,0612мс.
Последовательность повтора кнопки <reply-pulse>: <pre-pulse>+0+<after-pulse>.
Если кнопка удерживается, то сразу же за <after-pulse> предыдущей посылки циклически повторяется посылка <reply-pulse>.
Кнопка Play/Pause: <pre-pulse>10000001/10000001/10000000/01111111<after-pulse>
Кнопка STOP:<pre-pulse>10000001/10000001/10010000/01101111<after-pulse>
Кнопка Prew:<pre-pulse>10000001/10000001/10001000/01110111<after-pulse>
Кнопка Next:<pre-pulse>10000001/10000001/10011000/01100111<after-pulse>
Сигнал повтора кнопки: <pre-pulse>0<after-pulse>
Помогите распознать протокол.
В посылке всего 32 бита.
Последовательность предварительная <pre-pulse>: 4,44+4,44=8,88мс.
Последовательность логической единицы: 0,612+1,59=2,202мс.
Последовательность логического нуля: 0,612+0,453=1,065мс.
Последовательность окончательная: 0,612+(~9,000)=~9,0612мс.
Последовательность повтора кнопки <reply-pulse>: <pre-pulse>+0+<after-pulse>.
Если кнопка удерживается, то сразу же за <after-pulse> предыдущей посылки циклически повторяется посылка <reply-pulse>.
Кнопка Play/Pause: <pre-pulse>10000001/10000001/10000000/01111111<after-pulse>
Кнопка STOP:<pre-pulse>10000001/10000001/10010000/01101111<after-pulse>
Кнопка Prew:<pre-pulse>10000001/10000001/10001000/01110111<after-pulse>
Кнопка Next:<pre-pulse>10000001/10000001/10011000/01100111<after-pulse>
Сигнал повтора кнопки: <pre-pulse>0<after-pulse>
Помогите распознать протокол.
Сдесь второй байт равен первому, а четвертый инвертирован относительно третьего. Если выкинуть второй и четвертый байты посылки, то получается протокол JVC, включая временные показатели. Однако меня смущает тот факт, что в посылке первый байт дублируется, а второй — инвертируется. Т.е. это получается как-минимум «JVC c перепроверкой».
Все это конечно инересно, вот только в STM8S в таймере 2 отсутствует контроллер и, соответственно отсутствует регистр TIM2_SMCR где можно задать действие при захвате. Поэтому чистить счетчик придется ручками в обработчике прерывания по захвату. А вы видимо используете STM8L. Там регистр TIM2_SMCR присутствует и ваш пример прокатит.
- mark13121971
- 26 февраля 2014, 19:58
- ↓
Используйте первый таймер. Давно было дело, 2011 год.
Если необходимо работать с Ик пультом посмотрите более свежую статью ziblog.ru/2013/05/14/distantsionnoe-upravlenie-ot-ik-pulta.html
Если необходимо работать с Ик пультом посмотрите более свежую статью ziblog.ru/2013/05/14/distantsionnoe-upravlenie-ot-ik-pulta.html
Комментарии (16)
RSS свернуть / развернуть