SSブログ

「レイアウトモジュール4」その後・・・・(番外編) [第4モジュール(レイアウトねた)]

※おことわり。
①今回はかなりコア&マニアックな内容になりますので、ご了承の程。
②当方、インフラSEを生業としていますが、プログラミングに関してはスキルがそんなに高くない&今回紹介するソースコードは、片手間のお遊びで作っております。よって、「ここのロジックがおかしい」や「ソースの書き方が汚い」等の苦情は一切受け付けませんのであしからず(滝汗)

その7で紹介した自作の「列車接近警報表示装置」。
4th-module_alert_20210422_006.jpg

実は当初は「直線モジュール」を作る気満々でいたため、踏切の警報装置の為にこれを構想&設計していたわけですが、諸事象によりコーナーモジュールの制作を担当することになったため、流用(仕様変更)してこれを作成。なのでこれを流用して、踏切を作ることも可能です。(※かなり手を加えなおす必要がありますが)

当プログラムのポイントは以下の5つ

・電源投入直後に、センサーや配線等に異常がないかどうかを判断するための、ステータスチェックを実施。
・在線フラグによる、機器作動時間の管理。
・単純ループによる動作なので、設計した時間よりも各動作時間が若干長い・・・かも。
・始点/終点のセンサー間で、もし車両がトラブル発生で撤去された等、列車が不在なっても、一定時間後(5秒後)に反応動作がリセットされる。
・センサーはフォトリフレクタの使用を限定とする。

ちなみに実際のソース内容はこんな感じ(現物をコピペ)

ここから=============================================

// 列車接近警報装置
//Rev V1.2 (2021/4/19)

int led1 = 9;
int led2 = 10;
int led3 = 13;

void setup() {
Serial.begin(9600);
pinMode(led1, OUTPUT);
pinMode(led2, OUTPUT);
pinMode(led3, OUTPUT);
}

// Tflag[0(S1センサ入力),1(S1/センサ入力),2(TrainINS1/S2),3(TrainOn),4(ledOUT),6(TIMECOUNT)}
int Tflag[] = {0,0,0,0,0,0,0};
// 反応動作時間
int OVERTIME = 5; //sec

//赤外線センサー入力
int valS1;
int valS2;
int res;

// 初回起動フラグ
int startFlag = 1;

