IRプロトコルのデコードに関するヘルプまたはヒント


10

少し前に、私はシンプルで安価な小さなIR制御のおもちゃのヘリコプターを購入しました(これも同じです-"Diamond Gyro"または "Diamond Force"と呼ばれています)。楽しみのために、私はArduinoを介してそれを制御することを検討してきました。

更新:プロトコルを理解しました。答えを見る

他の人たちは、別のIRおもちゃのヘリコプターをハッキングし、そのIRプロトコルをデコードした結果をすでに共有しています。本当にクールですが、残念ながら私のヘリコプターは別のプロトコルを使用しています。よくわからないもの。(私はエレクトロニクスが純粋に時々趣味であることを付け加えるべきです、それで私は明白な何かを見落としたかもしれません)。

上記の2番目のリンクと同様に、コントローラーを分解して、LEDを制御するICピンを配置し(ちなみに、ICのマーキングは消去されています)、ロジックアナライザーを接続しました。

たくさんの良いデータを手に入れましたが、それでもプロトコルを理解することができません。このサイトはすばらしいリソースですが、リストされているプロトコルはどれも適合していないようです。そして、私が見つけた他のどれも、私が捕らえた信号に適合しているようには見えません。しかし、私が想像する必要があるのは、それが単純な市販のプロトコルであることです。それは、安価な小さなおもちゃだからです。

だから私はあなたが持つかもしれないアイデアをいただければ幸いです。多分私はそれを間違って見ているだけです。
(画像の下の詳細)

チャンネルAのサンプル

信号/プロトコル特性

コントローラをチャネルAに設定して、16MHzでこれをキャプチャしました。タイミング的に正確でなければなりません。(選択できるIRチャネルは3つありますが、他の2つのチャネルを使用しても特性は変わりません。パケット自体の一部のみです。)タイミングは非常に一貫しています(最大+/- 10µs)。パケットはさまざまな間隔で繰り返されますが、最低でも約100ミリ秒離れています。

キャリア:38kHz @ 50%デューティサイクル

低:
-ショート:285µs-
ロング:795µs

高値:
-短い:275µs-
長い:855µs

パケットごとに常に17の高値。

コントロール/入力

ヘリには3つのコントロールがあります。「スロットル」(つまり、リフト/ローターの速度)、ピッチ(前方/後方)、およびヨー(ローター軸の周りの回転)はすべて、2つのサムスティックで制御されます。それらはすべて、(オン/オフだけでなく)ある種の範囲を持ち、私が知る限り、すべて1つのパケットで送信されます。左/右の入力は、何かが送信されている場合にのみ送信されるため、サンプリング時に最大スロットルを適用しました。送信された独自のトリガーパケットのスロットルおよびピッチ入力。しきい値またはデッドバンドを超えてサムスティックを押すとすぐに(「最小」ラベルの下のグラフは、デッドバンドを超えてコントロールをゆっくりとプッシュしたときに送信される最初のパケット用です)。

また、左右トリミングするためのボタンを得たヘリのない(精密機器などだすべての)とそうでない場合は、ゆっくりとスピンする傾向があります。残念ながら、左/右のトリムボタンは、押すたびに何かをインクリメント/デクリメントする信号を送信しないようです(プロトコルを理解するのに便利です)。ヘリコプターに左/右にトリムするように指示するだけの単一のコマンドのようで、それを追跡します。


パケットを生で書き出す必要がある信号トレースを使用しないのはなぜですか?
Ignacio Vazquez-Abrams

@ IgnacioVazquez-Abramsヘリコプターに記録された信号を再生するだけですか?
フランビーノ2013

承知しました。ヘリコプターが違いを見分けることができるようではありません...
Ignacio Vazquez-Abrams

@ IgnacioVazquez-Abrams Trueです、私の知る限りでは、パケットには3つのコントロール(スロットル/ピッチ/ヨー)とヘリのコントロールがすべて含まれており、単にオン/オフになっているわけではありません。再生によって物事を操縦するには、すべての構成をキャプチャする必要があります...さらに、プロトコルを理解したい
Flambino

@ IgnacioVazquez-Abramsおっと、なんとか最後のコメントを文字化けしました。「...パケットには3つのコントロール(スロットル/ピッチ/ヨー)がすべて含まれており、それらのどれもオン/オフになっているわけではありません」
フランビーノ2013

回答:


8

