Некоторое время назад я купил простой и дешевый маленький игрушечный вертолет с ИК-управлением (такой же, как этот - он называется «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 не является точным инструментом ( вообще ) и в противном случае имеет тенденцию вращаться медленно. К сожалению, левая / правая кнопки обрезки, похоже, не посылают сигнал, который увеличивает / уменьшает что-то для каждого нажатия (что было бы удобно для определения протокола); кажется, что это всего лишь одна команда, говорящая вертолету обрезать влево / вправо, а затем он отслеживает это.
источник
Ответы:
Я позволю себе ответить на свой вопрос, поскольку выяснил большую часть его, и это хороший способ поделиться своими выводами. Моя благодарность Олину Латропу за то, что он дал мне место для начала и некоторые идеи, которые нужно опробовать, но в конечном итоге протокол оказался весьма отличным от предположения Олина, поэтому я разместил этот ответ.
Обновление: я отправил дополнительный вопрос относительно последних 8 битов, который я не полностью понял, и Дэйв Твид понял это . Я включу детали здесь, так что этот ответ может работать как полная спецификация протокола, но не забудьте проверить ответ Дэйва.
Мне пришлось попробовать разные вещи, чтобы понять это, но я уверен, что понял. Как ни странно, я не нашел ничего похожего на этот протокол в другом месте, но вполне может быть, что это обычный протокол, о котором я просто не знаю.
Во всяком случае, вот что я нашел:
Протокол / кодирование
Оба импульса и промежутки между ними используются для кодирования данных. Длинный импульс / пробел является двоичным (1), а короткий импульс / пробел - двоичным нулем (0). Импульсы отправляются с использованием стандартной потребительской инфракрасной модуляции 38 кГц при коэффициенте заполнения 50%.
Время импульса / пробела в оригинальном вопросе, но я повторю их здесь для полноты:
Все макс. ± 10 мкс, тип ± 5 мкс. Это основано на выборках, снятых логическим анализатором на частоте 16 МГц; У меня нет осциллографа, поэтому я не знаю точный профиль (то есть время нарастания / спада).
Пакеты повторяются до тех пор, пока применяются управляющие входы, и кажется, что они расположены на расстоянии не менее 100 мс друг от друга.
Передача пакета начинается с преамбулы «импульс 1», которая является фиксированной и не является частью данных. Следующее пространство кодирует первый бит данных пакета, а последний импульс кодирует последний бит.
Каждый пакет имеет длину 32 бита и содержит каждый вход, который может предоставить пульт дистанционного управления. Значения читаются как little-endian, т.е. сначала MSB.
Структура данных
Ниже приведена базовая структура отдельных пакетов. Последние 8 битов меня смутили, но теперь это выяснилось (см. Ниже).
Примечание: диапазоны основаны на самых высоких показаниях, которые я получил. Протокол поддерживает большие диапазоны - до 255 для газа, 63 для тангажа / рыскания - но ограничен примерно вдвое.
Значение высоты тона имеет мертвую зону от 14 до 21 (включительно); только значения выше или ниже фактически заставляют вертолет реагировать. Я не знаю, одинаково ли это для рыскания (трудно сказать, так как вертолет в любом случае нестабилен, и может просто немного вращаться сам по себе).
Здесь это в графических терминах (сравните с графиком в оригинальном вопросе)
6 контрольных битов рассчитываются путем XOR'а всех предыдущих значений. Каждое значение рассматривается как 6 бит. Это означает, что 2 старших бита 8-битного значения газа просто игнорируются. Т.е.
Практические заметки
Синхронизация сигнала и модуляция не должны быть сверхточными. Даже не совсем точный тайминг моего Arduino работает нормально, несмотря на хитрую модуляцию и небольшую частоту попаданий / пропусков по сравнению с настоящим пультом дистанционного управления.
Я верю - но не проверял - что вертолет просто зафиксируется на канале первого найденного сигнала. Если он остается без сигнала слишком долго (пару секунд), он возвращается в режим «поиска», пока не получит сигнал снова.
Вертолет будет игнорировать значения шага и рыскания, если дроссель равен нулю.
Команды обрезки отправляются только один раз при нажатии кнопки на пульте дистанционного управления. Предположительно, значение триммера просто увеличивает / уменьшает значение в собственном контроллере вертолета; это не то, что отслеживает пульт дистанционного управления. Поэтому любая реализация этого, вероятно, должна придерживаться этой схемы и отправлять только случайное значение усечения влево / вправо, но в противном случае по умолчанию устанавливается нулевое значение усечения в пакетах.
Я рекомендую иметь выключатель, который просто устанавливает газ в ноль. Это приведет к тому, что вертолет упадет с неба, но он получит меньше урона, если не вращает моторы. Поэтому, если вы собираетесь потерпеть крах или что-то ударить, нажмите выключатель, чтобы избежать зацепления шестерен или поломки лезвий.
ИК-светодиоды оригинального пульта дистанционного управления имеют длину волны> 900 нм, но у меня нет проблем с использованием светодиода ~ 850 нм.
ИК-приемник вертолета в порядке, но не сверхчувствительный, поэтому, чем ярче ваш ИК-источник, тем лучше. В пульте дистанционного управления используются 3 светодиода последовательно, которые расположены на шине 9 В вместо шины на 5 В, используемой логикой. Я не очень точно проверил их текущую ничью, но держу пари, что это 50 мА.
Образец данных
Вот несколько пакетов, для всех, кто заинтересован (да, я написал сценарий декодера; я все это не декодировал вручную). Пакеты канала A поступают из тех же снимков, что и графики в исходном вопросе.
Как упомянуто выше, последние 8 битов были выяснены, но только для потомков, вот мои оригинальные мысли. Не стесняйтесь игнорировать это полностью, поскольку я был в значительной степени неправ в своих догадках.
Последние 8 бит
Последние 8 битов пакета все еще остаются загадкой.
Все 4 бита от 23 до 26, похоже, полностью определяются настройкой канала пульта дистанционного управления. Смена канала на пульте дистанционного управления никак не влияет на протокол или модуляцию; это только изменяет эти 4 бита.
Но 4 бита - это в два раза больше, чем нужно для кодирования настроек канала; Есть только три канала, поэтому 2 бита достаточно. Следовательно, в приведенном выше описании структуры я пометил только первые 2 бита как «Канал», а оставшиеся два пометил как «X», но это предположение.
Ниже приведен пример соответствующих битов для каждой настройки канала.
По сути, на 2 бита больше, чем необходимо для передачи настройки канала. Может быть, в протоколе отведено 4 бита, чтобы потом было больше каналов, или поэтому протокол можно использовать в совершенно разных игрушках, но я просто не знаю. Для больших значений в протоколе используются дополнительные биты, которые можно было бы опустить (рыскание / дроссель / высота тона могли бы обойтись чуть-чуть меньше каждого), но для обрезки, которая также имеет 3 состояния, используются только 2 бита. Таким образом, можно заподозрить, что канал тоже всего 2 бита, но из-за этого не учитываются следующие 2 бита.
Другая возможность состоит в том, что контрольная сумма пакета имеет длину 8 битов, начиная с «X битов», и - благодаря магии контрольной суммы - они просто как-то всегда отражают настройку канала. Но опять же: я не знаю.
И если говорить о: я понятия не имею, как формируются эти контрольные биты. Я имею в виду, что это контрольные биты, поскольку они не соответствуют ни одному из входов управления, и вертолет, похоже, не реагирует, если я с ними возлюсь. Я предполагаю, что это какой-то CRC, но я не смог понять это. Проверка имеет длину 6-8 бит, в зависимости от того, как вы интерпретируете «биты Х», поэтому существует множество способов, которые можно объединить.
источник
Это не выглядит так плохо. Сначала обратите внимание, что все сообщения содержат ровно 17 импульсов. Это сразу дает нам твердую подсказку, что короткие пробелы в сообщении не имеют значения. Кажется, что данные кодируются с помощью коротких или длинных импульсов, и что некоторый диапазон расстояния между этими импульсами является приемлемым.
Очевидно, что каждое сообщение начинается с длинного импульса в качестве начального бита. Это оставляет 16 бит данных. Вероятно, некоторые из ранних битов - это код операции, возможно, переменной длины. Если бы я делал это, некоторые из конечных битов были бы контрольной суммой. Представьте, что инженеры, написавшие прошивку, хотели, чтобы все было просто для себя, поэтому вы можете начать с предположения, что там где-то есть 8 бит данных. Теперь посмотрим, имеет ли смысл какое-либо из сообщений.
Давайте назовем длинную 1 и короткую 0. Это может быть наоборот, но мы должны с чего-то начать. Снятие стартового бита оставляет:
Несколько вещей всплывают сразу. Очевидно, бит 0 является битом четности. В противном случае, по-видимому, имеется 3-битовое поле <15:13>, 8-битное значение данных <12: 5> и еще одно 4-битное поле <4: 1>.
Похоже, что значение данных отправляется в младшем и старшем битовом порядке, поэтому, вероятно, имеет смысл интерпретировать целые 16 бит, перевернутые из того, что я показываю.
Мне не хочется тратить на это больше времени, но, надеюсь, это дало вам начало. Я бы продолжил, переписав вышеприведенный список с удаленным битом четности, целое число перевело LSB в MSB, и каждое предполагаемое поле показывалось отдельно с пробелом между ним и примыкающим полем. Это может позволить больше всплыть на вас. Также имейте в виду, что у нас может быть чувство 1/0 каждого бита назад. Возможно, каждый раз выписывайте новую таблицу и посмотрите, будет ли что-то более разумным.
источник