シャープの測距モジュールGP2Y0A21YKとPIC 12F1822 を使って、さっと、手をかざすと点灯するLEDランプを作ってみた。
ランプの上で、さっと手をかざすとピッと音が鳴って、ランプが、点灯、消灯する。
ランプの上で、しばらく手をかざしたままでいると、ピピッと鳴って、調光モードとなり、音が鳴ったところから手を下にやると、だんだん暗くなり、上にやると、だんだん明るくなる。
好みの明るさのところで手をはずすと、そのときの明るさがキープされる仕組み。
明るさの最大値、最小値に達すると、また、ピピッとなる。
手をかざすと点灯するLEDランプ
回路図は、以下のようなもの。
パーツは、手元のジャンク箱のトランジスタとか適当ですが、
測距モジュールは、10cmから80cmまで測れて最大3Vのようなので、そのまま、PICのAD変換でいけると思うのですが、いまいち、思うように反応してくれなかったので、トランジスタをはさんでいます。LEDも実際には、3WのパワーLEDを使っていますが、Vfが3Vくらいで、5Vで作っているので、実質2V、電流制限抵抗を5Ωにしているので、400mAくらい流れるはずですが、実測、200mAくらいでした。と、いうわけで、ゆる~く点灯しているので、ぜんぜん熱くならないので、このまま特に放熱もせずに使っています。
もし、しゃかりきに点灯するのであれば、LED駆動用のトランジスタの見直し(ここで使っているのは、ジャンク箱の古いTrなので、どの道、見直しが必要だと思いますが・・・。)とか、何か放熱対策が必要かも・・・。
明るさのコントロールは、PWMでやっています。
PICのプログラムは、以下のような感じです。
回路もプログラムも変なところがあるかと思いますが、とりあえず、動いています。
参考にされる方が、万が一あるようでしたら、あくまでも、自己責任で・・・。よろしく・・・。
あっ、それと、うちのPC古いのでMPLAB IDEも古いままなので、プログラムは、あまり役に立たないかも・・・。
/************************************************************** 12F1822 LED Motion Control Pin assignment: (1)Vdd (2)RA5 PWM out for LED (3)RA4(AN3) ADC----Distance Sensor GP2Y0A21 (4)RA3 MCLR 10Kohm Resister between Vdd (5)RA2(AN2) (6)RA1 SP out / ICSPCLK (7)RA0 ICSPDAT (8)Gnd **************************************************************/ #include <pic.h> #define _XTAL_FREQ 8000000 __CONFIG( FOSC_INTOSC & WDTE_OFF & PWRTE_ON & MCLRE_OFF & CP_OFF & CPD_OFF & BOREN_ON & CLKOUTEN_OFF & IESO_OFF & FCMEN_OFF ); __CONFIG( WRT_OFF & PLLEN_OFF & STVREN_ON & BORV_25 & LVP_OFF ); //Delay 100msec -------------------------------- void Delay_10ms(unsigned char time){ while(time--){ __delay_ms(10); } } void beep(void){ int i; for(i=1;i<200;i++){ RA1=1; __delay_us(200); RA1=0; __delay_us(200); } } //------------------main void main(void){ unsigned int SW=0, command=0,incliment; int adcv,getv,bright=30; //Initialization OSCCON = 0b01110010; // PLL disable, 4MHz internal clock ANSELA = 0b00010000; //RA4 to ADC TRISA = 0b00111000; //GPIO dirction setting PORTA = 0b00000000; //GPIO initialize //--------------------------------------------------------- //PWM CCP1SEL = 1 ; // 2番ピン(RA5)をCCP1/P1Aピンとして出力 CCP1CON=0b00001100; //PWM mode: P1A, P1C active-high; P1B, P1D active-high // PWM機能(シングル)を使用する T2CON = 0b00000000 ; // TMR2プリスケーラ値を1倍に設定 CCPR1L = 0 ; // デューティ値は0で初期化 PR2 = 0x65 ; // PWMの周期を設定(19kHzで設定) TMR2ON = 1 ; // TMR2(PWM)スタート while(TMR2IF == 0); TRISA5=0; //---------------------------------------------------------- //ADC ADCON1 = 0b00010000; ADCON0 = 0b00001100; //AN3 to ADC //---------------------------------------------------------- while(1){ ADON=1; __delay_ms(1); GO_nDONE = 1; while(GO_nDONE); adcv=ADRESH; if(adcv<=230){ command=1; Delay_10ms(50); ADON=1; __delay_ms(1); GO_nDONE = 1; while(GO_nDONE); adcv=ADRESH; if(adcv>250){ beep(); SW=!SW; if(SW==1){bright=30;} else{bright=0;} CCPR1L=bright; command=0; } else if(SW==1){ beep();Delay_10ms(3);beep(); Delay_10ms(100); getv=adcv; while(command==1){ ADON=1; __delay_ms(1); GO_nDONE = 1; while(GO_nDONE); adcv=ADRESH; if(adcv<250){ if(adcv>getv){ incliment=1; bright+=3; if(bright>90){ bright=90; beep(); Delay_10ms(3); beep(); } } else if(adcv<getv){ incliment=2; bright-=3; if(bright<=3){ bright=3; beep(); Delay_10ms(3); beep(); } } CCPR1L=bright; beep(); Delay_10ms(50); } if(adcv>250)command=0; } } } Delay_10ms(1); } }