HOME >> 鉄道模型自動運転システム >  卓上レイアウトで楽しもう 自動運転 その11

卓上レイアウトで楽しもう 自動運転 その11

 今回の内容は、反対側のホームに制御を追加し、さらももうひと列車を入線させて、合計3列車を同時運転させようとの試みの続きです。 今回は、他方のホームに停車している列車がある場合は、そちらの列車も同時に出発させようとするものです。

 

■ 運行ダイヤの検討

 自動運転を実施するための運行ダイヤは下記のパターン4です。 追い抜き列車が通過後3秒後に発せさせる方式は今までと同じですが、この時、他方のホームに停車している列車がある場合は、そちらの列車も同時に出発させるものです。 運行ダイヤを引いてみましたが上手く行きそうなので採用してみました。

 

■ ハード回路の構成

 まず、二つのホームを制御するそれぞれのマイコンを通信させる必要があります。 そこで、空いているポートを使って、発信用と受信用のポートを設定しました。 その回路構成を下に示します。

 PICマイコンの RA0 ポートを送信用の出力ポートし、RA1 ポートを受信用の入力ポートとして設定し、その間を1KΩの抵抗で接続します。 理由は曖昧ですが、何となく10KΩの抵抗でGND と接続させて、LOW 出力時の不安要素取除く事にしました。 全くの素人考えです。

 出発信号は出発OKの信号をHIGH とすることにします。

 

