つじるの忘れんぼ鉄道

DCC自動運転で秋葉原にあった交通博物館のジオラマを目指すブログ

DSbasic 入門してみる(6)往復運転 + 機関車2両

前回の往復運転コードをベースに、機関車2両を互いに発進させるコードを作ります。

と、気軽に始めたはいいものの、いざコードを作り始めると、考えなければいけないことが多く、いきなり難易度が上がったような気がしてきた。。。

忘れないように流れを図にまとめてみました。

 

f:id:tsujiru:20190502004818p:plain

f:id:tsujiru:20190502004833p:plain

f:id:tsujiru:20190502004850p:plain

f:id:tsujiru:20190502004905p:plain

f:id:tsujiru:20190502004920p:plain

 

2台の機関車を行ったり来たりさせたいだけなのに、結構大変。。。

ちなみにここでは、Slot0(アドレス4) と Slot1(アドレス51)の2つの車両を動かす前提でコードを書いています。(下図の4と51)

f:id:tsujiru:20190502013409p:plain

 

コードは下記のとおりです。

※ブログに貼り付けるとタブインデントが消えちゃって可読性悪いですね。。。

GoogleDriveにアップしましたので、DSbasic - Google ドライブ からダウンロードしてください。(今回のコードは[006_s88-shuttle_2xloco_20190501.BAS]というファイルです)

screen(7)
s88start

print "START S88 Control -Shuttle + 2xLoco-"
sleep 5000
pwr 1
acc 31,1
acc 41,1
sleep 5000

'動かす2両のアドレスをSlot0と1に設定する
SLOT0 = getslotaddr(0)
SLOT1 = getslotaddr(1)
print "SLOT 0 = " + SLOT0
print "SLOT 1 = " + SLOT1

'前提:2両の初期位置は、検知区間①、②にすること。
S0Pos = 2
S1Pos = 1
'先発をSlot0に設定
NextLoco = 0

'SLOT0を起動(ESU BR151)
print "BR151 booting..."
dir SLOT0,2
fnc SLOT0,0,1
sleep 5000
fnc SLOT0,1,1
sleep 2000
fnc SLOT0,3,1
sleep 2000
fnc SLOT0,4,1
sleep 2000
fnc SLOT0,9,1
sleep 2000
fnx SLOT0,2
print "BR151 boot completed"
sleep 2000
spd SLOT0,200

sleep 10000

'SLOT1を起動(NGC DD51)
print "DD51 booting..."
dir SLOT1,2
fnc SLOT1,0,1
fnc SLOT1,1,1
print "DD51 boot completed"
sleep 2000
fnx SLOT1,2


while 1


if s88get(2)=1 then
if S0Pos = 2 then
else
print "S88.2 Detected"
S0Pos = 2
sleep 500
'SLO0を停止
spd SLOT0,0
sleep 10000
'ポイントを分岐
acc 31,0
'SLOT1を発進
NextLoco = 1
dir SLOT1,2
sleep 2000
fnx SLOT1,2
sleep 2000
spd SLOT1,200
end if
end if


if s88get(1)=1 then
if S1Pos = 1 then
else
print "S88.1 Detected"
S1Pos = 1
sleep 1000
'SLO1を停止
spd SLOT1,0
sleep 10000
'ポイントを直進
acc 31,1
'SLOT0を発進
NextLoco = 0
dir SLOT0,2
sleep 2000
fnx SLOT0,2
sleep 2000
spd SLOT0,200
end if
end if


if s88get(3)=1 then

'検知区間③に進入した車両がSLOT0の場合
if NextLoco = 0 then
if S0Pos = 3 then
else
print "S88.3 Detected as SLOT0"
S0Pos = 3
spd SLOT0,0
sleep 10000
dir SLOT0,1
sleep 2000
fnx SLOT0,2
sleep 2000
spd SLOT0,200
end if
end if

