今回からレールからDCCのパケットを受信する実験をしたいとおもいます。
そのためにはDCCの規格を読まないといけません。DCCの標準規格はNMRAという団体が策定しています。DCCのパケット情報についての説明はNMRA STANDARDの中のElectrical Standards For Digital Command Controlに電気的な説明が、Communication Standards For Digital Command Controlにパケットについてが記載されています。
そこでこの書類を読んで順番に進めていくのですが、桂庵さんが日本語に翻訳なさっているのでそちらをありがたく参照させていただきます。さらにはDCCパケットの内容についても詳しく説明なさっているので非常に参考になります。
まずは電気的な説明を
DCCではレールに電源とデジタル情報の両方を送出しています。そのために、直流ではなく交流を(正弦波ではなく矩形波)流し、そのパルス幅を用いてデータをデコーダに伝えています(PWM変調)。簡単にいうと、デコーダに伝える情報を「レールの両側に電気を流す方向を変える間隔」として伝えています。ので、通信方式はシリアル通信となります(RS-232Cなどとは関係ない)。
パルス幅が58usがビット”1″、95usから9900usがビット”0″を表しています。が、この規格ではデジタルデコーダは、(中略)52usから64usまでの信号を”1″として検出できなければならない。90usから10000usまでの信号を”0″として検出できなければならない。とされていますので、この通りに信号を読んでいきます。
とりあえずビット幅を計ってみる
なにはともあれこのビット幅を計測できないと始まらないのでこの幅を計ってパソコンに出力するだけというのをやります。
マイコンはAVRを利用します。
回路について概略を説明すると、
- レールからの信号をブリッジダイオードに通しポイントとマイコンを動かすための電力を得る
- AVRの入力端子に抵抗を挟んでレールの信号を入力する(もちろん整流する前の)
- Macとシリアルポート(USB-Serial変換)で接続
この3点だけです。
プログラムは、パルスの立ち上がりでタイマー1の計測を開始し、パルスの立ち下がりでタイマー1で計測した値を取得、シリアルに送信するだけです。
計測した結果を散布図にしたものが次のチャートです。囲んだ部分が上の規格にそったパルスです。
確かに、規格にそった部分にパルスがたくさんならんでいるのですが、明らかに準拠していないパルスがあります。これをどう無視するのか…
パケットの解析
とりあえず、”0″と”1″の羅列をパケットと思われる部分を切り出してみます。
DCCのパケットはプリアンプルと呼ばれる14個以上(デコーダは10個以上で認識)の連続した”1″の後の”0″からスタートします。データに関係ない区切れ目を表す”0″をデータスタートビットと呼びます。その後、1バイト(8ビット)の情報、スタートビットの順に交互にデータが流れ、最後のバイトの次はスタートビット(“0”)ではなく”1″を送出することでパケットの終了を表します。これをパケットエンドビット(“1”)と呼びます。
ということで、とりあえずこれに沿って、プリアンプルごのスタートビットからパケットエンドまでを一行にしてシリアルでパソコンに送るようにプログラムを書き換えます。このとき、上のチャートの規格に沿ってないパルスについては完全に無視(ビット列に含めない、現在受信し終わった部分は捨てない)することにします。
以下が受信した内容です。
000000000000000000000000000111111111111
000000000000000000000000000111111111111
000000000000000000000000000111111111111
000000000000000000000000000111111111111
中略
0111111110000000000111111111111
0111111110000000000111111111111
0111111110000000000111111111111
0111111110000000000111111111111
中略
000000001000111111000000000000111110111111111111
0000000010100101010100000111111111111
00000000100011111000000000000111110111111111111000000001000111111000000000000111110111111111111000000001000111111000000000000111110111111111111
0000000010101100000101000111111111111
00000000100011111000000000000111110111111111111000000001000111111000000000000111110111111111111000000001000111111000000000000111110111111111111
0000000010100101010100000111111111111
00000000100011111000000000000111110111111111111
000000001000111111000000000000111110111111111111000000001000111111000000000000111110111111111111
000000000101100000101000111111111111
000000001000111111000000000000111110111111111111
000000001000111111000000000000111110111111111111000000001000111111000000000000111110111111111111000000001010010101010010100111111111111
00000000100011111000000000000111110111111111111000000001000111111000000000000111110111111111111
00000000000111111000000000000111110111111111111
こんな感じです。何となく受信できているような気がしますので、このパケットの意味を、受信できている事を確認します。
まずは「000000000000000000000000000111111111111」
これをバイトごとに分けるとこのようになります。
0 00000000 0 00000000 0 00000000 1 11111111111
つまり、バイトごとに16進数表記で 0x00 0x00 0x00 というパケットです(最後の1の羅列は次のプリアンプル部)。これはすべてのデコーダへのリセット命令です。という事ははじめに送信されているので合ってそうな気がします。
次の「0111111110000000000111111111111」は0xff 0x00 0xffですが、これはアイドルパケットです。
その後にいろいろ出ていますが一番はじめの「0 00000001 0 00111111 0 00000000 0 00111110 1」を見ていくと、アドレス1の車両へのアドバンスト動作命令です。
ということで
受信できてそうですね。ということで今回は成功です。
車両用、アクセサリ用など個別に今後受信を試し、デコーダの製作をしていくことができそうです。