HOME >> 鉄道模型自動運転システム > ATS列車自動停止システム 信号回路の検討
なんとか PIC マイコンを動かせるようになったので、次に実際の線路とセンサーを使って、初歩的な制御から少しづつステップアップしていく事にする。 まず制御の入力情報となる通過センサのハード回路と処理ソフトの検証から実施しました。
.
■ 通過センサー
通過センサーは、我が実験室では実績のある CdS を使用した光センサを使用することにしている。 そしてセンサ部分は、レイアウト解体時に保管していた右の様なユニットをできるだけ再利用する予定である。
光センサからの信号を処理する回路として、CdS と調整用の半固定抵抗の組合せを使用して、その中間からトランジスタのベース回路に入力している。 この時、抵抗とCdS どちらを電源側に配置するか何時も悩んでいた。 最初に使用したATSシステムでは抵抗を電源側に配置し、その後の自動運転システムなどにはアース側に配置していた。 ポリシーの無い設計で、メリットとデメリットの整理が出来ていないのである。
この件に関しては、「車両検知センサ」を参照ください
今回も悩んだが、後者の配置を選択した。 理由は、断線も無く充分な光の強さが確保されている場合にはスタンバイOK のランプが点灯するようにしたかったからである。
また、今回使用するPIC の電源電圧は、2.0 〜 5.5V とのことであるので、5.0V を使用するため、LED に流す電流を 15 〜 20mA になるように抵抗を変更することにした。 また、半可変抵抗の値を 10KΩとしたが、これで調整できるのかも実際に部品を組んでみて確認した。 2個のCds を直列に配置しているので、車両間の間や、ボギー台車間の隙間でも、誤動作する事のない様に調整可能であった。 ただ、横からの光が強い場合には上に車両が存在するのに、いないぞ!と判断される場合があったが、この様な場所には線路脇に障害物を置けば対策出来る事も確認した。
■ ブレッドボードでの回路構成と簡易レイアウト
今回テストを実施した回路を下に示す。 使用したPICマイコンは、教則本と同じ PIC12F683 を使用し、使用できる電源電圧は 2.0 〜 5.5V であるので、他の処理回路を含めた電源も兼ねて 5.0V とし、制御回路専用のAC アダプターを使用する。
センサからの信号をPICマイコンに入力させるとともに、確認としてLED を点灯させる回路も構成した。 PICマイコンからは、赤、橙、青の信号を点灯させる出力と共に、給電線をON/OFFさせるリレー駆動回路にも出力させる。 入力2ポート、出力4ポート、+BとGNDの8ピンをフルに使用する。
リレー駆動回路は、5V小型リレー 946H-1C-5D を使用する。 コイル電圧 5V、コイル抵抗 125Ω、1回路C接点、接点容量は30VDC時に 2A の仕様である。 信号OFF時にはリレーが通電状態になっている設定とする。 このため、ATSシステムを停止している場合のは、通常の手動運転が可能となる。 また、Pic-Up Voltage は 3.75V 以上なので、コイル保護抵抗は設けず、フリーホイールダイオードだけを接続した。
.
最初に、信号回路のテストを実施するため、センサ2とそれに関係するトランジスタ回路を除いてブレッドボード上に組んだ。 こうすると、PICマイコンのGP3端子が浮いてしまうので、10Kの抵抗を介してGNDに接続した。 そして、下の写真のように、机の上にレールを設置してBトレ車両を走らせた。 レールへの給電はコントローラから直接実施している。
■ プログラムの記述
PICマイコンに書き込むプログラムは、センサ回路と信号回路の作動チェックになるようにと、電車が通るたびに赤信号と橙信号が交互に点灯、電車がいない場合には緑信号が点灯する簡単なプログラムを組んだ。
まず、プログラム記述の基本となるフローチャートを作成した。
EXCELのシートを使用し、センサの通過に合わせて赤色と橙色が交互に点灯するフローである。 この時の記述は、信号がHIGHとかLOWでは無くて、なるべく現実的な現象で記述しておくと、、ロジックの記述に間違いが少なくなる。
例えば、通過センサのS1をチェックとか、その結果によって、信号を赤にする、とか、後から容易に検証できるようにしておく。
#include P12F683.INC __config _BOD_ON & _WDT_OFF & _MCLRE_OFF & _INTOSCIO bcf STATUS, RP0 ; バンク0 clrf GPIO ; GPIO の出力が0になるよう設定 movlw 0x7 ; W ← 7 movwf CMCON0 ; コンパレータをオフ bsf STATUS, RP0 ; バンク1 clrf ANSEL movlw B'101000' movwf TRISIO ; GPIO を出力に設定 bcf STATUS, RP0 ; バンク0 bcf GPIO,0 bcf GPIO,1 bsf GPIO,2 LOOP: btfss GPIO,5 goto $-1 bcf GPIO,1 bcf GPIO,2 bsf GPIO,0 btfsc GPIO,5 goto $-1 bcf GPIO,0 bcf GPIO,1 bsf GPIO,2 btfss GPIO,5 goto $-1 bcf GPIO,0 bc f GPIO,2 bsf GPIO,1 btfsc GPIO,5 goto $-1 bcf GPIO,0 bcf GPIO,1 bsf GPIO,2 goto LOOP end ; プログラム終了
そして、その現象によって、PICの入力はHIGHになるのかLOWになるのか、あるいはPICの出力がHIGHの時はどうなるのかを落ち着いチェックしておく。 このチェックは一度確実に実施しておくと、回路を変更しない限り有効なので、ロジックを変更する度に頭を悩ますことは無いのである。
そして、フローチャートの各要素毎の内容にあわせ、アッセンブラの命令語に置き換えておけば、後は機械的に並べて行くだけである。 例えば、センサS1のチェック結果はONかOFFしかないので、その結果を判断して実行するアクションを指定すればよいのである。 これは、その次に実行プログラムはどこなのかを示すジャンプ命令なのである。
センサ1で列車が来たかどうかをチェックする場合を例にしてみます。
即ち、最初のS1チェックをアッセンブル言語で記述すると
btfss GPIO,5
goto $-1
と記述すればよいのです。
判断命令とその後のジャンプ先の指定は、何時もウロウロするのであるが、上記の様に最初に検討しておけば、その後の作業での間違いや勘違いの発生は防止することができる。
こうして作成したフローチャートを機械的にアッセンブラの命令語にて記述したので右の様なプログラムである。
勿論、記述には順序があります。 最初は使用する石に合わせたプログラムを読み込むヘッダ・ファイルの読み込みとコンフィグ・レジスタの指定を行う。 勿論、この行の行頭は、半角スペースまたはタブで開けておく必要があります。
次に初期設定を行る。 入出力ポートの指定などを行います。 そしてプログラム本体のLOOP部分をフローチャートに合わせて記述します。
記述が完了したら、まずプログラムを名前を付けて保存した後、アセンブラーを使ってアセンブルしてみましょう。 ここで、成功ですとのメッセージが出ない場合は、記述に問題がありますので、問題個所を見つけて修正していきましょう。
アセンブルが成功したら、記述内容はOKという事ですので、アッセンブリしたデータをPICkit 3 を使って書き込ましょう。 そして、システムのハードを準備して、データを書き込んだPICを作動させます。
.
その状態を右の写真に示す。 テストはこのまま実施出来るが、USBを使った電源ではなく、5ボルト用のACアダプターを使用するようにした。
この実際のシステムを使って正常に作動する稼働かを確認しましょう。 フローチャートで記述したロジックが正しかったのどうか、また、フローチャートどうりにアッセンブラ命令を記述したのかどうかが検証されるのです。
もし、思っていたとおりに作動しない場合には、どこが問題だったのかを知ればてプログラムを修正します。 この時、プログラムの修正とPICへの再書き込み作業が繰り返し必要となるので、最初はシステムを実行する回路とPICkit 3 を接続してプログラムの書き換えを実施する方法が良いでしょう。
プログラム修正作業に自信で出来たら、専用の書き込み装置を使ってPICへの書き込みを実施して、修正されたPICを実行装置に装着する作業手順を習得しましょう。 装置をレイアウトに組み込んでしまった後では、この方法でプログラムの修正とかチューニング作業を実施するからです。
また、プログラミング作業の常として、すぐには正常に作動しないものです。 間違い個所や不具合内容を調べ、それを修正して行くことによってノウハウを習得していく事ができます。 まず自分の力で挑戦してみましょう。 それでもダメだった場合は、他の方のアドバイスやネットでの情報収集にて問題を解決していきましょう。
■ ロジック飛びの発生
すぐにはまともに動かなかったが、何とか動くようになったものの、上記ののプログラムは赤と橙のLEDが交互に点灯するように設定したはずなのに、その順番がおかしいのである。 これは、プログラムの問題ではなく、スイッチ回路の問題と直感し、PICの入力ポートと 1KΩの抵抗との間に、0.1μF のパスコンを挿入してみた。
結果は良好であった。 これで信号回路の動作の確認が出来たと判断しました。
次は、線路に給電してリレー回路のチェックを実施しました。
■ 給電ラインの配線
次に、給電制御の確認のために、先方の通過信号であるセンサ2とそれに関係するトランジスタ回路をブレッドボード上に組んでテストを実施する。 この時の状態を下に示す。
テスト路線は、二つの閉塞区間を設け、コントローラからの配線を二手に分けて、一方を制御対象の閉塞区間に、他方を制御外の区間に配線する。 制御対象にある通過センサS1と、先方区間のセンサS2の信号をチェックして、制御対象の閉塞区間を制御する。
#include P12F683.INC ; PIC12F683用のヘッダファイルの読み込み ;;;;; コンフィグレジスタの設定 __config _BOD_ON & _WDT_OFF & _MCLRE_OFF & _INTOSCIO ;;;;; ファイルレジスタの割り当て CT_DELAY1MS qeu 0x20 CT_DELAY100MS equ 0x21 ;;;;; delay10us サブルーチン delay10us goto $+1 goto $+1 goto $+1 goto $+1 goto $+1 goto $+1 goto $+1 goto $+1 return ;;;;; delay1ms サブルーチン delay1ms movlw D'256' movwf CT_DELAY1MS delay1msL call delay10us decfsz CT_DELAY1MS, f goto delay1msL goto $+1 goto $+1 goto $+1 goto $+1 goto $+1 goto $+1 goto $+1 goto $+1 return ;;;;; delay100ms サブルーチン delay100ms movlw D'10' movwf CT_DELAY100MS delay100msL call delay1ms decfsz CT_DELAY100MS, f goto delay100msL return
■ 単なるリレー制御での走行テストの実施
リレーの機能を確認するために、次の様な簡単な制御フローとしした。
.
新しく使用した項目のうち、S2のチェックについてはS1の場合と入力ポートの違いだけなので、
btfss GPIO,3 ;S2をチェック、前方のチェックポイントに来たか?
とすれば良いだけである。 また、線路への通電をOFF は、
bsf GPIO,4 ;リレーをONさせて通電を切り列車を止める
のひとつの命令で実行される。 問題は時間待ちの命令である delay である。
アッセンブラ言語にには、C言語の様な delay 命令は無いので、自分で作るしかないのである。 タイマー割込みなどの高等テクニックがあるようですが、ここではプログラム上で作って見ましょう。 私も教則本を丸写しです。
まず、PICマイコンのクロックについて、学習しておきましょう。 このPiC12F683ではコンフィグ設定で INTOSCIO と指定した場合は、8MHz の内部クロックでマイコンが作動します。 このICのカタログでチェックして見ましょう。
すると、goto、call、return などの命令実行に 1μ秒の時間が掛かります。 このことを使って無駄な命令をマイコンに実行させて、時間を稼ぐ方法です。 この命令をサブルーチンとして定義して置き、必要に応じて呼び出せば良いのです。 そのサブルーチンの部分を取り出したものを右に示します。
ます最初に、ルーチン回数をカウントダウンするレジスタを2個作っておきます。 レジスタの場所は、ICのカタログをチェックし汎用レジスタの空きアドレスを指定しておきます。
CT_DELAY1MS equ 0x20
CT_DELAY100MS equ 0x21
次に、10μ秒を実行するサブルーチン delay10us を作ります。 μという文字は全角文字なので使えないため、よく似た u を使用しています。 そしてこのサブルーチンを使って 1m秒を実行する新たなサブルーチン delay1ms を作ります。 この時、ルーチンの最初にカウントダウンする開始数値をセットします。
movlw D'256'
movwf CT_DELAY1MS
この様にセッティングを行った後、call 命令を使って 10μ秒を実行するサブルーチン delay10us を呼び出し、カウントダウンを一つ減らして行きます。 そして、カウントダウンがゼロになるまで、サブルーチンを呼び出す作業を繰り返します。 ゼロになるとこのサブルーチンを抜け出すようにします。 これは、
delay1msL
call delay10us
decfsz CT_DELAY1MS, f
goto delay1msL
の命令となります。
また、同じ構成で100m秒を実行する新たなサブルーチン delay100ms を作ります。 このようにしてマイコンに無駄な時間を消費させているのです。 C言語の delay 命令も結局はこのような機械的な作業を実施しているものと解釈しています。 コンパイラが自動的に変換して記述してくれているはずです。
ところで、例に示したプログラムでは、100m秒を実行するサブルーチン delay100ms では、30m秒しか実行してくれません。 もし、delay1ms にて 1m秒、delay100ms にて100m秒 を実行させたい場合には、それぞれのカウントダウン開始数値を、
movlw D'256' ⇒ movlw D'86'
movlw D'10' ⇒ movlw D'100'
と記述しなければなりません。 即ち、この数値を変更することによって希望とする時間になるように設定することが出来るのです。 また、ここでは待ち時間を設定するためなので正確さは求めていません。 要するにいい加減な設定でよいのです。 少し長めにしようとか、短めにしようとか自在に設定できますし、 delay 命令を呼び出す前にカウントダウン数値を設定しておくと、個別のシーンでの調整も可能です。
注意点として、数値の最大値は 256 です。 こう以上の設定をしたい場合には、delay 命令を複数回呼び出すとか、サブルーチンをもう一つ加える必要があります。 ここでは、delay1ms の設定を最大値にしておき、 delay100ms にて時間調整が出来るようにしています。
走行テスト中は、あちこち修正しながら実施してなんとかリレーも正常に作動することが確認出来た。
2019/8/27 作成