Помогите с дешифровкой ИК сигнала
- Войдите на сайт для отправки комментариев
Сб, 25/09/2021 - 10:24
Задача у меня такая:
Есть некий ИК пульт, работает по NONAME протоколу, 100% ни один из распространенных(Код повтора 5 и 3 мс, ни где такого не нашел).
Естественно при использовании irrecv.decode я получаю набор белиберды.
Есть ли возможность записать на ардуинке паттерн сигнала? На выходе хочу получить следующее(как бы это выглядело с протоколом NEC):
9000, -2250, 560, -560.... и тп
Так посмотрите в исходнике библиотеки, кае описан протокол NEC и напишите так же
"Паттерн сигнала" удобнее всего записать логическим анализатором.
А, видимо я не понял вопроса
В данный момент на руках только ардуинка и комп, через микрофон уже пробовал снимать разными анализаторами сигнал, выглядит так:
https://ibb.co/Dp7j91r
Но я думаю что вижу не полную картину ибо слушаю сигнал на 22кгц. По этому хотел задействовать ардуино.
Повторюсь: удобнее всего - логическим анализатором. Логический анализатор на частоты до примерно 100 кГц можно сделать и из Ардуино Уно/Нано/Мини.
500кГц, может? Один канал-то.
хотя не, 500 многовато
Пока нашел только SVmonitor для ардуино, но опрос настолько медленный, что максимум, что можно корректно записать это нажатие кнопки... Можете посоветовать анализатор под ардуино годный для моей задачи?
Повторюсь: удобнее всего - логическим анализатором. Логический анализатор на частоты до примерно 100 кГц можно сделать и из Ардуино Уно/Нано/Мини.
Да по его картинке все видно и так. Увеличить и линейкой измерить. Я так уже примерно понял, что это. Только его картинка перевернута. И, кстати, это почти NEC. ;))
Линейкой мерил и с виду весь сигнал удается повторить, но приемник на него не реагирует. Думаю дело в начале пакета, первые 5 мс есть небольшие провалы и это не шум, скорее всего это не 5000, -3000... а больше похоже на 1600, -100, 1600, -100, 1600, -3000. Но эти провалы очень размыты и их длину я померить могу только приблизительно. Пробовал кстати оба варианта, все равно ноль реакции, в общем устал уже мерить линейкой, хочу просто записать.
Похоже что этот код то, что мне нужно:
Однако он нормально измеряет только если пальцами водить по дорожкам, на пульт он не реагирует почему то, хотя:
Отлично реагирует на пульт, правда выдает бессмыслицу. Такое ощущение что IRrecv намного чаще опрашивает вход чем digitalRead.
Разобрался почему не работало, нужно было Resolution уменьшить. Однако получаю слишком плавающие тайминги:
Received:
OFF ON
57958 usec, 8330 usec
985 usec, 50740 usec
35 usec, 17020 usec
53700 usec, 8835 usec
480 usec, 59125 usec
35 usec, 9035 usec
53305 usec, 7440 usec
1870 usec, 65175 usec
0 usec, 2665 usec
53660 usec, 8035 usec
1275 usec, 7315 usec
0 usec, 44635 usec
0 usec, 17270 usec
52275 usec, 8525 usec
790 usec, 59120 usec
40 usec, 9585 usec
52755 usec, 8255 usec
1060 usec, 45930 usec
0 usec, 21675 usec
53895 usec, 8530 usec
785 usec, 25500 usec
0 usec, 28850 usec
0 usec, 14545 usec
52595 usec, 9135 usec
180 usec, 10935 usec
0 usec, 16960 usec
0 usec, 41630 usec
51970 usec, 7710 usec
1605 usec, 20660 usec
0 usec, 7235 usec
0 usec, 40285 usec
53315 usec, 8080 usec
1235 usec, 49545 usec
5 usec, 19260 usec
52685 usec, 29975 usec
0 usec, 49360 usec
51480 usec, 8345 usec
965 usec, 43535 usec
0 usec, 20425 usec
0 usec, 4755 usec
52790 usec, 8190 usec
1125 usec, 20650 usec
0 usec, 33700 usec
0 usec, 7195 usec
0 usec, 6890 usec
53055 usec, 46820 usec
0 usec, 32465 usec
51530 usec, 8325 usec
985 usec, 30300 usec
0 usec, 13225 usec
0 usec, 10825 usec
0 usec, 13900 usec
53245 usec, 8690 usec
625 usec, 37500 usec
0 usec, 6055 usec
0 usec, 24565 usec
53370 usec, 9260 usec
55 usec, 20660 usec
0 usec, 48965 usec
51875 usec, 8870 usec
440 usec, 51955 usec
0 usec, 17025 usec
52520 usec, 8230 usec
1090 usec, 3029 usec
52935 usec, 9000 usec
315 usec, 4804 usec
51160 usec, 8525 usec
790 usec, 61515 usec
45 usec, 7215 usec
52725 usec, 8030 usec
1280 usec, 23095 usec
0 usec, 2405 usec
0 usec, 16800 usec
0 usec, 25970 usec
53225 usec, 11745 usec
0 usec, 849 usec
52685 usec, 9025 usec
285 usec, 8535 usec
0 usec, 60135 usec
52830 usec, 7830 usec
1485 usec, 3650 usec
0 usec, 8500 usec
0 usec, 4840 usec
0 usec, 6100 usec
0 usec, 45095 usec
53310 usec, 9225 usec
85 usec, 2994 usec
52975 usec, 8040 usec
1270 usec, 30300 usec
0 usec, 33660 usec
0 usec, 5275 usec
Особенно смущают значения 0 usec. Почему так могут плавать значения? Ардуинка все таки не может так быстро опрашивать вход?
500кГц, может? Один канал-то.
А какая разница, сколько каналов?
Что, прочитать один бит из порта быстрее, чем порт целиком?
А какая разница, сколько каналов?
Что, прочитать один бит из порта быстрее, чем порт целиком?
Смотря что понимать под логическим анализатором. Если просто отправка в SERIAL на компьютер и там анализировать, то один канал требует в восемь раз меньшей скорости SERIAL При частоте опроса 500 КГц требует скорость примерно 500000*10/8 = 625000 baud. Ближайшая частота для кварца 16МГц равна 666667. Восемь каналов с частотой опроса 500 КГц уже не передать.
Помогите пожалуйста доработать код. Попробовал через аналоговый вход считать и все выглядит довольно убедительно, однако в неудобном исполнении. Я же хочу вывести пройденное время при смене 0\1:
Сейчас на выходе получаю это:
One: 9304636 ms.
Zero: 9305356 ms.
One: 9306120 ms.
Zero: 9306836 ms.
Zero: 9307596 ms.
Zero: 9308356 ms.
One: 9309116 ms.
Zero: 9309836 ms.
Zero: 9310596 ms.
Zero: 9311360 ms.
Zero: 9312116 ms.
Zero: 9312876 ms.
Zero: 9313636 ms.
Zero: 9314396 ms.
One: 9315156 ms.
Zero: 9315876 ms.
One: 9316636 ms.
Zero: 9317356 ms.
Zero: 9318116 ms.
Zero: 9318876 ms.
One: 9319636 ms.
Zero: 9320356 ms.
Zero: 9321116 ms.
Zero: 9321876 ms.
И если посчитать на калькуляторе, тайминги ровные. Я с ардуино познакомился совсем недавно, не могу понять почему при таком коде, мне выдает актуальное время а не разницу между предыдущим результатом и актуальным временем, код такой:
Итак, через три дня я смог написать простую программу для записи паттернов, на основе прерываний:
На выходе получаем такое:
364892< мусор, 3068, 580, 584, 580, 584, 584, 580, 584, 584, 580, 584, 580, 584, 580, 588, 584, 584, 588, 588, 1604, 1608, 1608, 1612, 1608, 1608, 1612, 1604, 1608, 1612, 1604, 1608, 1608, 1608, 1608, 1608, 1608, 1600, 48400< повтор телеграммы
Однако допустим 584 должен выглядеть как 584,584(логическая единица), а 1608 как 584, 1608(логический ноль)
Если это отредактировать заменой в блокноте, на выходе получаем почти один в один диаграмму, за несколькими но, она немного длиннее оригинала, т.к. то, что считала ардуина 584 на самом деле 530,не знаю с чем это связано, возможно обработка прерывания занимает 54мкс. И начало пакета которое длится 5 мс(единицу) она не замечает в упор, дописывал руками, хотя ноль 3мс отлично видит. Заказал логический анализатор, замучила меня эта ардуина.
то, что считала ардуина 584 на самом деле 530,не знаю с чем это связано, возможно обработка прерывания занимает 54мкс. И начало пакета которое длится 5 мс(единицу) она не замечает в упор, дописывал руками, хотя ноль 3мс отлично видит. Заказал логический анализатор, замучила меня эта ардуина.
А как узнали, что оно на самом деле 530?
По логике, длительность обработки прерывания не должна влиять на показания, т.к. она вносит постоянную задержку вызова, и на разность между вызовами влиять не должна.
Если не рассматривать задержки за счет выполнения других прерываний, то данный код наоборот МОЖЕТ занижать значение длительности (но незначительно), т.к. micros() вызывается два раза. С этой точки зрения правильнее написать так
как узнали, что оно на самом деле 530?
Просто измеряю рулеткой в анализаторе.
Итак, по непонятным для меня причинам, сегодня заново прогрузил тот же скетч и получил актуальные паттерны (почти), а так же с вашими изменениями, результат одинаков:
3177192(мусор), 8000(5+3 мс старт пакета), 1060(единица), 1056, 1060, 1060, 1060, 1056, 1060, 1056, 1060, 1060, 1060, 1060, 1056, 1060, 1060, 1056, 1060, 1064, 2080(ноль), 2084, 2084, 2084, 2080, 2088, 2080, 2084, 2084, 2084, 2084, 2084, 2084, 2080, 2088, 2080, 2084, 2080, 48800(перерыв между пакетами)
Прилагаю картинку оригинала и моей копии пакета, прошу помочь разобраться с моими вопросами:
https://ibb.co/c17XZvR
1) Как видно по паттерну он отсчитывает логическую единицу(1*) как 1060 (530мс High + 530мс Low), то же самое с нулем(2*) (2080 = 530 High + 1550 Low) и со стартом пакета(3*) (8000 = 5000 High + 3000 Low). Хотя я использую прерывание CHANGE, то есть я должен получать единицу как 530, 530, а не 1060, почему так происходит?
2) Если с первым вопросом я могу корректировать полученные значения вручную, то вот, что делать со стартом пакета не знаю, на картинке видно, что начало телеграммы(3*) у моей копии это ровная планка 5мс, в то время как у оригинала есть два небольших спада, которые не видит ни ардуино, ни я не могу померить четко их анализатором. Это не помеха, начало пакета это точно не 5000, как я писал выше это похоже на 1600,100,1600,100,1600, но гарантированно это измерить я не могу. Почему ардуина эти спады не замечает, слишком короткие?
Я не разбираюсь в том как работают ИК пульты, и не могу сказать как должно быть и как не должно быть.
В добавок в вашем вопросе картинка не совпадает с описанием. 1* 2* и 3* в тексте и 1 2 3 выделения на картинке.
Спасибо, поправил.
Чуть не так это делается. Нужно завести массив и складывать в него полученные длительности после получения старт пакета. После получения перерыва выстааить флаг и выводить все значения в сериал из loop. Скорость сериала поставить 115200.
Что это даст? Ардуина рассмотрит структуру моего проблемного участка вначале пакета (5мс)? Или просто для красоты? Я вчера мучился со сборкой этого массива, исплевался и бросил, просто задрал скорость порта.
На таких таймингах - около миллисекунды можно и с задранной скоростью обойтись. Вывод одного символа через сериал на 115200 занимает 87 мкс, строки из 4 символов и cr lf - 486 мкс, что меньше Ваших 1056 мкс и значить буфер сериала чистится своевременно. Если наоборот, то при длинных последовательностях возможно переполнение буфера сериала и потери символов. Вот здесь получали данные с таймингами 20 мкс. Справились только с помощью массива.
На таких таймингах - около миллисекунды можно и с задранной скоростью обойтись. Вывод одного символа через сериал на 115200 занимает 87 мкс, строки из 4 символов и cr lf - 486 мкс, что меньше Ваших 1056 мкс и значить буфер сериала чистится своевременно. Если наоборот, то при длинных последовательностях возможно переполнение буфера сериала и потери символов. Вот здесь получали данные с таймингами 20 мкс. Справились только с помощью массива.
Помогите понять, что я делаю не так:
Не надо for в прерывании. Перед началом работы очищаем волатильную глобальную переменную, которая будет содержать указатель на текущее положение массива, и в прерывании, после записи в массив данных, делаем инкремент этой переменной. Проверяем получившееся значение и если превышает заданное количество выставляем флаг что можно выводить. В цикле loop проверяем флаг, если выставлен то очищаем флаг и переменную и в цикле for выводим в сериал заданное количество. Если повезло и до начала вывода не случилось прерывания, то получим нормальные данные. Как по мне, то 500 мкс должно хватить. По ссылке в предыдущем посте можно посмотреть как это реализовано.
Не надо for в прерывании. Перед началом работы очищаем волатильную глобальную переменную, которая будет содержать указатель на текущее положение массива, и в прерывании, после записи в массив данных, делаем инкремент этой переменной. Проверяем получившееся значение и если превышает заданное количество выставляем флаг что можно выводить. В цикле loop проверяем флаг, если выставлен то очищаем флаг и переменную и в цикле for выводим в сериал заданное количество. Если повезло и до начала вывода не случилось прерывания, то получим нормальные данные. Как по мне, то 500 мкс должно хватить. По ссылке в предыдущем посте можно посмотреть как это реализовано.
Случилось, вышел вот такой код:
Но на выходе я получил совершенно те же данные, только пачками по 500 штук. Все таки порт успевал.
Если у вас несколько ардуин, сделайте из одной генератор сигналов - вроде это и есть ваша конечная цель, отправляйте с нее известные сигналы на "логический анализатор" и смотрите, что он правильно измеряет, что нет. Какие минимальные импульсы может зарегистрировать. Хорошо бы знать из теории - какая может быть минимальная длительность импульса, с какой точностью надо воспроизводить импульсы. Тогда будет понятно, хватает возможностей самоделки, или надо ждать купленного.
Мало ардуин, мало, мало ардуин (голосом Бузовой). Я пришел к выводу, что ардуина это игрушка и я в нее наигрался, поэтому, подожду логический анализатор китайский на 24 мгц :)
Я ж писал выше про тайминги, что при 115200 Ваша программа будет успевать получать все данные. Массив в прерывании нужен, если время отправки одной строки больше времени между импульсами. Нужно помнить, что через миллис точность получения данных 4 мкс. Если нужна большая точность, то надо использовать свободный таймер для подсчёта интервалов времени. Зарядить его на нужную точность.
Там (#15) программа так написана, что минимально отрабатываемое время очень большое. В том числе за счет того, что флаг сбрасывается не сразу, а после обработки и поэтому, если за это время пришло и обработалось прерывание, то флаг обработки этого прерывания будет утерян.
Если перенести
12 flag = 0; // Сбрасываем флаг
наверх, сразу после if (flag), то станет намного лучше. Но все равно с массивом надежнее.