Помощь или подсказки для расшифровки протокола IR


10

Некоторое время назад я купил простой и дешевый маленький игрушечный вертолет с ИК-управлением (такой же, как этот - он называется «Diamond Gyro» или «Diamond Force»). Ради интереса, я пытался управлять им через Arduino.

Обновление: получил протокол выяснил; см ответ

Другие уже поделились своими результатами по взлому другого ИК игрушечного вертолета и расшифровке его протокола IR. Действительно круто, но, к сожалению, мой вертолет использует другой протокол. Тот, который я не могу понять, (Я должен добавить, что электроника для меня - просто хобби, поэтому я мог упустить из виду нечто очевидное).

Как и во второй ссылке выше, я разобрал контроллер, установил контакт IC, управляющий светодиодами (кстати, маркировка IC была стерта), и подключил логический анализатор.

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

Поэтому я буду признателен за любые ваши идеи. Возможно я просто смотрю на это неправильно.
(Более подробная информация под изображением)

Образцы из канала А

Характеристики сигнала / протокола

Я запечатлел это на частоте 16 МГц с контроллером, настроенным на канал A; должно быть точным, по времени. (Есть 3 ИК канала, из которых вы можете выбрать, но использование двух других каналов не меняет характеристики, только части самого пакета.) Время очень стабильное (максимум +/- 10 мкс). Пакеты повторяются с различными интервалами, но как минимум они находятся на расстоянии около 100 мс.

Несущая: 38 кГц при рабочем цикле 50%

Низкие:
- короткие: 285 мкс
- длинные: 795 мкс

Максимумы:
- короткие: 275 мкс
- длинные: 855 мкс

Всегда 17 максимумов за пакет.

Органы управления / входы

У heli есть 3 элемента управления: «Дроссель» (то есть скорость подъема / ротора), тангаж (вперед / назад) и рыскание (вращение вокруг оси ротора), все управляются с помощью 2 больших пальцев. Все они имеют некоторый диапазон (не только вкл / выкл) и, насколько я могу судить, все передаются в одном пакете. Левый / правый входы отправляются только в том случае, если отправляется что-то еще, поэтому я применил максимальный газ при выборке. Вход газа и шага для отправляемых пакетов запускается, как только вы нажимаете на ручку за некоторый порог / зона нечувствительности (на графике ниже метка «min» относится к первому пакету, посланному при медленном продвижении элемента управления за пределы зоны нечувствительности).

У него также есть кнопки для подрезки влево и вправо, так как heli не является точным инструментом ( вообще ) и в противном случае имеет тенденцию вращаться медленно. К сожалению, левая / правая кнопки обрезки, похоже, не посылают сигнал, который увеличивает / уменьшает что-то для каждого нажатия (что было бы удобно для определения протокола); кажется, что это всего лишь одна команда, говорящая вертолету обрезать влево / вправо, а затем он отслеживает это.


Почему бы просто не использовать трассировки сигналов, которые вы уже должны записать в виде пакетов?
Игнасио Васкес-Абрамс

@ IgnacioVazquez-Abrams Вы имеете в виду просто воспроизведение записанных сигналов на вертолет?
Фламбино

Конечно. Это не похоже на то, что вертолет сможет заметить разницу ...
Игнасио Васкес-Абрамс

@ IgnacioVazquez-Abrams Верно, но, насколько я могу судить, пакет содержит все 3 элемента управления (throttle / pitch / yaw) и элементы управления heli, ни один из них не включен или выключен. Чтобы управлять вещью путем воспроизведения, мне нужно было бы захватить каждую конфигурацию ... Кроме того, я хочу понять протокол
Flambino

@ IgnacioVazquez-Abrams Ой, я как-то исказил свой последний комментарий. Имеется в виду: «... пакет содержит все 3 элемента управления (газ / шаг / рыскание), и ни один из них не включен / выключен".
Фламбино

Ответы:


8

Я позволю себе ответить на свой вопрос, поскольку выяснил большую часть его, и это хороший способ поделиться своими выводами. Моя благодарность Олину Латропу за то, что он дал мне место для начала и некоторые идеи, которые нужно опробовать, но в конечном итоге протокол оказался весьма отличным от предположения Олина, поэтому я разместил этот ответ.


Обновление: я отправил дополнительный вопрос относительно последних 8 битов, который я не полностью понял, и Дэйв Твид понял это . Я включу детали здесь, так что этот ответ может работать как полная спецификация протокола, но не забудьте проверить ответ Дэйва.


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

Во всяком случае, вот что я нашел:

Протокол / кодирование

Оба импульса и промежутки между ними используются для кодирования данных. Длинный импульс / пробел является двоичным (1), а короткий импульс / пробел - двоичным нулем (0). Импульсы отправляются с использованием стандартной потребительской инфракрасной модуляции 38 кГц при коэффициенте заполнения 50%.

