LoginSignup
3
1
記事投稿キャンペーン 「2024年!初アウトプットをしよう」

PICAXEで鉄道模型の在線検出と信号機の制御

Last updated at Posted at 2024-01-01

プログラムについて

・予め用意されている変数ではプログラムが見づらくなるので symbol を使用して名前を変えています。

・ポート名、固定値も、symbolで定義してみました。

・2つの信号機を別々に制御するため、ステートマシンを使いました。

・時間管理は、EtimeA = time のように最初のシステム時刻し、以降は calA = time - EtimeA で現在のシステム時刻から、保存しておいたシステム時刻を減算し、if calA >= STPTIM then でタイムアップしたかをチェックしています。

・システム時間は time で取得できますが、16bitの為、連続稼働で18日とちょっと過ぎた時にオーバーフローします。
事前にオーバーフローを検出して2つのステートマシーンが進行IDLE時にtimeを初期化するようにしてみました。

・if 内で演算できませんでしたので

if time - EtimeA  >= STPTIM then

途中演算用の変数 calA を用意して回避しました。

calA = time - EtimeA 
if calA >= STPTIM then 

・debug を 有効にするとプログラムがかなり遅くなるので、タイムアウト時間を短くして動作確認しました。

・複数の時間制御を行うときは、pause を使わない方法でプログラムを作るとよいです。

組み立て

実際は、Cdsセンサ、LEDは別基板にて接続しています。
assy.png

動画

写真

PICAXE-20Mとブレッドボード
スクリーンショット 2024-01-01 23.10.12.png

動作確認用全体写真
スクリーンショット 2024-01-01 23.10.21.png

関連投稿

ソースファイル

;---------------------------------------------------------------------------
; 閉塞信号機 2回路
; [閉塞信号機2.bas]
; Copyright (c) 2024 Ayanosuke(Maison de DCC)
;
; http://maison-dcc.sblo.jp/ http://dcc.client.jp/ http://ayabu.blog.shinobi.jp/
; https://twitter.com/masashi_214
;
; DCC電子工作連合のメンバーです
; https://desktopstation.net/tmi/ https://desktopstation.net/bb/index.php
;
; This software is released under the MIT License.
; http://opensource.org/licenses/mit-license.php
;---------------------------------------------------------------------------

symbol STATE_A = b0 	;w0
symbol STATE_B = b1 	;w0
symbol CH1ADCVAL = b2 	;w1
symbol CH2ADCVAL = b3 	;w1
symbol EtimeA = w2
symbol EtimeB = w3
symbol calA = w4
symbol calB = w5

symbol CH1ADCPORT = c.1
symbol CH2ADCPORT = c.2

symbol ADCHth = 200		;Hth未使用
symbol ADCLth = 60		;60=曇りで照明を付けていないリビング
symbol STPTIM = 10		;停止 10
symbol CAUTIM = 5		;注意 5
symbol DECTIM = 5		;減速 5
;symbol STPTIM = 2		;停止 10 debugモード用
;symbol CAUTIM = 1		;注意  5 debugモード用
;symbol DECTIM = 1		;減速  5 debugモード用

symbol ST_INIT = 0
symbol ST_ADVANCE = 1
symbol ST_ADVIDLE = 2
symbol ST_CAUTION = 3
symbol ST_CAUIDLE = 4
symbol ST_STOP = 5
symbol ST_STPIDLE = 6
symbol ST_DECELE = 7
symbol ST_DECIDLE = 8

adcconfig %000		; b2 = 0 VRef- is 0V , b1-0 = 00 VRef+ is V+ (power supply)
setfreq m16			; m16timeが秒になる

let STATE_A = ST_INIT	; STATE変数に、初期値ST_INITを代入

main: 
;---------- CHA ----------
    select case STATE_A				; ステートマシーン
    	case ST_INIT				; STATE:初期
			STATE_A = ST_ADVANCE
    	case ST_ADVANCE				; STATE:進行状態
			gosub advanceA
			STATE_A = ST_ADVIDLE
    	case ST_ADVIDLE				;進行状態で在線検出を確認
			gosub detection_chk
			if CH1ADCVAL =< ADCLth then	;在線検知したら ST_STOP
				STATE_A = ST_STOP
			endif
		case ST_STOP				;STATE:停止状態
			gosub stopA
			EtimeA = time
			STATE_A = ST_STPIDLE
		case ST_STPIDLE				;停止状態で在線検出
			gosub detection_chk
			if CH1ADCVAL =< ADCLth then 	;在線検知したら ST_STOP
				STATE_A = ST_STOP
			endif
			calA = time - EtimeA 
			if calA >= STPTIM then	;タイムアップしたら ST_CAUTION 
				STATE_A = ST_CAUTION 
			endif
		case ST_CAUTION				;STATE:注意状態
			gosub cautionA
			EtimeA = time			;タイマーリセット
			STATE_A = ST_CAUIDLE
		case ST_CAUIDLE				;注意状態で在線検出を確認
			gosub detection_chk
			if CH1ADCVAL =< ADCLth then  	;在線検知したら ST_STOP
				STATE_A = ST_STOP
			endif
			calA = time - EtimeA 
			if calA >= CAUTIM then	;タイムアップしたらST_ADVNCE
				STATE_A = ST_ADVANCE
			endif
	endselect