'検知区間③に進入した車両がSLOT1の場合
if NextLoco = 1 then
if S1Pos = 3 then
else
print "S88.3 Detected as SLOT1"
S1Pos = 3
spd SLOT1,0
sleep 10000
dir SLOT1,1
sleep 2000
fnx SLOT1,2
sleep 2000
spd SLOT1,200
end if
end if

end if

wend

end

キモは、流れ図内にも吹き出しで記載していますが、「NextLoco」値による、命令対象となる機関車の判断ロジックかと思います。(上記の赤文字箇所)

たった2両でこれなので、これ以上増やす場合は、配列とか定義していかないと厳しいのかもしれません。私はプログラマーではないので、そういったコーディングがどこまで可能なのか心配。。。

 

 実行すると、こんな感じでメッセージ出力します。

f:id:tsujiru:20190502012452p:plain

  

実際に動かした動画はこちら。


DSbasic 機関車2両による自動往復運転

 

次は、これをスイッチバック全体で往復させる自動運転かな~

 

つづく

 

DSbasic 入門してみる(5)slot命令

次は、2つの機関車を動かしていきたいので、アドレスベタ打ちのコードをslotに直しておこうと思います。

Slotって?

Slotとは、下図のキャブ画面右側にある4つのロコアドレス登録箇所のことを指します。

f:id:tsujiru:20190501202603p:plain

上記画面だと、Slot0がアドレス3、Slot1がアドレス51、Slot2がアドレス4、Slot3がアドレス22 となります。要は、よく使うロコのアドレスを4つ登録しておくことで、これをクリックするだけで切り替えることができて便利だよー、という機能です。

 ※スロット番号は、0~3です。1~4ではないので注意。

 

DSbasicでも、このスロットを指定して命令を出すことができます。

Wikiを見てみると、Slot関連の命令として以下4つが記載されてます。

f:id:tsujiru:20190501214617p:plain


まずは基本的な命令の「getslotaddr」の動きを確認します。

これは指定したスロットのアドレスを取得するコマンドなので、スロット0~3のアドレスを取得し、それを変数に格納して警笛を鳴らす動きをみてみました。

screen(7)
s88start

pwr 1
print "START S88 Control -slot test-"

SLOT0 = getslotaddr(0)
SLOT1 = getslotaddr(1)
SLOT2 = getslotaddr(2)
SLOT3 = getslotaddr(3)

print SLOT0
print SLOT1
print SLOT2
print SLOT3

sleep 10000
fnx SLOT1,2

end

 実行結果は以下の通り。f:id:tsujiru:20190501202609p:plain

 スロットに設定した、アドレス3,51,4,22 と取得できました。

また18行目のfnxで、SLOT1(アドレス51)のロコが警笛を鳴らすのも確認できました。

 

以上で、 ある程度の動きを把握できたので、前回のアドレスベタ打ちコードをSlotベースに修正しつつ、2両を動かすコードを作ってみます。

 

つづく 

 

DSbasic 入門してみる(4)往復運転+1分岐

前回は単純な往復運転を自動化しました。

今回はポイント制御を追加し、往復するたびに検知区間①と②が入れ替わるようにします。

f:id:tsujiru:20190501161954p:plain

 

コードは以下の通り。

前回からの大きな差分は、検知区間③の処理にポイント(Adr:31)の制御(赤文字箇所)を追加したことで、これにより、検知区間①/②へ順番こに入線するようにしました。

screen(7)
s88start

sleep 5000
pwr 1
print "START S88 Control -Shuttle-"
acc 31,1
acc 41,1
prePos = 0
sleep 4000

dir 51,1
fnc 51,0,1
fnc 51,1,1
sleep 2000
fnx 51,2
sleep 2000
spd 51,200

while 1

if s88get(1)=1 then
if prePos = 1 then
else
print "S88.1 Detected"
prePos = 1
sleep 1000
spd 51,0
sleep 10000
dir 51,2
sleep 2000
fnx 51,2
sleep 2000
spd 51,200
end if
end if

