Я смію відповідати на власне запитання, коли я зрозумів більшість з них, і це хороший спосіб поділитися своїми висновками. Дякую Оліну Летропу за те, що він дав мені місце для початку та кілька ідей, щоб спробувати, але в кінцевому підсумку протокол виявився зовсім іншим, ніж здогадки Оліна, отже, я опублікував цю відповідь.
Оновлення: я розмістив подальше запитання щодо останніх 8 біт, яке я не повністю зрозумів, і Дейв Твід зробив це . Я включу тут деталі, тому ця відповідь може працювати як повна специфікація протоколу, але перегляньте відповідь Дейва.
Мені довелося спробувати кілька різних речей, щоб зрозуміти це, але я впевнений, що мені це вдалося. Як не дивно, я не знайшов нічого подібного до цього протоколу в іншому місці, але це може бути звичайним протоколом, про який я просто не знаю.
У будь-якому випадку, ось що я знайшов:
Протокол / кодування
І імпульси, і проміжки між ними використовуються для кодування даних. Довгий імпульс / простір - двійковий (1), а короткий імпульс / простір - бінарний нуль (0). Імпульси передаються за допомогою стандартної інфрачервоної модуляції 38 кГц при 50% робочому циклі.
Час імпульсу / простір є в оригінальному питанні, але я повторю їх тут для повноти:
Bit Pulse Space
-----+---------+---------
0 | 275µs | 285µs
1 | 855µs | 795µs
Всі ± 10 мкс макс., ± 5 мкс тип .. Це засновано на зразках, знятих за допомогою логічного аналізатора на 16 МГц; У мене немає осцилографа, тому я не знаю точного профілю (тобто часу підйому / падіння).
Пакети повторюються до тих пір, поки застосовуються керуючі входи і, здається, розташовані не менше 100 м один від одного.
Передача пакетів починається з преамбули "імпульс 1", яка є фіксованою і не є частиною даних. Наступний пробіл кодує перший біт даних пакету, а останній імпульс кодує останній біт.
Кожен пакет має 32 біти і містить кожен вхід, який може надати пульт. Значення читаються як мало ендіан, тобто спочатку 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'ing всіх попередніх значень. Кожне значення трактується як 6 біт. Це означає, що 2 MSB 8-бітового значення дроселя просто ігноруються. Тобто
check = yaw ^ (throttle & 0x3F) ^ pitch ^ trim ^ channel
Практичні записки
Тимчасові сигнали та модуляція не повинні бути надто точними. Навіть не зовсім точний час мого Ардуїно працює чудово, незважаючи на хитрі модуляції та трохи удару та пропуску тривалості імпульсу / простору порівняно з реальним пультом дистанційного керування.
Я вірю - але не перевіряв - що вертоліт просто зачепить на канал першого знайденого ним сигналу. Якщо воно залишається без сигналу занадто довго (пару секунд), воно, схоже, повернеться до режиму «пошуку», поки знову не набере сигнал.
Якщо дросель дорівнює нулю, вертоліт ігнорує значення висоти та нахилу.
Команди обрізки надсилаються лише один раз за натискання кнопки на пульті дистанційного керування. Імовірно, обрізне значення просто збільшує / зменшує значення у власному контролері вертольота; це не те, що дистанційне управління відстежує. Отже, будь-яка реалізація цього, ймовірно, повинна дотримуватися цієї схеми і надсилати лише випадкові обрізки вліво / вправо, але в іншому випадку за замовчуванням до нульового значення обрізки в пакетах.
Я рекомендую встановити перемикач kill, який просто встановлює газ на нуль. Це призведе до того, що вертоліт випаде з неба, але це понесе менше шкоди, коли він не крутить свої мотори. Тож якщо ви збираєтеся зламати або вдарити щось, натисніть перемикач, щоб уникнути позбавлення зубчастих коліс або зламу лопатей.
ІК-світлодіоди оригінального пульта дистанційного керування мають довжину хвилі> 900 нм, але у мене немає проблем із використанням світлодіода ~ 850 нм.
ІЧ-приймач вертольота в порядку, але не надто чутливий, тому чим яскравіше ваш ІЧ-джерело, тим краще. Пульт дистанційного керування послідовно використовує 3 світлодіоди, які сидять на рейці 9В замість 5V напрямних, використовуваних логікою. Я не перевірив їх поточний розіграш дуже точно, але ставлю на 50mA.
Зразок даних
Ось купа пакетів для всіх, хто цікавиться (так, я написав сценарій декодера; я все це не розшифрував вручну). Пакети каналу 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 біта - це багато. Отже, в описі структури, описаному вище, я позначив лише перші два біти як "Канал", а інші два позначив як "X", але це здогад.
Нижче наведено зразок відповідних бітів для кожного налаштування каналу.
Chan. Bits 23-26
-----+-------------
A | 0 1 0 1
B | 0 0 1 0
C | 1 0 0 0
В основному, на 2 біта більше, ніж потрібно для передачі налаштування каналу. Можливо, у протоколі є 4 біти, відведені для того, щоб пізніше було доступно більше каналів, або так протокол можна використовувати в абсолютно різних іграшках, але я просто не знаю. Для більших значень протокол використовує додаткові біти, які можна залишити (yaw / дросель / крок може пройти трохи менше кожного), але для обрізки - яка також має 3 стани - використовуються лише 2 біти. Тож можна було б підозрювати, що канал також є лише 2 бітами, але це залишає наступні 2 без уваги.
Інша можливість полягає в тому, що контрольна сума пакета становить 8 біт, починаючи з "біт X", і - через магію контрольної суми - вони просто трапляються, щоб якось завжди відображати налаштування каналу. Але знову: я не знаю.
А якщо говорити: я не маю поняття, як формуються ці контрольні біти. Я маю на увазі, що це контрольні біти, оскільки вони не відповідають жодному вхідному керуванню, і вертоліт, схоже, не відповідає, якщо я спішуся з ними. Я здогадуюсь, що це якась CRC, але я не змогла це зрозуміти. Перевірка 6-8 бітам, в залежності від того, як інтерпретувати «X біт», таким чином , є багато способів , які можна було б покласти разом.