Перейти к содержанию
    

Алгоритм распознавания команд с любого ИК пульта

Всем привет. Люди подскажите как с минимальными вычислениями реализовать распознавание, детектирование команд с любого пульта на МК.

Сейчас делаю так - использую ATtiny25 нога к которой подключен TSOP настроена как внешнее прерывание по спаду. После 2го спада начинает записывать в массив из 32х ячеек длину 1 и 0.

И потом соответственно ищем минимум это 0 максимум это 1. Пропускаем через алгоритм сравнения если больше минимума значит устанавливаем в конечной 32битной переменной соответствующий времени бит в 1 или соответствующий расположению от начала приема, если равно минимальной длительности то соответственно 0. Все работает. Но на пульте Philips с RC6 глючит по страшному. Он просто по иному работает. Переворачивает toggle бит если второй раз та же кнопка нажимается, плюет без остановки команды пока кнопку не отпустишь и т.д.

 

Помимо массива длительностей массив из 4х например 32бит переменных в которые в начале записываются команды, ну и потом с ними сравниваются поступающие в реальном времени команды с пульта для управления.

 

Так вот задача. Следить за длительностью любого импульса что 1 что 0 что паузы или переходов. Потом массив длительностей преобразовать к виду например мин ширина 1, больше в 1.5 или 2 раза минимальной ширины соответственно 2. И этот преобразованный массив к 1,2 (потому что ширина импульсов гуляет то например 10, то 12 или 36, 37) кинуть на что-то подобное CRC8 после чего у нас число в котором зашифрована команда и последовательность бит учтена. Что-то на подобии сжатия. С другой похожей не совпадет.

 

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

Изменено пользователем TViT

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

У меня такой алгоритм:

Разбил работу на процесс захвата посылки и процедуру распознавания захваченных посылок.

Захват посылки:

Изначально процесс захвата посылки ищет тишину на линии не менее заданной, при её обнаружении переходит в состояние "ожидания первого перепада 0->1 или 1->0".

После первого перепада переходит в состояние "захват посылки". Выход из этого состояния - по обнаружении тишины на линии не менее T1 мсек.

После обнаружения каждого перепада кратковременно переходит в состояние "подавление дребезга" (просто пауза T2 мкс в течение которой состояние линии не анализируется - для ограничения загрузки CPU при ВЧ-помехах на линии). При обнаружении ошибочных состояний (например: превышение максимально допустимого числа перепадов в посылке; превышение общей длительности посылки; нарушение фазы (состояние покоя до посылки и после посылки - разное) и прочих), процесс захвата переходит в состояние "ожидание тишины на линии не менее времени T3" (T3 > T1; T3 - минимальный интервал тишины между двумя посылками ИК-приёмника).

Записываю в массив длительности нулей и единиц, начиная от первого перепада 0->1 или 1->0 (знаю что у TSOP состояние покоя - единица вроде, но просто на всякий случай сделал возможность работы на инверсном сигнале) и до обнаружения паузы пороговой длительности. С разрешением 1мкс (можно меньше, точности хватит).

Обнаружение заданной паузы T1 - конец посылки, после этого начинаю анализ посылки.

Анализ посылки:

Приёмник ИК-посылок у меня работает в одном из двух режимов - обучение или детектирование.

В режиме обучения каждая новая принятая посылка сравнивается с массивом имеющихся посылок и, если обнаружена похожая, эти посылки сливаются в одну суммарную посылку для которой длительности нулей и единиц рассчитываются как средние между первой и второй сливаемыми посылками.

После слияния посылок, анализирую весь остальной массив посылок на похожесть с новой посылкой и, если обнаружена похожая, суммирую эти посылки. И так далее, пока не проверен весь массив накопленных посылок на непохожесть. Это нужно, так как после прибавления к существующей посылке новой посылки, длительности её импульсов меняются и она может оказаться похожей на другую, на которую раньше была не похожа. У меня есть пороговый критерий "похожести".

