ワンコインデコーダXシリーズは、「8ピン車載のX」「20ピン車載用のX Plus(BEMF対応)」「8ピン:ファンクション専用のX FL」そして「X(ポイント用)」という、役割の違う4種類のデコーダをラインナップしています。
しかし、驚くべきことにこれら4つのファームウェアは、別々のプロジェクトとして作られているわけではありません。1つの共通ソースコード(C言語プロジェクト)から、用途に合わせて4つの姿に変化して生み出されています。
このページでは、その合理的な「マルチターゲット・アーキテクチャ」の仕組みと、みなさんが「オリジナルデコーダ」を作るときのためのヒントを解説します。
鉄道模型のDCCデコーダを作るうえで最も難しく、デバッグ(バグ修正)に時間がかかるのが「線路からのDCC信号(パルス)を正確に読み取り、パケットとして解釈する処理」です。
もし4種類のデコーダを別々のソースコードで作ってしまうと、DCC信号の読み取り部分にバグが見つかった際、4つのプロジェクトすべてを個別に修正しなければならず、管理が崩壊してしまいます。
そこでワンコインデコーダXでは、DCC信号の受信(dcc_core.c)や、CV値のメモリ保存(cv_manager.c)といった「デコーダの基礎となる心臓部」を全ターゲットで共通化しています。そして、出力(ピンの役割)に関する部分だけを切り替える設計にしました。
どのデコーダとしてコンパイル(プログラムの生成)を行うかは、設定ファイルである decoder_config.h の先頭にあるマクロ(#define)で決定されます。
// ============================================================================
// コンパイル・ターゲットの選択 (※どれか1つだけを有効にする)
// ============================================================================
#define TARGET_8PIN_LOCO // 8ピン 車両用デコーダ (モーター+ライト)
//#define TARGET_20PIN_LOCO // 20ピン 車両用デコーダ (BEMF対応・モーター+ライト拡張)
//#define TARGET_8PIN_FUNC // 8ピン ファンクションデコーダ (モーター無し・ライト専用)
//#define TARGET_8PIN_POINT // 8ピン ポイントデコーダ (アクセサリデコーダ)この例では TARGET_8PIN_LOCO のみが有効(コメントアウトされていない)になっているため、コンパイラはこのコードを「8ピン車載のX版」としてビルドされます。
ターゲットが指定されると、各ソースコードの中にある #ifdef(「もしこのマクロが定義されていたら」という条件分岐)が機能し、必要なコードだけがブロックのようにつなぎ合わされます。
例えば、ピンの初期設定を行う Outputs_Init() 関数の中身は、ターゲットによって全く違う姿になります。
void Outputs_Init(void) {
// 【共通】基本的なGPIOクロックの有効化などは共通で行う
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOC, ENABLE);
#ifdef HAS_MOTOR_OUTPUT
// 車両用・ポイント用の場合は、モーターを回すためのPWMタイマー(TIM1)を起動
RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE);
#endif
#ifdef TARGET_8PIN_FUNC
// ファンクション専用の場合は、モーター用ピンもすべて「ライト出力」として初期化する
GPIO_Init(GPIOC, &light_pin_config);
#endif
#ifdef TARGET_20PIN_LOCO
// 20ピン車両用の場合は、ADC(アナログ電圧読み取り)を起動してBEMF測定の準備をする
BEMF_Init();
#endif
}さらに、CVの初期値を定義している Default_CV_Tab 配列も、ターゲットごとに #ifdef で区切られています。これにより、「車両用のアドレスはCV1(ショートアドレス)」、「ポイント用のアドレスはCV1/CV2(アクセサリアドレスの下位/上位)」といった規格の違いを、1つのファイル内で完全に吸収しています。
このマルチターゲット構造は、「あなたが考えた新しいアイデア」をDCCシステムに組み込むための最高のベース(土台)になります。面倒なDCC信号の解析やCVの保存処理はすべてワンコインデコーダXのコア(共通部分)に任せて、あなたは「出力をどう動かすか」という楽しいプログラミングに専念できます。
派生版・開発のヒント
- decoder_config.h に、新しいターゲット(例:#define TARGET_MY_CROSSING 踏切用デコーダ)を追加します。
- dcc_core.c のコマンド受信部で、指定したアドレスの信号を受信したときのフラグを立てます。
- main.c のメインループや motor_ctrl.c の出力部分に #ifdef TARGET_MY_CROSSING を追記し、「LEDを交互に点滅させる」「サーボモーターを動かして遮断機を下ろす」といった独自の処理を記述します。
C言語の基礎とWCHマイコンの開発環境(MounRiver Studio等)さえあれば、アイデア次第で「トマラン(自動停止)デコーダ」や「室内灯ホタル点滅デコーダ」など、どんなものでも生み出すことができます。
GPLv3ライセンスの元、ぜひ皆さんの手で面白いデコーダを開発し、世界中のDCCファンと共有してみてください!