void loop() {

if ( startFlag == 1 )
{

//起動テスト
digitalWrite(led1,HIGH);
digitalWrite(led2,HIGH);
digitalWrite(led3,HIGH);
delay (3000);

//S1センサーチェック
valS1 = SENSOR_read(0); // S1センサーから読み込む
if ( valS1 > 50 ) {
//S1センサー異常
digitalWrite(led1,LOW);
digitalWrite(led2,LOW);
digitalWrite(led3,HIGH);
delay (50);
digitalWrite(led1,HIGH);
delay (50);
digitalWrite(led1,LOW);
digitalWrite(led3,LOW);
delay (50);
digitalWrite(led1,HIGH);
delay (50);
digitalWrite(led1,LOW);
digitalWrite(led3,HIGH);
delay (50);
digitalWrite(led1,HIGH);
delay (50);
digitalWrite(led1,LOW);
digitalWrite(led3,LOW);
delay (50);
digitalWrite(led1,HIGH);
delay (50);
digitalWrite(led1,LOW);
digitalWrite(led3,HIGH);
delay (50);
digitalWrite(led1,HIGH);
delay (50);
digitalWrite(led1,LOW);
digitalWrite(led3,LOW);
delay (50);
digitalWrite(led1,HIGH);
delay (50);
digitalWrite(led1,LOW);
digitalWrite(led3,HIGH);
delay (50);
digitalWrite(led1,HIGH);
delay (50);
digitalWrite(led1,LOW);
digitalWrite(led3,LOW);
delay (50);
digitalWrite(led1,HIGH);
delay (50);
digitalWrite(led1,LOW);
digitalWrite(led3,HIGH);
delay (50);
digitalWrite(led1,HIGH);
delay (50);
digitalWrite(led1,LOW);
digitalWrite(led3,LOW);
delay (50);
digitalWrite(led1,HIGH);
delay (50);
digitalWrite(led1,LOW);
digitalWrite(led3,HIGH);
delay (50);
digitalWrite(led1,HIGH);
delay (50);
digitalWrite(led1,LOW);
digitalWrite(led3,LOW);
delay (50);
digitalWrite(led1,HIGH);
delay (50);
} else {
//S1センサー正常
digitalWrite(led1,LOW);
digitalWrite(led2,LOW);
digitalWrite(led3,HIGH);
delay (500);
digitalWrite(led1,HIGH);
delay (500);
digitalWrite(led1,LOW);
digitalWrite(led3,LOW);
delay (500);
digitalWrite(led1,LOW);
digitalWrite(led3,HIGH);
delay (500);
digitalWrite(led1,HIGH);
delay (500);
digitalWrite(led1,LOW);
digitalWrite(led3,LOW);
delay (500);
digitalWrite(led1,LOW);
digitalWrite(led3,HIGH);
delay (500);
digitalWrite(led1,HIGH);
delay (500);
digitalWrite(led1,LOW);
digitalWrite(led3,LOW);
delay (500);
}
//S2センサーチェック
valS2 = SENSOR_read(1); // S2センサーから読み込む
if ( valS2 > 50 ) {
//S2センサー異常
digitalWrite(led1,LOW);
digitalWrite(led2,LOW);
digitalWrite(led3,HIGH);
delay (50);
digitalWrite(led2,HIGH);
delay (50);
digitalWrite(led2,LOW);
digitalWrite(led3,LOW);
delay (50);
digitalWrite(led2,HIGH);
delay (50);
digitalWrite(led2,LOW);
digitalWrite(led3,HIGH);
delay (50);
digitalWrite(led2,HIGH);
delay (50);
digitalWrite(led2,LOW);
digitalWrite(led3,LOW);
delay (50);
digitalWrite(led2,HIGH);
delay (50);
digitalWrite(led2,LOW);
digitalWrite(led3,HIGH);
delay (50);
digitalWrite(led2,HIGH);
delay (50);
digitalWrite(led2,LOW);
digitalWrite(led3,LOW);
delay (50);
digitalWrite(led2,HIGH);
delay (50);
digitalWrite(led2,LOW);
digitalWrite(led3,HIGH);
delay (50);
digitalWrite(led2,HIGH);
delay (50);
digitalWrite(led2,LOW);
digitalWrite(led3,LOW);
delay (50);
digitalWrite(led2,HIGH);
delay (50);
digitalWrite(led2,LOW);
digitalWrite(led3,HIGH);
delay (50);
digitalWrite(led2,HIGH);
delay (50);
digitalWrite(led2,LOW);
digitalWrite(led3,LOW);
delay (50);
digitalWrite(led2,HIGH);
delay (50);
digitalWrite(led2,LOW);
digitalWrite(led3,HIGH);
delay (50);
digitalWrite(led2,HIGH);
delay (50);
digitalWrite(led2,LOW);
digitalWrite(led3,LOW);
delay (50);
digitalWrite(led2,HIGH);
delay (50);
digitalWrite(led2,LOW);
digitalWrite(led3,HIGH);
delay (50);
digitalWrite(led2,HIGH);
delay (50);
digitalWrite(led2,LOW);
digitalWrite(led3,LOW);
delay (50);
digitalWrite(led2,HIGH);
delay (50);
} else {
//S2センサー正常
digitalWrite(led2,LOW);
digitalWrite(led3,HIGH);
delay (500);
digitalWrite(led2,HIGH);
delay (500);
digitalWrite(led2,LOW);
digitalWrite(led3,LOW);
delay (500);
digitalWrite(led2,LOW);
digitalWrite(led3,HIGH);
delay (500);
digitalWrite(led2,HIGH);
delay (500);
digitalWrite(led2,LOW);
digitalWrite(led3,LOW);
delay (500);
digitalWrite(led2,LOW);
digitalWrite(led3,HIGH);
delay (500);
digitalWrite(led2,HIGH);
delay (500);
digitalWrite(led2,LOW);
digitalWrite(led3,LOW);
delay (500);
}
digitalWrite(led1,LOW);
digitalWrite(led2,LOW);
delay (3000);
startFlag = 0;
} else {

//通常ループ再開
digitalWrite(led1,HIGH);
digitalWrite(led2,HIGH);

valS1 = SENSOR_read(0); // S1センサーから読み込む
valS2 = SENSOR_read(1); // S2センサーから読み込む

Serial.println(valS1);
Serial.println(valS2);

// S1センサが反応ON時
if ( valS1 > 20 ) {
Tflag[0]=1;
} else {
Tflag[0]=0;
}

// S2センサが反応ON時
if ( valS2 > 20 ) {
Tflag[1]=1;
} else {
Tflag[1]=0;
}

if( Tflag[0]==0 ) {
//S1センサの値が0
if(Tflag[1]==0 ) {
//S2センサの値も0
if( Tflag[3]!=0 ) {
//在線アリ
Tflag[4]=1; //(反応アリ)
Tflag[5]++; //(時間+)
} else {
//在線ナシ
Tflag[4]=0; //(反応ナシ)
Tflag[5]=0;
}
} else {
//S2センサの値0は1
if( Tflag[3]==1 ) {
//在線アリ
Tflag[4]=1; //(反応アリ)
Tflag[5]=1; //(時間+)
} else {
//在線ナシ⇒アリ(S2侵入)
Tflag[2]=2; //(S2侵入)
Tflag[3]=1; //(在線ナシ⇒アリ)
Tflag[4]=1; //(反応ナシ⇒アリ)
Tflag[5]=0; //(時間初期化)
}
}
} else {
//S1センサの値が0でない場合
if( Tflag[1]==0 ) {
//S2センサの値は0
if( Tflag[3]==1 ) {
//在線アリ
Tflag[4]=1; //(反応アリ)
Tflag[5]=1; //(時間+)
} else {
//在線ナシ⇒アリ(S1侵入)
Tflag[2]=1; //(S1侵入)
Tflag[3]=1; //(在線ナシ⇒アリ)
Tflag[4]=1; //(反応ナシ⇒アリ)
Tflag[5]=0; //(時間初期化)
}
} else {
//S2センサの値も1(=在線アリ)
Tflag[4]=1; //(反応アリ)
Tflag[5]=1; //(時間+)
}
}

// 反応動作時間超過の場合、反応
if( Tflag[5] > OVERTIME ){
Tflag[2]=0; //(S1/S2侵入)
Tflag[3]=0; //(在線アリ⇒ナシ)
Tflag[4]=0; //(反応アリ⇒ナシ)
Tflag[5]=0;
}

//反応アリ
if( Tflag[4]!=0 ){
digitalWrite(led1,LOW);
digitalWrite(led2,LOW);
digitalWrite(led3,HIGH);
delay (150);
digitalWrite(led1,HIGH);
digitalWrite(led2,HIGH);
delay (150);
digitalWrite(led1,HIGH);
digitalWrite(led2,HIGH);
delay (150);
digitalWrite(led1,LOW);
digitalWrite(led2,LOW);
digitalWrite(led3,LOW);
delay (150);
digitalWrite(led1,HIGH);
digitalWrite(led2,HIGH);
delay (150);
digitalWrite(led1,HIGH);
digitalWrite(led2,HIGH);
delay (150);
} else {
digitalWrite(led1,HIGH);
digitalWrite(led2,HIGH);
}

}
}