■ プログラムの内容

 先回のプログラムに手を加えて下記のように記述しました。

  1 /*****************************************
  2 *   Takujo-10-1
  3 *           2019/12/20
  4 *           PIC16F1827   MPLAB X   XC8
  5 ******************************************/
  6 #include <xc.h>
  7 
  8 #define _XTAL_FREQ  8000000
  9 
 10 // CONFIG1
 11 #pragma config FOSC = INTOSC    // 内部クロック使用
 12 #pragma config WDTE = OFF       // ウォッチドッグ不使用
 13 #pragma config PWRTE = ON       // パワーアップタイマ
 14 #pragma config MCLRE = ON       // リセットピン
 15 #pragma config CP = OFF         // プログラムメモリ保護
 16 #pragma config CPD = OFF        // データメモリ保護
 17 #pragma config BOREN = ON       // 電源電圧監視
 18 #pragma config CLKOUTEN = OFF   // クロック出力
 19 #pragma config IESO = ON        // クロック切替
 20 #pragma config FCMEN = OFF      // 外部クロック監視
 21 
 22 // CONFIG2
 23 #pragma config WRT = OFF        // フラッシュメモリ保護
 24 #pragma config PLLEN = ON       // 4xPLLの作動
 25 #pragma config STVREN = ON      // スタック時のリセット
 26 #pragma config BORV = LO        // リセット電圧
 27 #pragma config LVP = OFF        // 停電圧プログラミング
 28 
 29 void main()
 30 {
 31     unsigned int spe ;          // デューティ比変数の宣言
 32     
 33     OSCCON = 0b01110010;        // 内部クロック 8MHz設定
 34     ANSELA = 0b00000000;        // I/Oはすべてディジタル使用
 35     ANSELB = 0b00000000;        // I/Oはすべてディジタル使用
 36     TRISA  = 0b00000010;        // I/Oの入出力設定
 37     TRISB  = 0b00001100;        // I/Oの入出力設定
 38     PORTA  = 0b00000000;        // I/Oの初期値設定
 39     PORTB  = 0b00001100;        // I/Oの初期値設定
 40     CCPTMRS = 0b00000000;       // PWM制御タイマ指定
 41     CCP3CON = 0b00001100;       // PWM制御使用宣言
 42     T2CON = 0b00000010;         // プリスケーラ値の設定
 43     PR2 = 124;          // PWMの周期設定 1kHz
 44     CCPR3L = 0;         // カウンタの初期化
 45     CCPR3H = 0;         // カウンタの初期化
 46     TMR2  = 0;          // タイマーの初期化
 47     TMR2ON = 1;         // PWM機能のスタート
 48      

 49     RB0 = 0;            // ポイントの作動チェック
 50     __delay_ms(500);
 51     RB1 = 0;
 52     __delay_ms(500);
 53     RB0 = 1;
 54     __delay_ms(500);
 55     RB1 = 1;
 56     __delay_ms(500);
 57     RB1 = 0;
 58     __delay_ms(500);
 59     
 60     CCPR3L = 255;       // デューティ比100%
 61     RA2 = 1;            // 給電ON
 62     
 63     while(1){
 64         
 65         //STEP1
 66         while(RB2 == 1){        // センサ1を待つ
 67              __delay_ms(10);
 68         }
 69         RB0 = 0;                // P1ポイントを正位に
 70         for(spe=255; spe>-1; spe--){    // 減速開始
 71            CCPR3L = spe ;       // デューティ比出力
 72            __delay_ms(5);
 73         }
 74         RA2 = 0;                // 給電停止
 75         __delay_ms(500);
 76         
 77         //STEP2
 78         while(RB3 == 1 && RA1 == 0){   // センサ2と通信を待つ
 79             __delay_ms(10);
 80         }
 81         RA0 = 1;				   // 通信を発信
 82         RB0 = 1;                // P1ポイントを反位に
 83         __delay_ms(3000);       // 3秒待つ
 84         RA2 = 1;                // 給電開始
 85         for(spe =0; spe<256; spe++){   //加速開始
 86             CCPR3L = spe ;      // デューティ比出力
 87             __delay_ms(5); 
 88          }
 89         RA0 = 0;				   // 通信信号を消す
 90         RB1 = 1;                // P2ポイント反位に
 91         __delay_ms(500);
 92         while(RB3 == 1){        // センサ2を待つ
 93             __delay_ms(10);
 94         }
 95         RB1 = 0;                // P2ポイント正位に
 96         __delay_ms(500);
 97     }
 98 }
 99 

 

 プログラムの修正は、まず、ポートの入出力設定を変更しました。 RA0ポートを出力に、RA1ポートを入力とするために、36行の記述を TRISA = 0b00000010; としました。 また、センサは負論理なので初期値として、39行目を PORTB = 0b00001100; と変更しました。 これはスタート時に列車がピクリと動くのを防止するためです。

 つぎに、発車の条件をウォッチしている 78 行目の記述ですが、センサ2と他方のマイコンからの発車信号どちらかを受けれたら発車すれば良いと、単純に考えて、発車信号のRA1 とのOR論理で記述していました。

    78         while(RB3 == 1 || RA1 == 1){   // センサ2と通信を待つ
    79             __delay_ms(10);
    80         }

 この条件をクリアーするとカッコ内を抜け出して次のステップとして、相手側に発車信号を発信し(81行)、自分も発車して(82〜88行)、出発後は発車信号を消しておく(89行)というプロセスを追加しました。 ところが実際に作動させると、列車はダンマリで発車をしてくれませんでした。 賢明な諸君なら、どこを間違えているかすぐに分かると思いますが、ボンクラ頭の小生には戸惑ってしまいました。

 まず、while(***) { *** } 命令を充分に理解していななかったのです。 (***) が成立している間は、 { *** } を実施せよとの命令ですので、RA1== 1 は反対ですね。 でも、これだけではダメでした。 ORで記述すると、センサがON/OFFに関係なく、発車命令が無い場合はかっこ内は成立しますから抜け出せません。 RA1== 0 の指定は出発禁止指令なのです。 結局、AND 条件にして、センサ信号がOFFで、発車命令が無い場合のみ、停車して待っている状態にすることを指示するように記述しました。

 

   ****************************************************************************************************************

 次に、回路の配線を実施した。 その配線状態をを下に示す。

 先回の配線に通信回路を追加したのみです。 上右の写真。

 

■ 作動状態

 上に示す3列車を同時運行させてみました。

 運行状態は動画のとおりで、順調に機能しています。 そして、いつも同じ列車では面白くないので今度は新幹線のBトレを持ち出しました。 でも最初からトラブル発生です。

 自動運転のシーケンスがどこかで狂ってしまい、上右の写真のように追突事故が発生しました。 旧型客車で構成した列車では順調に作動していたのでプログラム自体はOKと思われますが、細かなチューニングが必要かもしれません。 でもそれよりも、センサとポイントの作動をの信頼性を疑ってみる必要があります。

 まず、センサの作動状態を観察していると、軽い先頭車両では反応していない状態が見受けられました。 Bトレ車両の重さでは反応しない恐れがあります。

 そこで、先頭車両を重点に重りを追加して車重をアップさせました。 この効果は効いたようで、トラブルはほとんどなくなりましたが、それでもゼロではありませんでした。

 新幹線の走行状態を紹介します。

 

 センサもそうですが、ポイントも定期的なメンテナンスが必要と思われます。 月に一度? いや、週に一度かな?  いやいや、面倒なので、トラブル多発になってからにしよーと!

ページトップへ戻る .


 2019/12/22 作成