TViT 0 21 февраля, 2017 Опубликовано 21 февраля, 2017 (изменено) · Жалоба Всем привет. Люди подскажите как с минимальными вычислениями реализовать распознавание, детектирование команд с любого пульта на МК. Сейчас делаю так - использую 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 после чего у нас число в котором зашифрована команда и последовательность бит учтена. Что-то на подобии сжатия. С другой похожей не совпадет. Ну потом естественно простое сравнение какая кнопка нажата... Посоветуйте, как сделать с минимальными вычислениями... Изменено 21 февраля, 2017 пользователем TViT Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 182 23 марта, 2017 Опубликовано 23 марта, 2017 · Жалоба У меня такой алгоритм: Разбил работу на процесс захвата посылки и процедуру распознавания захваченных посылок. Захват посылки: Изначально процесс захвата посылки ищет тишину на линии не менее заданной, при её обнаружении переходит в состояние "ожидания первого перепада 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мкс, хоть меньше (хотя это уже избыточно имхо). Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
TViT 0 24 марта, 2017 Опубликовано 24 марта, 2017 (изменено) · Жалоба Я думаю ваш алгоритм сложен, у меня нет столько памяти, чтобы в несжатом виде хранить массивы длительностей. Массив у меня 65байт. Было 32байта ранее, работает кроме пультов от Филипса с RC6. Всего 128байт память и еще занято под программу ФИУ симистором, управлением освещением, плавным включением, яркостью различными режимами и блокировками поступающих команд и т.д. Это всего лишь одна опция моей системы, управление с пульта. Помимо управления кнопками и голосом. На Филипсе 3 вида длительностей оказалось и разная длительность команд. Может 35 импульсов плюнуть, а может 39 и т.д. Зависит от команды. В остальном похоже с вашим описанием. Плюют постоянно при удержании. И новую команду при повторном нажатии. Но есть еще кнопки, которые 3 команда разом плюют и ожидают. Конечно тайминги и задержки у меня тоже есть, не принимать вторичную посылку. Все упирается в память. Хотелось бы что-то попроще. Итак не успевает моргает свет при управлении с пульта пока обрабатывает прерывания и вычисляет команду, а управление симистором на это период упускает. На сколько помню в ATtiny25 нет режима захвата по таймеру. Изменено 24 марта, 2017 пользователем TViT Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 182 24 марта, 2017 Опубликовано 24 марта, 2017 · Жалоба Я думаю ваш алгоритм сложен, у меня нет столько памяти, ... Это всего лишь одна опция моей системы, управление с пульта. Помимо управления кнопками и голосом. Очевидно Вы неправильно выбрали элементную базу. Раз столько функций, зачем было на дохлом AVR делать? Переделайте на Cortex-M. На Филипсе 3 вида длительностей оказалось и разная длительность команд. Может 35 импульсов плюнуть, а может 39 и т.д. Я описанным алгоритмом уже много лет пользуюсь. Несколько программ с ним написал. Написал даже ПО под винду для визуализации и исследования посылок - вот с помощью него в своё время и выяснил многое про работу пультов. И пультов 1-го и 2-го вида - полно, то что Вы нашли только один ни о чём не говорит. Я перепробовал десятки разных. И были очень даже хитрые: например от какого-то потолочного кондишена на каждое новое нажатие менял длительность не одного импульса, а нескольких. Вот для того пульта даже моя программа детектирования работать не будет, так как у него более двух кодов на каждую кнопку (там в посылке похоже какой-то N-разрядный счётчик нажатий передавался, а может он ещё что-то передавал вместе с нажатием, так как пульт был навороченный, имел ЖК-индикатор). Но такой пульт встречал только раз. Хотелось бы что-то попроще. Итак не успевает моргает свет при управлении с пульта пока обрабатывает прерывания и вычисляет команду, а управление симистором на это период упускает. Попроще - забудьте тогда об универсальном приёмнике - не получите никак. Тогда можно сделать под один конкретный пульт. На сколько помню в ATtiny25 нет режима захвата по таймеру. Так меняйте его на адекватный задаче. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
TViT 0 24 марта, 2017 Опубликовано 24 марта, 2017 (изменено) · Жалоба Я пока зашифровал команды все работает. И уменьшил количество кнопок управления с 4х до одной. Т.е. 8байт хранят 4 зашифрованные команды информацию по сути 4х - 65байтовых массивов длительностей, но 4 вариации одной команды полюбому сработает. Не будет 4х функций будет одна на первое время. Тестирую пробую пока все нормально за исключением мерцаний... А в будущем будет видно что и как. Поскольку главное размер и цена моего устройства. Конечно это пробный блин немножко комом оказался... Изменено 24 марта, 2017 пользователем TViT Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 182 24 марта, 2017 Опубликовано 24 марта, 2017 · Жалоба По цене самые простые Cortex-ы не уступают AVR-ам. А по функционалу Вы уже в потолок упёрлись, уже приходится урезать функционал из-за нехватки ресурсов. Дальше будет хуже. Какой смысл считать отдельные байты в наше время?? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
TViT 0 24 марта, 2017 Опубликовано 24 марта, 2017 (изменено) · Жалоба Я с вами согласен. Но это потом я все переведу на 32битные STM или Atmel. Пока AT32UC3L064 управляет распознаванием речи почти в реальном времени, а ATtiny25 всем остальным командами с пульта с кнопок, импульсами команд от голосового модуля. Что есть то есть не выкидывать же деньги на ветер, послушался совета называется у разных профи... Что закупил нужно использовать. И платы разведены. Это не считая что Atmel кинула с ценой на AT32UC3L064. Которые пару лет назад стоили 122р... и наши бравые ребята наверху обвалив рубль... Сами что посоветуете макс дешевое из эл базы. Для распознавания голоса нужно 64кБ флеш и 16кб ОЗУ. А отдельная ATtiny25 просто нужна для освещения. Планируется как полный комплект функций, так и отдельно только управление с пульта и кнопками. Поэтому 2е отдельные МС использовал... И еще такой выбор был сделан из-за минимизации размеров и главное потребления, поскольку устройство работает сутками в реальном режиме, не отключаясь и не засыпая... Изменено 24 марта, 2017 пользователем TViT Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
neiver 0 24 марта, 2017 Опубликовано 24 марта, 2017 · Жалоба Я как-то вот такое делал: http://we.easyelectronics.ru/Soft/prostoy-...oder-ik-du.html Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
TViT 0 24 марта, 2017 Опубликовано 24 марта, 2017 · Жалоба Я как-то вот такое делал: http://we.easyelectronics.ru/Soft/prostoy-...oder-ik-du.html У меня примерно так же только частота 4МГц и еще проверка разных кнопок какая нажата с какой длительностью и что делать. Плюс детектор нуля сетевого напряжения на компараторе и программа генерации и управления импульсами через таймер для MOC и ФИУ симистором. Ну и программа хеширования массива 65байт длительностей импульсов на выходе уникальное 2байтовое число характеризующее нажатую кнопку. С другими кнопками на пульте не совпадает и на разных пультах тоже не совпадает. Только по переполнению таймера детектируется конец кодовой посылки. А значение длительности импульса записывается при новом изменении на входе при прерывании. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
aiwa 0 25 марта, 2017 Опубликовано 25 марта, 2017 · Жалоба Хотелось бы что-то попроще. Итак не успевает моргает свет при управлении с пульта пока обрабатывает прерывания и вычисляет команду, а управление симистором на это период Попробуйте точнее замерить длительности, может так случиться, что длительности этих посылок кратны между собой. ~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 байт вместе с окантовкой. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
TViT 0 25 марта, 2017 Опубликовано 25 марта, 2017 (изменено) · Жалоба Попробуйте точнее замерить длительности, может так случиться, что длительности этих посылок кратны между собой. ~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-самое высокое время импульса которое было в массиве. А потом хеширование и на выходе уникальное число. Которых в мою память можно напихать кучу, соответственно и команд кучу можно запомнить. В принципе я уже решил задачу. В моем случае этого для управления пока освещением более чем достаточно. А в будущем просто МК с большей памятью прикручу и все )) Всем спасибо )) Изменено 25 марта, 2017 пользователем TViT Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 182 26 марта, 2017 Опубликовано 26 марта, 2017 · Жалоба Тогда самую маленькую длительность можно представить как бит, и тогда вся команда представима как несколько байт, что значительно сэкономит память. Только это никак не соответствует теме треда: "распознавания команд с любого ИК пульта". Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться