Nゲージレイアウト用制御盤 (その4) PWMコントローラ

電気機関車の運転台を模した、PWMコントローラを製作中であるが、これはハンドル類が複数になる予定。
動いている列車を眺めるなら、スイッチ1つで運転ができるパワーパックが欲しい。ということでロータリースイッチ1つで運転できるPWMコントローラを作って制御盤に組み込んだ。

「ArduinoでPWMパワーパックを作ってみた」というページを参考にさせていただいて、それをベースにごちょごちょとカスタマイズ。
アリガトウゴザイマシタ・・。

PWMコントローラ部
プログラムやハード部分がちょっこっと違ったバージョンを3つほど作成した。
4つ目のパワーパックはトミックスのパワーパック。
ここまでを制御盤上に置くことにした。

現在作成中の電気機関車の運転台を模したコントローラはPICマイコンを使ったものになるが、電車用も作るつもりなので、パワーパックは合計6台。

一方、レイアウトの方は固定式として線路配置の案もできた。
運転線区は上り線、下り線、機関区など8個のブロックになる。
運転線区とパワーパックをくくりつけてしまうと、PWMコントローラで動かない列車はその線区で運転できなかったり、運転パターンがマンネリになるので、ロータリースイッチでパワーパックと運転線区が切り換えられるようにした。

コントローラ切換えスイッチ
8個ならんでいるロータリースイッチで切り換える。

フィーダー用プッシュターミナル
8連のプッシュターミナルを背面に取り付け、ここから線路に配線する。
となりの2連のプッシュターミナルは、制御盤の外に作る電機用と電車用のコントローラからの入力。

 

スイッチを配置するパネルの部品
スイッチを配置するパネルは合板を使って、表面には文字を印刷したシール。
MP3再生ボードの再生スイッチは基板上にタクトスイッチを配置して、合板にはスイッチ本体分が収まる穴をあけ、表面にはタクトスイッチの丸い頭の部分のみがでるようにした。

ロータリースイッチは軸の部分が樹脂製で長さを自由にカットできるタイプ。
つまみが表面にでるようにしてカットして合板に止めた。

裏から見たところ
裏から見たところ。

スイッチを配置するパネル
スイッチを配置するパネル、完成。

 

サウンド再生用ボタン
ロータリースイッチの左側は、Nゲージレイアウト用制御盤 (その1)で作ったMP3再生ボードの再生スイッチ。
こちらもPICマイコンで制御するつもりだが、駅の発車の合図、発車の際の汽笛類などのサウンドが再生される・・予定。

まだまだ、作りこむ部分がいっぱいあるのだが、なんとか形になってきた。

 

Nゲージレイアウト用制御盤

緑のパネルはポイント切り換え用のスイッチを配置するためのもの。
今はすっきりして見えるけど、そのうち切り換え用のテコがつくとゴチャゴチャします・・

 

で、冒頭にあるようにここで作成したコントローラは、「ArduinoでPWMパワーパックを作ってみた」を参考にさせてもらって作り始めました。
最初からカスタマイズすると何が悪いのかわからなくなるので、まずはHPに掲載されている回路図とソースプログラムをそのまま使用させてもらいました。

 

電源を投入すると7セグメントLEDに値が表示されたが、ロータリースイッチを回していくと多くのポジションで0などと表示され・・どうも、出力先には電圧が印加される気配がない。

ソースを拝見すると、ロータリースイッチの入力を判定する部分は、次の部分のようです。

——–
#define MASCON masconvol( analogRead( 3 ) + 42) // ロータリースイッチ 1~12

int masconvol(int vol){ // マスコン位置検出
// 0~1023の入力を12段階に分ける さらに3段階に分けて真ん中の時だけ採用
// 中途半端な位置の時にでたらめな入力になるので
int a;
if ( (vol * 10 / 284) % 3 == 1 ){
a = 13 – vol / 85;
} else {
a = 0;
}
return a;
}
——–

推測するに、私が作成したロータリースイッチの部分の回路では、analogReadで返される値は、3で割ったときに余りが1にならない?

ひとまず、何が返ってきているのか確認。

ロータリースイッチの部分のみをArduino unoのボードの5V端子とGND端子、A0端子にとりつけ、シリアルモニターに出力。

————-
void setup() {
Serial.begin(115200UL);
}
void loop() {
int value = analogRead(A0);
Serial.println(value);
delay(1000);
}
————-

返ってきた値は、
1023
931
838
745
651
558
464
371
277
184
90
0

ちなみに、ロータリースイッチはノンショーティー。上記のように1000ms毎にanalogReadすると、切り換えた瞬間に、たまに戻ってくる値が1くらいふらつくことがありますが、すぐに安定して同じ値を返してきます。
と、いうことは、余りが1以外で安定されるとマスコンの位置は常に0と判断されます。

 

抵抗の誤差もあるし、電源も基準電圧回路ではないので、もし、動かないのであれば、このあたりのソースを変更されたらいいんじゃないかなぁと思います。
ちがったら、ゴメン m(__)m

 

私の回路の場合、ロータリースイッチを回しきったところ(スイッチ 12)では0が返っていますので、
————-
#define MASCON masconvol( analogRead( 3 ) ) // ロータリースイッチ 1~12
————-
として、

————-

int masconvol(int vol){ // マスコン位置検出
return 12 – (int)(((float)vol / 90.0) + 0.5);
}
として試してみました。

実回路上に組み込むとデバッグが面倒なんで、(float)など、間違いがないようにこれでもかとキャストしてますが・・余分なところは・・当然・・いりません(^^;
+ 0.5 を入れているのは、スイッチ 11の時、89などと90以下の値が返った場合に0となるのを防止するための切り上げです。