if s88get(2)=1 then
if prePos = 2 then
else
print "S88.2 Detected"
prePos = 2
sleep 500
spd 51,0
sleep 10000
dir 51,2
sleep 2000
fnx 51,2
sleep 2000
spd 51,200
end if
end if

if s88get(3)=1 then
if prePos = 3 then
else
print "S88.3 Detected"
if getacc(31) = 0 then
acc 31,1
end if
if getacc(31) = 1 then
acc 31,0
end if
prePos = 3
spd 51,0
sleep 10000
dir 51,1
sleep 2000
fnx 51,2
sleep 2000
spd 51,200
end if
end if

wend

end

 

上記を実行すると、検知区間に進入して検知されたタイミングに「S88.X Detected」と表示されるので、処理状況をある程度把握できます。

f:id:tsujiru:20190501194410p:plain

デバッグ中などは、print文による出力粒度を上げることで、切り分け作業が楽になります。

 

ということで、実際に動きはこちらの動画をどうぞ。


DSbasic 自動往復運転 + 1分岐

 

おわり

DSbasic 入門してみる(3)往復運転

これまでの(1)(2)の記事で、DSbasicで自動運転を行うための準備体操が終わりました。

今回から、いよいよ実際の自動運転処理を試してみます。

 

往復運転

まず最初は、検知区間②~③を行ったり来たりする単純な往復運転を自動化してみよう!

f:id:tsujiru:20190430221412p:plain

この往復運転については、Yaasanさんのブログでサンプルプログラムを提供してくれています。

 

これはもうパクって参考にさせてもらうしかないですよね!
記事内の「s88test.zip」がそうです。ただ、私とやーさんのS88構成は異なりますので、それを修正してみよー。

 

と気軽に始めたものの、全然意図した動きにならない。。。

 具体的には以下のような挙動に悩まされました。

  • 在線時、s88getのIF条件が繰り返し実行されてしまう。
    よく考えたら当たり前の挙動なんだけど、2つのif文をwhile で永久ループさせているため、end if までの処理が在線検知している間ずっとループしちゃってる。

 ●以下はダメな例

screen(7)
s88start

pwr 1
print "START S88 Control -Shuttle-"
acc 31,1
acc 41,1
sleep 10000

dir 51,1
fnc 51,0,1
fnc 51,1,1
fnx 51,2
spd 51,200

while 1

if s88get(2)=1 then
print "S88.2 Detected"
spd 51,0
sleep 10000

dir 51,2
fnx 51,2
spd 51,200
end if

if s88get(3)=1 then
print "S88.3 Detected"
spd 51,0
sleep 10000

dir 51,1
fnx 51,2
spd 51,200
end if

wend

end

 上記例だと、検知区間②に在線している間はずっと、赤文字箇所がループ実行されちゃう。

これを回避するため、「prePos」という変数を定義し、検知区間に入って最初の一回だけ折り返し処理を実行するようにした。

 

●以下はそれなりにOKな例

'以下の2行はおまじないとして必要。

screen(7)
s88start

 

'DCC電源投入と、ポイント状態や変数を初期化してます。
pwr 1
print "START S88 Control -Shuttle-"
acc 31,1
acc 41,1
prePos = 0
sleep 4000

 

'アドレス51の車両に対して、FWD方向でF0/F1をON、2秒待って汽笛(F2)を鳴らし、2秒待って速度200で発進。

dir 51,1
fnc 51,0,1
fnc 51,1,1
sleep 2000
fnx 51,2
sleep 2000
spd 51,200

'赤文字の while~wend 内を永久ループ

while 1

'検知区間②で在線検知、かつ、prePosが2でない、つまりこの区間で1回目の検知である場合のみ、print文以降の処理を実施。この中でprePos に2を投入しているので、繰り返し処理とならない。

if s88get(2)=1 then
  if prePos = 2 then
  else
  print "S88.2 Detected"
  prePos = 2
  spd 51,0
  sleep 10000
  dir 51,2
  sleep 2000
  fnx 51,2
  sleep 2000
  spd 51,200
  end if
end if

'検知区間③の処理で、上述の②と同様の処理を記述。