私は自分の質問のほとんどを理解したので、自由に自分の質問に答えています。これは私の発見を共有する良い方法です。開始する場所と試してみるアイデアを提供してくれたOlin Lathropに感謝しますが、最終的にプロトコルはOlinの推測とはかなり異なることが判明したため、この回答を投稿しました。


更新:最後の8ビットに関するフォローアップの質問を投稿しましたが、完全には理解できませんでしたが、Dave Tweedがそれを理解しました。詳細をここに含めますので、この回答は完全なプロトコル仕様として機能しますが、Daveの回答を確認してください。


私はこれを理解するためにいくつかのことを試さなければなりませんでしたが、私はそれを理解したと確信しています。奇妙なことに、このプロトコルに似たものは他に見つかりませんでしたが、私が知らない一般的なプロトコルである可能性が非常に高いです。

とにかく、これが私が見つけたものです:

プロトコル/エンコーディング

データのエンコードには、パルスとその間のスペースの両方が使用されます。長いパルス/スペースはバイナリ1(1)、短いパルス/スペースはバイナリ0(0)です。パルスは、消費者の標準的な赤外線38kHz変調@ 50%デューティサイクルを使用して送信されます。

パルス/スペースのタイミングは元の質問にありますが、完全を期すためにここで繰り返します。

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

すべて±10µs max。、±5µs typ.。これは、16MHzでロジックアナライザーによってキャプチャされたサンプルに基づいています。オシロスコープを持っていないので、正確なプロファイル(つまり、立ち上がり/立ち下がり時間)がわかりません。

制御入力が適用され、最小100msの間隔があるように見える限り、パケットは繰り返されます。

パケット送信は「パルス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演算によって計算されます。各値は6ビットとして扱われます。これは、8ビットのスロットル値の2つのMSBが単に無視されることを意味します。すなわち

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

実用的なメモ

信号のタイミングと変調は、非常に正確である必要はありません。私のArduinoの正確ではないタイミングでも、実際のリモートコントロールと比較して、怪しげな変調と、パルス/スペースの持続時間に対する多少のヒットとミスにもかかわらず、うまく機能します。

私は信じていますが、テストしていません-ヘリコプターは、最初に見つかった信号のチャネルにラッチするだけです。信号がない状態で長時間(数秒)放置すると、再び信号を取得するまで「検索」モードに戻ったように見えます。

スロットルがゼロの場合、ヘリコプターはピッチとヨーの値を無視します。

トリムコマンドは、リモコンのボタンを押すたびに1回だけ送信されます。おそらくトリム値は、ヘリコプター自身のコントローラーの値を単純に増減します。リモコンが追跡するものではありません。したがって、これの実装はおそらくそのスキームに固執し、時折トリムの左/右の値のみを送信する必要がありますが、それ以外の場合はデフォルトでパケットのゼロのトリム値になります。

スロットルをゼロに設定するだけのキルスイッチを用意することをお勧めします。これにより、ヘリコプターが空から落下しますが、モーターを回転させていないときのダメージは少なくなります。クラッシュしたり何かにぶつかったりする場合は、ギアを剥がしたりブレードを壊したりしないようにキルスイッチを押してください。

元のリモコンのIR LEDの波長は> 900nmのようですが、〜850nm LEDを使用しても問題はありません。

ヘリコプターのIRレシーバーは問題ありませんが、感度が高くないため、IR光源が明るいほど優れています。リモコンは3つのLEDを直列に使用し、ロジックが使用する5Vレールではなく9Vレールに配置します。彼らの現在のドローを非常に正確にチェックしていませんが、私はそれが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ビットはまだ少し謎です。

ビット23から26までの4ビットはすべて、リモコンのチャネル設定によって完全に決定されるように見えます。リモコンのチャンネルを変更しても、プロトコルや変調は変更されません。これらの4ビットのみが変更されます。

しかし、4ビットはチャネル設定をエンコードするために実際に必要なものの2倍です。チャネルは3つしかないので、2ビットで十分です。したがって、上記の構造の説明では、最初の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つは考慮されていません。

もう1つの可能性は、パケットのチェックサムが「Xビット」で始まる8ビット長であり、チェックサムマジックによって、チャネル設定が常に何らかの形で反映されることです。しかし、再び:わかりません。

そして言うと、私はそれらのチェックビットがどのように形成されるのかわかりません。つまり、それら単一の制御入力に対応していないためチェックビットであり、私がそれらをいじくるとヘリコプターが応答しないようです。それはある種のCRCだと思いますが、それを理解することができませんでした。チェックは、「Xビット」の解釈方法に応じて6〜8ビット長であるため、組み合わせることができる方法は多数あります。


