HOME >> 鉄道模型工作室 > レイアウト設置用の速度計を作る 機能テストの実施
製作中であったレイアウト設置用の速度計が出来上がったので、機能チェックのためにミニレイアウトでテストを実施する。 今回もロジック・ミスを発見する。
■ ミニレイアウトでのテスト
机上でチェックした時、なんだか変な動きだったので、テスト的に設置したミニレイアウト上でテストした。 そのレイアウトを下に示す。
装置への電源は5volt 仕様のACアダプターを使って供給した。 またレイアウトにはTOMIXのコントローラから給電させている。 まず装置の作動状態をチェックすると、速度計はゼロ表示され、正常に作動している様子だった。
電車はBトレの赤い電車2両を走行させる。 センサの投光部も正常な様子である。 この時の走行中の動画を下に示す。 表示のチラツキは、LEDと動画の表示タイミングによって生じており、実際はチラツキなく見えている。
次に、多編成の電車を走らせてみたが、速度計は何故だか ”000” の表示なのである ?!
この時の速度計の表示は、時々、変な数字がチラリと見えるが下に示す様に綺麗にゼロが並んでいた。
やはり解せないので、もう一度1両で走らせてみた。
1両で走らせると正常に表示することは確認できたが、何故多編成の車両で走行させるとゼロ表示なのだろうか?
■ ロジックの見直し
どうやらロジックがおかしいと睨んで、タイムチャートを作って冷静に検討した結果、下記のような間違いに気が付いた。
今回のゲート通過を検出する方法は、信号の立ち上がり、あるいは立下りを検知するキャプチャ機能でのパルス計測方法でなく、信号が HIGH か LOW かの状態をチェックする方法を採用している。 チェックのタイミングはメインのループ時間のほぼ 5msec 間隔でチェックされていますので、上記のチャートの様に最後には、異状カウントを実施した後に待機状態に入ってしまう恐れがあります。 このため、異常カウントを表示しているものと推察した。
通過車両が1両の場合は、ゲート間隔 102o よりも短いのでこの異常カウントは発生しません。 しかしBトレでも 2両以上になると、上記の状態に陥るのです。
すると長さ102mmのゲート区間を5msec で駆け抜けたことを示しまので、スケールスピードに換算すると、11,500 Km/h ・・・・・・・・マッハ9の超超音速で駆け抜けましたよと表示しているのです。 でもなんで”000” の表示なのかの疑問を持ちつつ、間違いは間違いなので、ロジックを修正することにした。 その修正ロジックをチャートで示すと下のように図になります。 測定禁止区間を設ける様にしたのです。
測定禁止を示すサブフラグ sflg を設けて測定禁止区間を示す様にしたのです。 この区間の設定は、測定終了後に開始設定をして、INゲートとOUTゲートの両方がON の状態になってから区間解除をするようにしたのだ。 そして、慌てて解除しないようにこの状態が何回か続いてから解除するようにした。
改良後の走行状態の動画を下に紹介する。 正常に作動していることが分かる。
/***************************************** * SpeedMeter-R1 * 2019/3/14 * PIC16F1827 MPLAB X XC8 ******************************************/ #include#define _XTAL_FREQ 8000000 // CONFIG1 #pragma config FOSC = INTOSC #pragma config WDTE = OFF #pragma config PWRTE = ON #pragma config MCLRE = ON #pragma config CP = OFF #pragma config CPD = OFF #pragma config BOREN = ON #pragma config CLKOUTEN = OFF #pragma config IESO = ON #pragma config FCMEN = OFF // CONFIG2 #pragma config WRT = OFF #pragma config PLLEN = ON #pragma config STVREN = ON #pragma config BORV = LO #pragma config LVP = OFF long val; long mstimer; int digit; int flg; int sflg; int dc; int segment_data[]= {0xDE,0x42,0x5D,0x57,0xC3,0x97,0x9F,0xD2,0xDF,0xD7}; char st[3]; void interrupt MStimer(void) { if(TMR2IF==1){ mstimer++; TMR2IF=0; } } void main() { OSCCON = 0b01110010; ANSELA = 0b00000000; ANSELB = 0b00000000; TRISA = 0b00000000; TRISB = 0b00110000; PORTA = 0b00000000; PORTB = 0b00000000; T2CON = 0b00111100; TMR2 = 0; TMR2IF =0; TMR2IE =1; PEIE =1; GIE =1; digit=0; flg=0; sflg=0; val=0; mstimer=0; dc=0; while(1){ if(RB4==0 && flg==0 && sflg==0){ mstimer=0; flg=1; } if(RB5==0 && flg==1){ val=56787/mstimer; flg=0; sflg=1; } if(RB4==1 && RB5==1){ if(dc>=10){ sflg=0; dc=0; } dc++; } st[2]=val/100; st[1]=val/10-st[2]*10; st[0]=val%10; if(digit==2){ PORTA = segment_data[st[2]]; RB1 = 1; __delay_ms(5); RB1 = 0; __delay_us(100); } if(digit==1){ PORTA = segment_data[st[1]]; RB2 = 1; __delay_ms(5); RB2 = 0; __delay_us(100); } if(digit==0){ PORTA = segment_data[st[0]]; RB3 = 1; __delay_ms(5); RB3 = 0; __delay_us(100); } digit++; if(digit ==3) digit=0; } }
結果は良好で、多編成状態でもそれらしく表示していた。
■ 修正したプログラム
修正した最終仕様のプログラムを右に示す。
測定ゲート間の距離は、右行きが 102mm 、左行きが 103mm でした。 そして、計算する実時間は、「時間を計測しよう」(2019/3/7)の実時間に関する換算式を用いて修正している。 下に示すゲートチェックの中に僅か一行で計算されている。
たったこの一行のために、初めてのCコンパイラに挑戦してきたのだ・・・・・・・・・・!
待機状態解除には10回チェックしてる。 時間にして約 50msec であるが、短いようであったら変更するつもりである。
while(1){ if(RB4==0 && flg==0 && sflg==0){ 測定開始 mstimer=0; flg=1; } if(RB5==0 && flg==1){ 測定終了 val=56787/mstimer; flg=0; sflg=1; } if(RB4==1 && RB5==1){ 待機状態解除 if(dc>=10){ sflg=0; dc=0; } dc++; } 表示処理 }
■ まとめ
これで、やっとレイアウトに設置できる速度計が仕上がった。 次はレイアウト工事に入ることにしよう。
ところで、本当にスピード表示って合っているの? いい加減な数字を表示しているだけではないのか?・・・・・・・との陰の声が聞こえてきた!
2019/3/27 作成