В режиме детектирования, приёмник просто сравнивает новую посылку с массивом имеющихся и, если найдена похожая, выдаёт на выход код виртуальной кнопки назначенной готовой посылке, не сливая её с новой посылкой. Если не найдено похожей - посылка отбрасывается.

Алгоритм сравнения посылок на похожесть:

Я сравниваю не длительности 0 и 1, а длительности пар 0/1 и 1/0. Это гораздо более надёжный способ как показала практика на многих пультах.

Т.е. - процедура сравнения определяет если длительности всех пар 0/1 или длительности всех пар 1/0 двух разных посылок отклоняются не более чем на K друг от друга - посылки похожие. Сейчас у меня K == 5%.

Насчёт формата посылок от разных пультов, обнаружил два вида пультов:

1. Для каждой кнопки выдают определённую уникальную посылку, а при длительном удержании - генерят код автоповтора (общий для всех кнопок пульта).

2. Для каждой кнопки имеют две уникальных посылки, при длительном удержании нажатой кнопки повторяют одну посылку, при каждом новом нажатии - выдают другую посылку из пары.

Так что при обучении пульту, я задаю либо для каждой виртуальной кнопки одну посылку и один общий код автоповтора для всего пульта; или каждой кнопке назначаю 2 посылки (в этом случае кода автоповтора нет).

К тому-же - если у Вас 32 - это максимальное количество 0 и 1 в посылке - это слишком мало. Есть пульты, выдающие несколько десятков импульсов. У меня максимальное количество импульсов в посылке задано ==100 (встречал пульты выдающие около 60 импульсов на посылку, может есть и больше).

Описанный алгоритм у меня работает уже несколько лет, проверял с десятком разных пультов - нажатия детектирует почти 100%-но. Не детектируются только нажатия, на которые наложилась помеха.

ПО у меня может обучаться и хранить информацию сразу о кнопках нескольких разных пультов (сколько хватит памяти) и детектирует посылки сразу от всех пультов и имеющихся в базе. Эти пульты могут разных типов (тип1 или тип2). Так что наружу процесс детектирования выдаёт сообщение вида: пультM.кнопкаN.флаг_автоповтора(с длительностью).

И захватывать посылки надо не по прерыванию на ноге (слишком низкая точность, зависящая от загрузки CPU к тому же), а таймером, работающим в режиме захвата. Тогда разрешение можно поставить любое, хоть 1мкс, хоть меньше (хотя это уже избыточно имхо).

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Я думаю ваш алгоритм сложен, у меня нет столько памяти, чтобы в несжатом виде хранить массивы длительностей. Массив у меня 65байт. Было 32байта ранее, работает кроме пультов от Филипса с RC6. Всего 128байт память и еще занято под программу ФИУ симистором, управлением освещением, плавным включением, яркостью различными режимами и блокировками поступающих команд и т.д. Это всего лишь одна опция моей системы, управление с пульта. Помимо управления кнопками и голосом.

 

На Филипсе 3 вида длительностей оказалось и разная длительность команд. Может 35 импульсов плюнуть, а может 39 и т.д. Зависит от команды. В остальном похоже с вашим описанием. Плюют постоянно при удержании. И новую команду при повторном нажатии. Но есть еще кнопки, которые 3 команда разом плюют и ожидают. Конечно тайминги и задержки у меня тоже есть, не принимать вторичную посылку. Все упирается в память.

image.jpg

 

 

Хотелось бы что-то попроще. Итак не успевает моргает свет при управлении с пульта пока обрабатывает прерывания и вычисляет команду, а управление симистором на это период упускает.

На сколько помню в ATtiny25 нет режима захвата по таймеру.

Изменено пользователем TViT

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Я думаю ваш алгоритм сложен, у меня нет столько памяти,

...

Это всего лишь одна опция моей системы, управление с пульта. Помимо управления кнопками и голосом.

