センサーライト開発(10) 動作不具合対策

恥ずかしながら、こんな簡単な回路にもかかわらず、動作が不安定で、不具合がなかなか終息できなかった。

電源を入れた直後には設計通りの動作をするのだが、その後、徐々におかしな動作になる。しかし、場合によっては、電源投入直後にもおかしな動作は起きる。つまりは、再現性が乏しく、バグ解析にとっては、極めて困難な事象に悩まされていた。

発生している事象を列挙すると、概ね以下の症状が不定期に発生する。

(1)   電源ONで点灯、5分経過で消灯。人の動き検知で点灯(正常動作)

(2)   電源を入れても照明が点灯しない場合がある

(3)   消灯まで5分と設定しているのに10秒程度で消灯してしまう場合がある

(4)   5分以上全く消灯しない場合がある

上記の症状は、発生条件が特定できるのかも知れないが、数日確認した限りでは、切り分けができなかった。

仕方ないので、想定される原因に対する対策を施してみた。

【想定原因1】人感センサの安定化

入手した人感センサは、電源投入後、安定するまで10秒程度必要で、その間に数回の検知信号が現れるという。発生している事象との関係は、説明できないが、それ以外にも不安定原因があるのかも知れないと言うことで、電源ON後、タイマを起動する前に30秒の待ち時間を挿入。

結果的には、あまり効果がない模様。

【想定原因2】メモリ破壊

不可解な症状が発生する場合は、ソフト的な原因としては、変数のサイズオーバーによる隣接変数領域を破壊することが想定される。プログラムを確認すると・・・・オーマイガッ!!

//Delay 100msec ——————————–

void delay_10ms(unsigned char time){

while(time–){

__delay_ms(10);

}

}

~~~~~~~~~~~~~~~~~~~~~~~~~~~~

delay_10ms(3000){                  // 人感センサ安定化待ち

想定原因1の対策として入れた部分にミス発見。

unsigned char は1バイト(8ビット)サイズで、0~255までの数値しか扱えない。しかし、3000という値を代入してしまっている。Cコンパイラの実装によっては、隣接する変数領域を浸食してしまうことが考えられる。そこで、”unsigned char“を”unsigned short int“に修正。

結果的には、あまり改善効果はない模様。

【想定原因3】照明による検知異常

人感センサは、赤外線により動きを検知する仕組み。赤外線を発するものは、人だけではなく、動物もそうだし、照明機器もある。今回の人感センサは、照明のすぐそばに設置するため、照明の点灯消灯が外乱となる可能性がある。動作検証の段階で、照明が消灯することによって発する赤外線の変化を検知して、消灯してもすぐ点灯するという症状が確認されていた。

センサレンズ(白いキャップ)をはずして、焦電赤外センサにアルミ箔で円筒形のカバーを作成し、照明側を隠すようにしてみた。(写真)

s-20131031人感センサバグ解析001

結果としては、5分以上経っても消灯しない場合が減ったように感じられた。しかし、点灯しっぱなしという症状が完全に解消されたわけではなく、根本解決には至らず。

【想定原因4】PIC動作不良

CPUのポートが、ソケットから抜差ししている間に、異常となり、動作が不安定な症状になっているのではないかと想定。別のPICに交換してみたが、症状改善せず。

【想定原因5】PIC設定ミス

たかだか90行のプログラムで、しかも、何度もロジックを見直し、コンパイラバグまで想定して、代替論理に変更してみたりと、いろいろなことをやってみたので、もはやミスは考えられない。。。

と、思っていたら、偶然発見!!

//Initialization

OPTION_REG      =                          0b11000000;                    // Pull up Off,

CMCON          =    0x00000111;        // ComperlatorOFF

TRISIO            =    0b00011100;       // GP0,1,5:Output GP2,3,4:Input

GPIO               =    0b00000010;       // LEDのみON

上記は、PICの初期設定のため、特殊レジスタに設定値を入れる部分。PICの初期設定は、複雑怪奇と言われ、データシートを読んでやろうとすると、数百ページあるデータシートをあっちこっちあっちこっち、読みながら行わなければならず、極めて面倒。なので、ネットに転がっている先人のノウハウを流用するのが一般的。で、コピペしてきて、自分の条件に合わせて修正すると。

上記の中のミスは、“CMCON=0x00000111;”の部分。

C言語では、変数の値は一般的には10進数で表すが、ハード寄りの事をやろうとすると、16進数や2進数の方が便利な場合が多い。そういう場合は、進数を表す接頭辞を置く。“0x”はそれ以降が16進数であることを、“0b”は2進数であることを表す。

PICの特殊レジスタはビット毎に意味が設定されているため、2進数で設定しなければならないため”0b“とすべきところ”0x“と16進数にしてしまっている。

引用した元の表記が”CMCON=0x07″であったのだが、分解して設定情報を分り易くするためにビット表記に変更した際、xをbに修正することを忘れてしまったようだ。

コンピュータからすれば、文法的には間違っていないので、エラーとして検出してくれない。

いや~~~ まいった。

おそらくは、これが、根本原因。この修正を施して、状況を確認中だが、今までの不可思議な症状は、ほぼ解消されたようである。それにしても、たかだか1文字のタイプミスがここまで困難なバグ取り作業になろうとは。重要なノウハウとして心に刻んでおこう。

前回へ  次回へ

(Visited 3,004 times, 1 visits today)
スポンサーリンク

シェアする

フォローする