// フォトリフレクターからの読み込み処理(15回読込み平均をとる)
int SENSOR_read(int PinNo) {
long ans ;
int i ;

ans = 0 ;
for (i=0 ; i < 30 ; i++) {
ans = ans + analogRead(PinNo) ; // 指定のアナログピン(0番端子)から読取り
}

return ans/30 ; // 15回の平均値を返す
}

ここまで=============================================

ちなみに現時点で判明している大きな不具合(バグ)の不可避事象としては、以下の2点が確認されており・・・(滝汗)

・フォトリフレクターに強い紫外線(直射日光や赤外線リモコンの光)が照射されることにより誤動作する(反応が続いてしまう)。
・床下機器がスカスカで少ない「サハ」や、貨車等をセンサー上に留置したまたでも、位置によって無検知状態になってしまう。

・・・というわけで、運転会や展示イベント等で誤動作を起こし、電源オフで機能停止されていても、温かい目で見守って頂けたら・・・


ちなみに所属&お世話になっている「相模原鉄道模型クラブ」のこちらの公式動画(1:18~1:25付近)で動作している状態を見ることができます。

(続く)


↓もしよろしかったら、クリックをば・・・↓

鉄道コム



↓ついでに、こちらとこちらも・・・↓


↓さらにこちらもお願いします↓

nice!(0)  コメント(0) 
共通テーマ:趣味・カルチャー

nice! 0

コメント 0

コメントを書く

お名前:
URL:
コメント:
画像認証:
下の画像に表示されている文字を入力してください。

※ブログオーナーが承認したコメントのみ表示されます。

この広告は前回の更新から一定期間経過したブログに表示されています。更新すると自動で解除されます。