Очевидно Вы неправильно выбрали элементную базу. Раз столько функций, зачем было на дохлом AVR делать?

Переделайте на Cortex-M.

 

На Филипсе 3 вида длительностей оказалось и разная длительность команд. Может 35 импульсов плюнуть, а может 39 и т.д.

Я описанным алгоритмом уже много лет пользуюсь. Несколько программ с ним написал.

Написал даже ПО под винду для визуализации и исследования посылок - вот с помощью него в своё время и выяснил многое про работу пультов.

И пультов 1-го и 2-го вида - полно, то что Вы нашли только один ни о чём не говорит. Я перепробовал десятки разных.

И были очень даже хитрые: например от какого-то потолочного кондишена на каждое новое нажатие менял длительность не одного импульса, а нескольких. Вот для того пульта даже моя программа детектирования работать не будет, так как у него более двух кодов на каждую кнопку (там в посылке похоже какой-то N-разрядный счётчик нажатий передавался, а может он ещё что-то передавал вместе с нажатием, так как пульт был навороченный, имел ЖК-индикатор). Но такой пульт встречал только раз.

 

Хотелось бы что-то попроще. Итак не успевает моргает свет при управлении с пульта пока обрабатывает прерывания и вычисляет команду, а управление симистором на это период упускает.

Попроще - забудьте тогда об универсальном приёмнике - не получите никак. Тогда можно сделать под один конкретный пульт.

 

На сколько помню в ATtiny25 нет режима захвата по таймеру.

Так меняйте его на адекватный задаче.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Я пока зашифровал команды все работает. И уменьшил количество кнопок управления с 4х до одной. Т.е. 8байт хранят 4 зашифрованные команды информацию по сути 4х - 65байтовых массивов длительностей, но 4 вариации одной команды полюбому сработает. Не будет 4х функций будет одна на первое время. Тестирую пробую пока все нормально за исключением мерцаний... А в будущем будет видно что и как. Поскольку главное размер и цена моего устройства. Конечно это пробный блин немножко комом оказался...

Изменено пользователем TViT

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

По цене самые простые Cortex-ы не уступают AVR-ам.

А по функционалу Вы уже в потолок упёрлись, уже приходится урезать функционал из-за нехватки ресурсов. Дальше будет хуже.

Какой смысл считать отдельные байты в наше время??

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Я с вами согласен. Но это потом я все переведу на 32битные STM или Atmel. Пока AT32UC3L064 управляет распознаванием речи почти в реальном времени, а ATtiny25 всем остальным командами с пульта с кнопок, импульсами команд от голосового модуля.

Что есть то есть не выкидывать же деньги на ветер, послушался совета называется у разных профи... Что закупил нужно использовать. И платы разведены. Это не считая что Atmel кинула с ценой на AT32UC3L064. Которые пару лет назад стоили 122р... и наши бравые ребята наверху обвалив рубль...

 

Сами что посоветуете макс дешевое из эл базы. Для распознавания голоса нужно 64кБ флеш и 16кб ОЗУ. А отдельная ATtiny25 просто нужна для освещения. Планируется как полный комплект функций, так и отдельно только управление с пульта и кнопками. Поэтому 2е отдельные МС использовал...

 

И еще такой выбор был сделан из-за минимизации размеров и главное потребления, поскольку устройство работает сутками в реальном режиме, не отключаясь и не засыпая...

Изменено пользователем TViT

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Я как-то вот такое делал: http://we.easyelectronics.ru/Soft/prostoy-...oder-ik-du.html

 

