DCCデコーダ 自作 や CH32V003 開発 に興味がある方へ。
この記事では、ワンコインデコーダXの開発で最も重要だった
「DCC信号解析コアをゼロから自作した理由」 を詳しく解説します。
- なぜ既存の NMRA DCCライブラリ(NmraDcc) を使わなかったのか
- CH32V003 の 16KB Flash / 2KB RAM という制約の中でどう最適化したのか
- 高速割り込みやステートマシンをどう活用したのか
これらを、実際の開発経験に基づいてまとめました。
ワンコインデコーダXは、WCH純正の MounRiver Studio Ⅱ(MRS2) と 超低価格RISC-Vマイコン CH32V003 を組み合わせて開発しています。
しかし、一般的な NMRA DCCライブラリ(NmraDcc) は Arduino環境(C++)を前提としており、MRS2のC言語ベアメタル環境とは相性が良くありません。
- Arduino APIへの依存
ライブラリ内部で attachInterrupt() などのArduino特有の関数やタイマー処理が使われており、そのままではコンパイルが通りません。 - C++とC言語の混在による複雑化
互換レイヤーを挟むことは可能ですが、コードが肥大化し、限られたリソースのマイコンでは無視できない負担になります。 - タイマー構造の根本的な違い
AVR(Arduino Uno)や ESP32 と CH32V003 ではタイマーの仕組みが大きく異なり、結局ライブラリ内部の時間計測処理を大幅に書き換える必要があります。
「これなら、移植のためにライブラリを無理やり改造するよりも、CH32V003のハードウェア特性に合わせて自分でゼロから書いた方が圧倒的に早いし、綺麗に仕上がる」と判断しました。
結論:移植コストが高いため、ゼロから自作した方が圧倒的に合理的 でした。
ワンコインデコーダXに採用した「CH32V003」は、1個数十円という驚異的なコストパフォーマンスを誇るRISC-Vマイコンですが、リソースは非常に限られています。
- Flash(プログラム容量):16KB
- RAM(動的メモリ):2KB
汎用的に作られた既存のNMRAライブラリは、あらゆる機能に対応するためコード量が多く、使わない機能まで含まれてしまうため、メモリ消費が大きくなりがちです。
ワンコインデコーダXでは、
- BEMF(逆起電力)によるモーター制御
- 多彩なFXファンクション
- CV読み書き
など、実装したい機能が多数あります。
DCC解析だけでメモリを圧迫するわけにはいきませんでした。
こうして誕生したのが、ワンコインデコーダX専用に最適化した独自DCC解析コア(dcc_core.c / .h) です。
自作にあたり、CH32V003 の特性を最大限に活用しました。
- WCH独自の「高速割り込み(WCH-Interrupt-fast)」
DCC信号は高速なパケットが連続して届くため、信号のエッジ(立ち上がり・立ち下がり)を 数十マイクロ秒単位で正確に検出 する必要があります。
WCHコンパイラの
attribute((interrupt(“WCH-Interrupt-fast”)))
を使うことで、割り込み時のレジスタ退避オーバーヘッドを最小化し、超高速でビット判定を行う割り込みルーチンを実現しました。 - ステートマシンによる超軽量パケット解析
無駄なバッファを使わず、1ビット受信するごとに「プリアンブル待ち → データバイト読み込み → エラーチェック」と状態を遷移させるステートマシン方式を採用。
これにより、RAM消費は数バイトレベル に抑え込めています。
既存ライブラリを使わず自作したことで、次のような大きなメリットが得られました。
- 圧倒的なリソースの節約
DCCコアを極限まで軽量化したことで、16KBのFlashに「高度なモーター制御」や「多数のCVマネージャー」を実装できました。 - 信号の安定性が向上
高速割り込みによりパルスの取りこぼしがなく、実走行でも非常に安定してコマンドを追従します - デバックしやすい
すべて自作コードのため、サービスモード(プログラミングトラック)や Ops モード(PoM)の特殊な挙動も内部処理を追いながら確実にデバッグできます。
安価なマイコンだからこそ、
ライブラリに頼らずハードウェアを限界まで使い切る
という自作デコーダの醍醐味があります。
ワンコインデコーダXのソースコードはWebサイト「ダウンロード」ページで公開しています。
CH32V003でDCCデコーダを作りたい方、MounRiver StudioでRISC-Vを触りたい方は必見です。