Время импульса / пробела в оригинальном вопросе, но я повторю их здесь для полноты:

 Bit    Pulse     Space
-----+---------+---------
  0  |  275µs  |  285µs
  1  |  855µs  |  795µs

Все макс. ± 10 мкс, тип ± 5 мкс. Это основано на выборках, снятых логическим анализатором на частоте 16 МГц; У меня нет осциллографа, поэтому я не знаю точный профиль (то есть время нарастания / спада).

Пакеты повторяются до тех пор, пока применяются управляющие входы, и кажется, что они расположены на расстоянии не менее 100 мс друг от друга.

Передача пакета начинается с преамбулы «импульс 1», которая является фиксированной и не является частью данных. Следующее пространство кодирует первый бит данных пакета, а последний импульс кодирует последний бит.

Каждый пакет имеет длину 32 бита и содержит каждый вход, который может предоставить пульт дистанционного управления. Значения читаются как little-endian, т.е. сначала MSB.

Структура данных

Ниже приведена базовая структура отдельных пакетов. Последние 8 битов меня смутили, но теперь это выяснилось (см. Ниже).

 0                   1                   2                   3
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2
--+---------------------------+-----------+---+-------+-----------
 P|    Yaw    |   Throttle    |   Pitch   | T | Chan. |   Check

P: Preamble (always a pulse-1), T: Trim, Chan.: Channel

Bit    Length    Description (see note below)
-----------------------------------------------
0      1         Preamble. High 1
1-6    6         Yaw. Range 0-36 for left-right, 17 being neutral
7-14   8         Throttle. Range 0-134
15-20  6         Pitch. Range 0-38 for forward-back, 17 being neutral
21-22  2         Trim. Left = 1, right = 2, no trim = 0
23-26  4         Channel. A = 5, B = 2, C = 8
27-32  6         Check bits

Примечание: диапазоны основаны на самых высоких показаниях, которые я получил. Протокол поддерживает большие диапазоны - до 255 для газа, 63 для тангажа / рыскания - но ограничен примерно вдвое.
Значение высоты тона имеет мертвую зону от 14 до 21 (включительно); только значения выше или ниже фактически заставляют вертолет реагировать. Я не знаю, одинаково ли это для рыскания (трудно сказать, так как вертолет в любом случае нестабилен, и может просто немного вращаться сам по себе).

Здесь это в графических терминах (сравните с графиком в оригинальном вопросе)

структура пакета

6 контрольных битов рассчитываются путем XOR'а всех предыдущих значений. Каждое значение рассматривается как 6 бит. Это означает, что 2 старших бита 8-битного значения газа просто игнорируются. Т.е.

check = yaw ^ (throttle & 0x3F) ^ pitch ^ trim ^ channel

Практические заметки

Синхронизация сигнала и модуляция не должны быть сверхточными. Даже не совсем точный тайминг моего Arduino работает нормально, несмотря на хитрую модуляцию и небольшую частоту попаданий / пропусков по сравнению с настоящим пультом дистанционного управления.

Я верю - но не проверял - что вертолет просто зафиксируется на канале первого найденного сигнала. Если он остается без сигнала слишком долго (пару секунд), он возвращается в режим «поиска», пока не получит сигнал снова.

Вертолет будет игнорировать значения шага и рыскания, если дроссель равен нулю.

Команды обрезки отправляются только один раз при нажатии кнопки на пульте дистанционного управления. Предположительно, значение триммера просто увеличивает / уменьшает значение в собственном контроллере вертолета; это не то, что отслеживает пульт дистанционного управления. Поэтому любая реализация этого, вероятно, должна придерживаться этой схемы и отправлять только случайное значение усечения влево / вправо, но в противном случае по умолчанию устанавливается нулевое значение усечения в пакетах.

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

ИК-светодиоды оригинального пульта дистанционного управления имеют длину волны> 900 нм, но у меня нет проблем с использованием светодиода ~ 850 нм.

ИК-приемник вертолета в порядке, но не сверхчувствительный, поэтому, чем ярче ваш ИК-источник, тем лучше. В пульте дистанционного управления используются 3 светодиода последовательно, которые расположены на шине 9 В вместо шины на 5 В, используемой логикой. Я не очень точно проверил их текущую ничью, но держу пари, что это 50 мА.

Образец данных

Вот несколько пакетов, для всех, кто заинтересован (да, я написал сценарий декодера; я все это не декодировал вручную). Пакеты канала A поступают из тех же снимков, что и графики в исходном вопросе.