;---------- CHB ----------
	select case STATE_B				; ステートマシーン
		case ST_INIT				; STATE:初期
			STATE_B = ST_ADVANCE
		case ST_ADVANCE				; STATE:進行状態
			gosub advanceB
			STATE_B = ST_ADVIDLE
		case ST_ADVIDLE				;進行状態で在線検出を確認
			gosub detection_chk
			if CH2ADCVAL < ADCLth then	;在線検知したら ST_STOP
				STATE_B = ST_STOP
			endif
		case ST_STOP				;STATE:停止状態
			gosub stopB
			EtimeB = time			;現在値のタイマー読み込み
			STATE_B = ST_STPIDLE
		case ST_STPIDLE				;停止状態で在線検出
			gosub detection_chk
			if CH2ADCVAL =< ADCLth then 	;在線検知したら ST_STOP
				STATE_B = ST_STOP
			endif
			calB = time - EtimeB
			if calB >= STPTIM then		;タイムアップしたら ST_CAUTION 
				STATE_B = ST_CAUTION 
			endif
		case ST_CAUTION				;STATE:注意状態
			gosub cautionB
			EtimeB = time			;タイマーセット
			STATE_B = ST_CAUIDLE
		case ST_CAUIDLE				;注意状態で在線検出を確認
			gosub detection_chk
			if CH2ADCVAL =< ADCLth then  	;在線検知したら ST_STOP
				STATE_B = ST_STOP
			endif
			calB = time - EtimeB
			if calB >= DECTIM then		;タイムアップしたらST_DECELE
				STATE_B = ST_DECELE
			endif
		case ST_DECELE				;STATE:減速
			gosub decelerationB
			EtimeB = time			;タイマーセット
			STATE_B = ST_DECIDLE
		case ST_DECIDLE				;減速状態で在線検出を確認
			gosub detection_chk
			if CH2ADCVAL =< ADCLth then  	;在線検知したら ST_STOP
				STATE_B = ST_STOP
			endif
			calB = time - EtimeB
			if calB >= CAUTIM then		;タイムアップしたらST_ADVNCE
				STATE_B = ST_ADVANCE
			endif	
	
	endselect

	gosub timechk					;timeのオーバーフローチェック
;	debug		;有効にするとかなり遅くなる
goto main

;------------------------------------------------------------
;3現示信号機
;------------------------------
;消灯
;------------------------------
ledoffA:
	low b.0
	low b.1
	low b.2
	low b.3
return
;------------------------------
;進行
;------------------------------
advanceA:
    low b.0
	high b.1
	low b.2
	low b.3
return
;------------------------------
;注意
;------------------------------
cautionA:
	high b.0
	low b.1
	low b.2
	high b.3
return
;------------------------------
;停止
;------------------------------
stopA:
	high b.0
	high b.1
	high b.2
	low b.3
return
;------------------------------------------------------------
;4現示信号機
;------------------------------
;消灯
;------------------------------
ledoffB:
	low b.4
	low b.5
	low b.6
	low b.7
return
;------------------------------
;進行
;------------------------------
advanceB:
    low b.4
	high b.5
	low b.6
	low b.7
return
;------------------------------
;注意
;------------------------------
cautionB:
	high b.4
	high b.5
	low b.6
	high b.7
return
;------------------------------
;減速
;------------------------------
decelerationB:
	low b.4
	high b.5
	low b.6
	high b.7
return
;------------------------------
;停止
;------------------------------
stopB:
	high b.4
	high b.5
	high b.6
	low b.7
return
;------------------------------
;ADC取り込み
;------------------------------	
detection_chk:
	readadc CH1ADCPORT,CH1ADCVAL
	readadc CH2ADCPORT,CH2ADCVAL
return
;------------------------------
;time のオーバーフローを確認
;------------------------------	
timechk:
	if time >= 64800 then	; 18日以上 60 x 60 x 18 = 64800
		if STATE_A = ST_ADVIDLE and STATE_B = ST_ADVIDLE then
			time = 0
		endif
	endif
return

PICAXE関連の投稿

PICAXE(ピカクス)でLチカ
https://qiita.com/masashi_214/items/5495503bf6bd82c1980b
PICAXE 最初に調べた事
https://qiita.com/masashi_214/items/d1acb1ecdc32de5a1698
PICAXEで鉄道模型の在線検出と信号機の制御
https://qiita.com/masashi_214/items/c728814df4f7a2453112
PICAXE(ピカクス)のポート設定
https://qiita.com/masashi_214/items/e5d5e1b9817aed754f52
PICAXE(ピカクス) リンク集
https://qiita.com/masashi_214/items/8b630b2c60ddb466b1ac
PICAXE(ピカクス)のpwm設定
https://qiita.com/masashi_214/items/f92e52837a9fa902879f
PICAXEでPWMを使用した調光機能を使って蛍を作る
https://qiita.com/masashi_214/items/0231a75ae0c77c2be206

3
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
1