if s88get(3)=1 then
  if prePos = 3 then
  else
  print "S88.3 Detected"
  prePos = 3
  spd 51,0
  sleep 10000
  dir 51,1
  sleep 2000
  fnx 51,2
  sleep 2000
  spd 51,200
  end if
end if

wend

end

 

上記対応で定義した「prePos」、要は列車の位置を監視するための変数であり、今後複数の編成を走らせる場合、かなり重要になりそう。。。

なお、dir、fnc、fnx、spd あたりの命令を連続して記述すると、動作が不安定になることがあったため、適宜 sleep 処理を追加しています。

 

ということで、実際に動かしてみた動画です。


DSbasic 単純な自動往復運転

 

 

つづく 

DSbasic 入門してみる(2)S88センサの動作確認

さて本題のDSbasicです。

基本的な情報は、以下のサイトを参照して勉強しましょう。

https://desktopstation.net/wiki/doku.php/dsair2_basic

http://powerele.sblo.jp/article/185553068.html

 

DSbasic の動作確認

そもそも、自分のDSair2環境で、DSbasicが正常に動作するか確認してみましょう。

まずはDSbasic画面を表示し、左側のコンソールに以下を入力しましょう。

screen(7)
s88start
print "s88 detecting test"
end

入力できたら、画面右側のブラウン管画面下部の再生ボタンをクリック。

下図のように「s88 detecting test」と表示されたら、DSbasicが正常に実行されたと考えて大丈夫かと。

f:id:tsujiru:20190430195313p:plain

 

S88センサー情報取得の動作確認

上述の「s88start」を実行することで、DSairのS88機能が動作し始めます。逆に言うと、このコマンドを実行しない限り、DSairはS88センサの情報取得を行わないようです。

f:id:tsujiru:20190430195316p:plain

具体的には、上画面内の下記表記がS88センサの状態を出力した箇所ですが、いつまでたっても全chがゼロのままです。

S88 data: (1-> ) 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0( <-16)

「s88start」を実行することで、上画面内のように検知しているセンサーchが "1" と検出されるようになりました。

ちなみに私が利用しているS88センサは、NuckyさんのS88-N Train Detector(16ch) です。

 

DSbasicでのS88センサ検知情報取得

今回のレイアウトですが、以前に記事にしていた以下のレイアウトです。

f:id:tsujiru:20180828233748p:plain

図内の検知区間①~⑦ が、S88 Detectorの ch1~7 に該当します。

で、これらのセンサーが正常に動作しているかを確認するため、以下のようなbasicを書いて実行しました。(2秒ごとにS88センサのch1~16状態を表示)

screen(7)
s88start
print "s88 detecting test"
FOR i = 0 TO 3000
  CLS
  FOR j=1 to 16
    print "s88(" + j + ")" + s88get(j)
  NEXT j
  sleep 2000
NEXT i
end

下図のように、センサ検知しているch5が "1" と表示されてます。

f:id:tsujiru:20190430195324p:plain

 

車両を動かすと、"1" となっているセンサchも変化しているのが分かります。下図ではch4が検知している状態。

f:id:tsujiru:20190430195328p:plain

 

同様に、ch3が検知している状態。

f:id:tsujiru:20190430195334p:plain

 

ということで、DSbasicからS88センサ状態の取得ができていることを確認できました。

次は、S88センサ状態をもとに、車両を動かす命令を書いていきます。

 

つづく

 

DSbasic 入門してみる(1)DSair2の事前設定

自動運転を実現するうえで、非常に重要な位置づけである DSbasic に入門してみます。

というか、この機能が実装されて遊んでみたかったからDSair2を購入したのであって、入門しなくてどうすんの?って感じです。

 

 DSair2へのアクセサリ登録

DSbasicで参照、操作することとなるアクセサリ(ここではポイント)をDSairへ登録していなかったので、今更だけど登録。

登録は以下の画面で行った。表示されている番号がそのままアドレス番号でした。

f:id:tsujiru:20190430193203p:plain

