恥ずかしながら、こんな簡単な回路にもかかわらず、動作が不安定で、不具合がなかなか終息できなかった。
電源を入れた直後には設計通りの動作をするのだが、その後、徐々におかしな動作になる。しかし、場合によっては、電源投入直後にもおかしな動作は起きる。つまりは、再現性が乏しく、バグ解析にとっては、極めて困難な事象に悩まされていた。
発生している事象を列挙すると、概ね以下の症状が不定期に発生する。
(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】照明による検知異常
人感センサは、赤外線により動きを検知する仕組み。赤外線を発するものは、人だけではなく、動物もそうだし、照明機器もある。今回の人感センサは、照明のすぐそばに設置するため、照明の点灯消灯が外乱となる可能性がある。動作検証の段階で、照明が消灯することによって発する赤外線の変化を検知して、消灯してもすぐ点灯するという症状が確認されていた。
センサレンズ(白いキャップ)をはずして、焦電赤外センサにアルミ箔で円筒形のカバーを作成し、照明側を隠すようにしてみた。(写真)
結果としては、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文字のタイプミスがここまで困難なバグ取り作業になろうとは。重要なノウハウとして心に刻んでおこう。