6

これはそれほど悪くはありません。最初に、すべてのメッセージに正確に17パルスが含まれていることに注意してください。これにより、メッセージ内の短いスペースは無関係であるという強力な手がかりがすぐにわかります。データは短いまたは長いパルスでエンコードされているようで、これらのパルス間の一定範囲の間隔は許容範囲です。

明らかに、すべてのメッセージは開始ビットとして長いパルスで始まります。これにより、16データビットが残ります。おそらく、初期のビットのいくつかはオペコードであり、おそらく可変長です。私がこれを行っていた場合、最後のビットのいくつかはチェックサムになります。ファームウェアを作成したエンジニアが自分で物事をシンプルに保ちたいと考えているので、どこかに8つのデータビットがあると想定することから始めることができます。次に、メッセージの意味がわかるかどうかを確認します。

long a 1とshort a 0と呼びましょう。逆の場合もありますが、どこかから始めなければなりません。スタートビットの葉を取り除く:

1010001101011010分のスロットル
1010011101011000最大スロットル
1010000001011111分前倒し
1010000000011110最大転送
1010000011011101最大戻る
1010000100011010分前
0000010101011100最大左+最大スロットル
0100010101011110最大右+最大スロットル
1010000101111111左トリム
1010000101011011右トリム

いくつかのものがすぐに飛び出します。明らかに、ビット0はパリティビットです。それ以外の場合は、3ビットのフィールド<15:13>、8ビットのデータ値<12:5>、および別の4ビットのフィールド<4:1>が表示されます。

データ値が低いビット順序から高いビット順序で送信されているようです。そのため、16ビット全体を、私が示しているものとは逆に解釈する方が理にかなっています。

私はこれにもっと時間を費やす気はありませんが、うまくいけば、これであなたはスタートを切ることができました。パリティビットを取り除いて上記のリストを書き直し、整数をLSBからMSBに反転させ、想定された各フィールドを、それと隣接するフィールドの間にスペースを置いて個別に示します。それはあなたにもっと飛び出すことを可能にするかもしれません。また、各ビットの1/0の意味が逆になっている場合があることに注意してください。おそらく、新しいテーブルをそれぞれの方法で書き出し、何かがより意味のある方法であるかどうかを確認します。


ありがとう、これは素晴らしいです!私はそれに正解し、私が見つけたものを見ていきます。他のプロトコルを調べた後、スペースは無関係かもしれないと思い始めましたが、2つの非常に一貫したタイミングがあったため、確信が持てませんでした。それらが重要でなかった場合、それらはもっと変化すると思いました。とにかく試してみます。再度ありがとう
フランビーノ

ええと...私が知る限り、スペース重要です。私はスロットルに集中し、10の異なるスロットル位置でさらにいくつかのサンプルをキャプチャしました。スペースを除外すると、変換方法に関係なく、意味のある数値が得られませんでした。しかし、それらをlong = 1、short = 0として含めると、スロットル値が1から134(リトルエンディアン)にスムーズに移行します。その他のパラメータについてはまだ作業中です
Flambino 2013

私はプロトコルをほぼ完全に理解しましたが、まだ謎が少しあります。あなたがそれにスイングしたいなら、私の質問にたくさんのものを追加しました。いずれにせよ、これまでに助けてくれてありがとう!私は正しい方向に働きました。
フランビーノ2013

@Flambino:私が最初にやったことをはるかに上回っているように見えますが、これは後の考えではほとんど間違った推測であることがわかりました。更新された質問を読みましたが、スペースの長さがどのように使用されているのか正確にはわかりません。表示したすべてのパターンに正確に17のパルスがあり、最後のパルスが偶然に0または1であると見なされた場合に偶然パリティを示しているのは単なる偶然でしょうか。
Olin Lathrop

正直なところ、それは主に私の試行錯誤でした。スペースに使用される2つのタイミングは、パルスのタイミングとまったく同じであるため、意味があると考えました。また、スペースを無視しても有用なバイナリデータが生成されなかった場合は、長いパルス= 1 長いスペース= 1(および短いスペース/パルス= 0)を想定しただ​​けで、すぐに非常に有用なデータが得られました。したがって、プリアンブルパルスの後の最初のスペースは最初のビット(最大右+最大スロットルグラフは最初のビットとして「スペース1」を示します)の後に16パルスが続き、間に15個のスペースがあります。32ビット。
フランビーノ2013
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.