自分の環境では、アドレスの30、31、40、41 がポイントとして割り当て済みだったので、画面左上の「Edit」ボタンをクリックしてから、該当番号の赤丸アイコンをクリックして、対応する分岐方向のアイコンを選択。

Editモードを解いてから、ポイントのアイコンをクリックすることで、実際のポイントが切り替わることを確認しましょー。

※運悪く41番が次のページになってしまった。未使用のものを非表示にする機能があったらうれしいなぁ~。

 

DSair2へのレイアウト登録

f:id:tsujiru:20180828231247j:plain

続いて、上記のレイアウトをDSair2の画面で登録していきます。

 

f:id:tsujiru:20190430193159p:plain

こんな感じかな~、って程度で適当に登録。

 

作成したら、ポイント等のアドレスを紐づけてあげます。

画面左側メニューの鉛筆マークをクリックして編集モードにします。

f:id:tsujiru:20190430193209p:plain

 

で、対象となるパネルをクリックすると、以下のダイアログが表示されます。

f:id:tsujiru:20190430193213p:plain

 

ここでは、アドレス30のポイントパネルをクリックしている場合となるので、そのアドレス30を入力して「OK」をクリック。

f:id:tsujiru:20190430193217p:plain

 

すると、下図のようにポイントの分岐状態とアドレス番号が表示される。

f:id:tsujiru:20190430193220p:plain

 

画面左側メニューの「矢印」を選択して編集モードを解除し、

ポイントパネルをクリックすると、ポイントが分岐し、黄色表示に切り替わります。

f:id:tsujiru:20190430193223p:plain

これでだいぶ直観的にポイント操作ができるようになります。

 

他のポイントも同様にアドレス設定し、できあがり。

f:id:tsujiru:20190430193226p:plain

 

ここまで、準備作業でした。

 

おわり

ワンコインデコーダをNEM652(8ピン)に接続する

f:id:tsujiru:20190414132449j:plain

NEM652の8ピンコネクタを備えているにも関わらず、まだDCC化していない車両をなんとかしたかったので、Nuckyさんのワンコインデコーダでやってみました。

DCC化対象となる車両のどこまでをDCC化するのかで、必要となるデコーダが変わります。

DCC化対象(前提:8ピン接続) 必要なデコーダ
ヘッドライト・テールライトのみ ワンコインFLデコーダ v4.1 Slim
モーター・ヘッドライト・テールライト ワンコインデコーダ v4.2 Slim
 +
ワンコインFLデコーダ v4.1 Slim

冒頭の写真は、モーター・ヘッドライト・テールライトをDCC化する場合のものです。(下がワンコインデコーダ、上がワンコインFLデコーダ

配線はNuckyさんサイト内の各デコーダの接続図を参照。

 

Nuckyさんのデコーダテスター の8ピンへ接続し、正常に動作していることも確認できました。

f:id:tsujiru:20190414134147j:plain


テスターでの動作確認がとれれば、あとは車両に組み込むだけ。

この8ピンコネクタもNuckyさんが頒布されているものです。

f:id:tsujiru:20190414134551j:plain

 

●ヘッドライトの点灯ヨシ!

f:id:tsujiru:20190414134303j:plain

 

●テールライトの点灯ヨシ!

f:id:tsujiru:20190414134318j:plain

 

動画はないけど、モーター制御による動作もヨシ!

 

ただ、スロットルへのモーター反応がいまいちだったので、CV2(スタート電圧)の値を 15 に変更しました。(デフォルトの値は0)

 

ワンコインデコーダをモータ制御で導入したのは今回が初めてでしたが、BEMFや、CV3(加速率)、CV4(減速率)が未実装であることを今更知りました。加減速率はスピードテーブルをいじることである程度補間できるものなのかなぁ。そもそもスピードテーブルの格納されたCVはいじらないように記載されているのでやめておこう(笑)

ジリジリ進む低速走行が安定するようなチューニングが可能なのか、ちょっと調べてみよう。

 

おわり