Channel A                                                       
Yaw     Throttle  Pitch   Tr  Chan  Check     Description
-----------------------------------------------------------
000100  10000100  000000  00  0101  000101    Left Mid + Throttle
000000  10000110  010001  00  0101  010010    Left Max + Throttle 
100001  10000110  000000  00  0101  100010    Right Mid + Throttle 
100100  10000100  010001  00  0101  110100    Right Max + Throttle
010001  00000000  001011  00  0101  011111    Forward Min 
010001  00000000  000000  00  0101  010100    Forward Max 
010001  00000000  011000  00  0101  001100    Back Min 
010001  00000000  100101  00  0101  110001    Back Max
010001  00000000  010001  01  0101  010101    Left Trim 
010001  00000000  010001  10  0101  100101    Right Trim 
010001  00000011  010001  00  0101  000110    Throttle 01 (min)
010001  00010110  010001  00  0101  010011    Throttle 02
010001  00011111  010001  00  0101  011010    Throttle 03
010001  00101111  010001  00  0101  101010    Throttle 04
010001  00111110  010001  00  0101  111011    Throttle 05
010001  01010101  010001  00  0101  010000    Throttle 06
010001  01011111  010001  00  0101  011010    Throttle 07
010001  01101100  010001  00  0101  101001    Throttle 08
010001  01111010  010001  00  0101  111111    Throttle 09
010001  10000101  010001  00  0101  000000    Throttle 10 (max)

Channel B
Yaw     Throttle  Pitch   Tr  Chan  Check     Description
-----------------------------------------------------------
000000  10000110  010001  00  0010  010101    Left Max + Throttle 
100100  10000110  010001  00  0010  110001    Right Max + Throttle 
010001  00000000  001001  00  0010  011010    Forward Min 
010001  00000000  000000  00  0010  010011    Forward Max 
010001  00000000  010111  00  0010  000100    Back Min 
010001  00000000  100110  00  0010  110101    Back Max
010001  00000000  010001  01  0010  010010    Left Trim 
010001  00000000  010001  10  0010  100010    Right Trim 
010001  00000001  010001  00  0010  000011    Throttle Min 
010001  00110100  010001  00  0010  110110    Throttle Mid 
010001  01100111  010001  00  0010  100101    Throttle High 
010001  10001111  010001  00  0010  001101    Throttle Max 

Channel C
Yaw     Throttle  Pitch   Tr  Chan  Check     Description
-----------------------------------------------------------
000000  10000101  010001  00  1000  011100    Left Max + Throttle 
100100  10000101  010001  00  1000  111000    Right Max + Throttle 
010001  00000000  001010  00  1000  010011    Forward Min 
010001  00000000  000000  00  1000  011001    Forward Max 
010001  00000000  010111  00  1000  001110    Back Min 
010001  00000000  100110  00  1000  111111    Back Max
010001  00000000  010001  01  1000  011000    Left Trim 
010001  00000000  010001  10  1000  101000    Right Trim 
010001  00000001  010001  00  1000  001001    Throttle Min 
010001  00110100  010001  00  1000  111100    Throttle Mid 
010001  01100110  010001  00  1000  101110    Throttle High 
010001  10000101  010001  00  1000  001101    Throttle Max

Как упомянуто выше, последние 8 битов были выяснены, но только для потомков, вот мои оригинальные мысли. Не стесняйтесь игнорировать это полностью, поскольку я был в значительной степени неправ в своих догадках.

Последние 8 бит

Последние 8 битов пакета все еще остаются загадкой.

Все 4 бита от 23 до 26, похоже, полностью определяются настройкой канала пульта дистанционного управления. Смена канала на пульте дистанционного управления никак не влияет на протокол или модуляцию; это только изменяет эти 4 бита.

Но 4 бита - это в два раза больше, чем нужно для кодирования настроек канала; Есть только три канала, поэтому 2 бита достаточно. Следовательно, в приведенном выше описании структуры я пометил только первые 2 бита как «Канал», а оставшиеся два пометил как «X», но это предположение.

Ниже приведен пример соответствующих битов для каждой настройки канала.

Chan.   Bits 23-26
-----+-------------
  A  |  0  1  0  1
  B  |  0  0  1  0
  C  |  1  0  0  0

По сути, на 2 бита больше, чем необходимо для передачи настройки канала. Может быть, в протоколе отведено 4 бита, чтобы потом было больше каналов, или поэтому протокол можно использовать в совершенно разных игрушках, но я просто не знаю. Для больших значений в протоколе используются дополнительные биты, которые можно было бы опустить (рыскание / дроссель / высота тона могли бы обойтись чуть-чуть меньше каждого), но для обрезки, которая также имеет 3 состояния, используются только 2 бита. Таким образом, можно заподозрить, что канал тоже всего 2 бита, но из-за этого не учитываются следующие 2 бита.

Другая возможность состоит в том, что контрольная сумма пакета имеет длину 8 битов, начиная с «X битов», и - благодаря магии контрольной суммы - они просто как-то всегда отражают настройку канала. Но опять же: я не знаю.