У меня примерно так же только частота 4МГц и еще проверка разных кнопок какая нажата с какой длительностью и что делать. Плюс детектор нуля сетевого напряжения на компараторе и программа генерации и управления импульсами через таймер для MOC и ФИУ симистором. Ну и программа хеширования массива 65байт длительностей импульсов на выходе уникальное 2байтовое число характеризующее нажатую кнопку. С другими кнопками на пульте не совпадает и на разных пультах тоже не совпадает. Только по переполнению таймера детектируется конец кодовой посылки. А значение длительности импульса записывается при новом изменении на входе при прерывании.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Хотелось бы что-то попроще. Итак не успевает моргает свет при управлении с пульта пока обрабатывает прерывания и вычисляет команду, а управление симистором на это период

Попробуйте точнее замерить длительности, может так случиться, что длительности этих посылок кратны между собой.

~0.44 , ~0.88, ~ 1.2 , ~ 2.7 на самом деле это T, 2*T, 3*T и 6*T.

 

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

 

По перепаду запускать таймер с периодом 0.44 мс (или проще - 0.22 мс) в котором считывать очередной бит посылки.

Первый стартовый байт должен быть 0b000000 (~2,7 мc). окончание посылки характеризуется завершающим байтом 0b11111111 как начало 82 мс периода верхнего уровня.

Все что между ними - это команда. Нужно лишь составить список.

Если бывает 39 импульсов, то даже если они будут максимально широкими в 3 бита, то максимальный размер требуемого буфера 17 байт вместе с окантовкой.

 

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Попробуйте точнее замерить длительности, может так случиться, что длительности этих посылок кратны между собой.

~0.44 , ~0.88, ~ 1.2 , ~ 2.7 на самом деле это T, 2*T, 3*T и 6*T.

 

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

 

По перепаду запускать таймер с периодом 0.44 мс (или проще - 0.22 мс) в котором считывать очередной бит посылки.

Первый стартовый байт должен быть 0b000000 (~2,7 мc). окончание посылки характеризуется завершающим байтом 0b11111111 как начало 82 мс периода верхнего уровня.

Все что между ними - это команда. Нужно лишь составить список.

Если бывает 39 импульсов, то даже если они будут максимально широкими в 3 бита, то максимальный размер требуемого буфера 17 байт вместе с окантовкой.

 

Точно не получится. Когда 32байта массив был. Все работало на разных пультах кроме Филипса так - если ширина большая в 4х байтной переменной устанавливается соответствующий бит в 1 иначе 0. И на выходе 4х байтное число (32бита) - команда. Которых очень много можно записать в память - 16 кнопок управления если брать половину памяти в МК - 64байт.

Проверял на пультах от ЭЛТ телевизоров Rubin, JVC, Samsung, на новом TFT телеке LG и на пульте от звукового ресивера-усилителя Yamaha

 

А теперь при массиве в 65байт иначе.

 

Точно не измерить ширину импульса в моем случае (тактируется все от внутреннего RC генератора, плавать значения будут в массиве всегда и по другим причинам - от загрузки МК ведь он прерывает работу и обрабатывает еще кучу всего, прерывания от компаратора например постоянно поступают раз в 10мс, детектирует переходы через 0 сетевого напр, еще прерывания от первого таймера управляет шириной импульса для управления симистором - вкл\выкл освещения, запоминание состояний, команд, уровня яркости в eeprom и само управлением яркостью через генерирование в разные моменты управляющих импульсов в зависимости от начала полупериода сетевого напр).

 

Да мне точно и не нужно. Поскольку когда массив забивается, потом алгоритм нормирования все приводит к точным числам 1,2,3 --- соответственно 1-мин время импульса какое нашел в массиве, 2-среднее по длит время импульса какое было в массиве и 3-самое высокое время импульса которое было в массиве. А потом хеширование и на выходе уникальное число. Которых в мою память можно напихать кучу, соответственно и команд кучу можно запомнить.

 

В принципе я уже решил задачу. В моем случае этого для управления пока освещением более чем достаточно. А в будущем просто МК с большей памятью прикручу и все ))

 

 

 

Всем спасибо ))

Изменено пользователем TViT

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

Только это никак не соответствует теме треда: "распознавания команд с любого ИК пульта".

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

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

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...