今日は、一日中雨がザブザブ降ってたので、久しぶりに電気工作。
MOSFETのドライブ回路の調整は、少しおやすみして、先日eBayで入手した焦電型人感センサを利用したセンサライトの制御回路を造ってみた。
以前造ったものを1Fのトイレで使っているが、今回は2Fのトイレと洗面所用の2つ。
入手したモジュールには、照度センサを追加するパタンも準備されており、そこにCdSセルを載せるだけで、CPUを使わずに照度センサ付人感センサができる。しかし、それだと、明るいときには電気が点かなくなってしまう。洗面所は、明るくても電気を付けて更に明るくしたい場合もあるので困ってしまう。
いろいろと検討した結果、CPUにはPIC12F629という、以前購入してあったチップを使うことにした。
現在利用中のものは、PIC12F629でアセンブラでプログラムを記述した。当時は、まだCコンパイラが無償になっていなかったから。今回は、最新のMPLAB-XにXC8という組合わせ。全て無償の開発環境。
F629は、ちょっと前のチップで割込みを使う場合、レジスタをいちいち退避させねばならない。アセンブラだと、全部自分で書かなければならないのだが、Cでは、コンパイラが自動的に挿入してくれる。非常に賢くありがたい。
F629は、内部オシレータで4MHz発振するのだが、電力消費をとことん抑えるためにRC回路を外付けしてどんな発信周波数になるか試してみることも含めて検証した。外部発信を利用すると、スリープ中に割込みを受けられるという利点もある。処理をちょろちょろとやってすぐにスリープという制御論理を構成すれば、消費電力が大きく削減できる。
試してみると、抵抗22kHz、コンデンサ0.1μFで約4kHzの発振。Foscは1/4なので、1kHz。CPUクロックとしては、超のろいのだが、消費電力はFosc32kHzで35μAだから、それよりも少ないことになる。ちなみに20Mkzで動かすと24mAと700倍程度。大きな省電力効果が得られるはず。
プログラムは、mainではPICの初期設定の記述のみ。あとは、割込みハンドラで、ちょいちょいと記述してあるだけ。いたってシンプル。これだけで照度センサ付人感センサ、できあがり~~~
#include <xc.h>
#pragma config BOREN = OFF, CPD = OFF, FOSC = EXTRCIO, MCLRE = OFF, WDTE = OFF, CP = OFF, PWRTE = OFF #define LED GP1
#define MDS GP2
#define CDS GP4
#define RST_TMR1 64286 // 10秒カウンタの初期値
//****************************************
/* 割込みハンドラ
INT割込みでセンサー検知信号を受信
TMR1割込みで消灯タイミング処理
*/
void interrupt handler( void ){
unsigned char sleep_flag;
// 非同期動作のためカウント値を保護するためカウンタ停止
TMR1ON = 0; // TMR1カウンタ停止
sleep_flag = 0;
// TMR1割込み(180s周期)の場合
if(TMR1IE&&TMR1IF) { // TMR1割込み
TMR1IF = 0; // TMR1割込みフラグクリア
LED = 0; // LED照明消灯
sleep_flag = 1;
}
// INT割込み(人感センサ検知)の場合
if(INTE&&INTF) { // INT割込み
INTF = 0; // INT割込みフラグクリア
if(CDS) LED = 1; // 周囲が暗かったらLED照明点灯
TMR1 = RST_TMR1; // カウンタリセット
TMR1ON = 1; // TMR1カウント再開
}
// 割込み終了処理
GIE = 1; // 割込み許可
if(sleep_flag)SLEEP(); // スリープモードに
}
//#################### main ####
void main(void){
//Initialization
OPTION_REG = 0b11000000; // Pull up Off,
CMCON=0x00000111; // ComperlatorOFF
// 入出力指定
TRISIO = 0b00011100; // GP0,1,5:Output GP2,3,4:Input
// 出力ポート状態初期化
GPIO = 0b00000000; // 0b00000000 = all off
// TMR1初期化
// TMR1割込みでSleepからWakeUpさせるためにはXtalが必要で今回は断念
// TMR1:(1kHz)*8*22500=180s(3m) 毎にタイマー割込みが発生する
// 65536-22500=43036が初期値となる
T1CON = 0b00110000; // クロック源外部(2pin),プリスケール1:8,TMR1停止
LED = 1; // 電源が入ったときは先ずは点灯
// タイマ設定
TMR1 = RST_TMR1; // TMR1初期化
TMR1ON = 1; // TMR1カウント開始
// 割込み設定
PEIE = 1; // 周辺機器割込み許可
INTE = 1; // 外部割込み許可
TMR1IE = 1; // TMR1割込み許可
GIE = 1; // 割込み許可
//———————————————————
while(1){}
}