И если говорить о: я понятия не имею, как формируются эти контрольные биты. Я имею в виду, что это контрольные биты, поскольку они не соответствуют ни одному из входов управления, и вертолет, похоже, не реагирует, если я с ними возлюсь. Я предполагаю, что это какой-то CRC, но я не смог понять это. Проверка имеет длину 6-8 бит, в зависимости от того, как вы интерпретируете «биты Х», поэтому существует множество способов, которые можно объединить.


6

Это не выглядит так плохо. Сначала обратите внимание, что все сообщения содержат ровно 17 импульсов. Это сразу дает нам твердую подсказку, что короткие пробелы в сообщении не имеют значения. Кажется, что данные кодируются с помощью коротких или длинных импульсов, и что некоторый диапазон расстояния между этими импульсами является приемлемым.

Очевидно, что каждое сообщение начинается с длинного импульса в качестве начального бита. Это оставляет 16 бит данных. Вероятно, некоторые из ранних битов - это код операции, возможно, переменной длины. Если бы я делал это, некоторые из конечных битов были бы контрольной суммой. Представьте, что инженеры, написавшие прошивку, хотели, чтобы все было просто для себя, поэтому вы можете начать с предположения, что там где-то есть 8 бит данных. Теперь посмотрим, имеет ли смысл какое-либо из сообщений.

Давайте назовем длинную 1 и короткую 0. Это может быть наоборот, но мы должны с чего-то начать. Снятие стартового бита оставляет:

1010001101011010 мин дроссель
1010011101011000 Макс. Дроссельная заслонка
1010000001011111 мин вперед
1010000000011110 макс вперед
1010000011011101 Макс назад
1010000100011010 мин назад
00000101011100 Макс. Левый + Макс. Дроссельная заслонка
0100010101011110 Макс. Правый + Макс. Дроссельная заслонка
1010000101111111 отделка слева
1010000101011011 облицовка правая

Несколько вещей всплывают сразу. Очевидно, бит 0 является битом четности. В противном случае, по-видимому, имеется 3-битовое поле <15:13>, 8-битное значение данных <12: 5> и еще одно 4-битное поле <4: 1>.

Похоже, что значение данных отправляется в младшем и старшем битовом порядке, поэтому, вероятно, имеет смысл интерпретировать целые 16 бит, перевернутые из того, что я показываю.

Мне не хочется тратить на это больше времени, но, надеюсь, это дало вам начало. Я бы продолжил, переписав вышеприведенный список с удаленным битом четности, целое число перевело LSB в MSB, и каждое предполагаемое поле показывалось отдельно с пробелом между ним и примыкающим полем. Это может позволить больше всплыть на вас. Также имейте в виду, что у нас может быть чувство 1/0 каждого бита назад. Возможно, каждый раз выписывайте новую таблицу и посмотрите, будет ли что-то более разумным.


Спасибо, это отлично! Я пойду прямо и посмотрю, что найду. Посмотрев на другие протоколы, я начал думать, что, возможно, пробелы не имеют значения, но поскольку у них было два очень согласованных времени, я не был в этом уверен. Я полагал, что они изменились бы больше, если бы они не были важны. В любом случае, я попробую это.
Еще

Ха ... Насколько я могу сказать, пространство сделать дело. Я сфокусировался на газе и собрал еще несколько образцов в 10 различных положениях газа. Исключение пробелов не дало мне значимых чисел, независимо от того, как я делал преобразования. Но включая их как long = 1, short = 0 дает плавное изменение значения газа от 1 до 134 (little-endian). Все еще работаю над другими параметрами
Flambino

Я почти полностью выяснил протокол, но есть еще немного загадки. Добавил кучу вещей к моему вопросу, если вы хотите поразмышлять над этим. В любом случае, спасибо за вашу помощь до сих пор! Заставил меня работать в правильном направлении.
Фламбино

@Flambino: Похоже, вы намного опередили то, что я сделал для начала, что оказалось в основном неправильными догадками. Я прочитал ваш обновленный вопрос, но все еще не понимаю, как именно используется длина пробелов. Было ли это просто совпадением, что все показанные вами паттерны имели ровно 17 импульсов и что последний из них указывал на четность, если считать только импульсы равными 0 или 1?
Олин Латроп

Честно говоря, это было в основном методом проб и ошибок с моей стороны. Поскольку 2 тайминга, используемые для пробелов, так же точны, как и импульсы, я подумал, что они могут быть значимыми. И когда игнорирование пробелов не давало полезных двоичных данных, я просто предполагал, что long pulse = 1 и long space = 1 (и short space / pulse = 0), что сразу дало мне очень полезные данные. Таким образом, первый пробел после импульса преамбулы - это первый бит (график максимального правого + максимального дросселя показывает «пробел 1» в качестве первого бита), за которым следуют 16 импульсов, с еще 15 пробелами между ними; 32 бита
Flambino
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.