目次
前
次
光センサー利用
書籍の付録には、光センサーとなるCdSが入っています。
日本国内ではCdSという単語で理解されますが、正式名は
Light Detect Registerなので、この用語が使われて
います。
LDRの特徴は、光が入ると抵抗値が下がり、遮断すると
抵抗値があがります。
この性質を利用して、次のような回路を構成できます。
(夜になると、負荷に電源を供給します)
昼夜は、LDRの抵抗値で判断します。トランジスタを
スイッチとして使い、電源を負荷に接続するか否か
を指定します。
LDRは、利用している元素により抵抗値の範囲が
異なるので、可変抵抗と組合せて、感度を調整
している回路が多く見られます。
PIC内蔵のアナログコンパレータを利用すれば
LDRに直列に接続する抵抗を可変にしないでも
対応できます。また、直流電圧をA/D変換器で
リードし、閾値との比較で制御信号を出力する
処理を書くことも可能です。
書籍で扱っている回路は、以下。
LDRの持っている抵抗値を、電荷の放電を利用して
測定しています。
この回路を動かすコードは以下。
#define OFF 0
#define ON OFF+1
#define DCNT 10
#define XDIV 2
typedef unsigned char UBYTE ;
typedef unsigned short UWORD ;
/* prototype */
void usr_init(void);
void vcharge(void);
UWORD vdischarge(void);
void main(void)
{
UBYTE cnt ;
/* initialize */
usr_init();
/* endless loop */
while (ON) {
/* charge */
vcharge();
/* discharge */
cnt = vdischarge();
/* show value */
PORTB = cnt / XDIV ;
}
}
void usr_init(void)
{
/* disable analog comparator */
CMCON = 0x07 ;
/* initialize PORT values */
PORTA = 0x00 ;
PORTB = 0x00 ;
/* set directions */
TRISA = 0x00 ;
TRISB = 0x00 ;
}
void vcharge(void)
{
/* PA0 : output */
TRISA.F0 = 0 ;
/* charge */
PORTA.F0 = 1 ;
/* delay */
Delay_ms(DCNT);
/* RA0 : input */
TRISA.F0 = 1 ;
}
UWORD vdischarge(void)
{
UWORD result ;
/* clear */
result = 0 ;
/* discharge */
while ( PORTA.F0 == ON ) {
result++;
}
return result ;
}
積分回路で利用した内容とほぼ同じ。
測定に利用する回路は、以下となります。
充放電の計測を、関数に一任してわかりやすくします。
#define OFF 0
#define ON OFF+1
#define DCNT 10
#define THRESHOLD 180
typedef unsigned char UBYTE ;
typedef unsigned short UWORD ;
/* prototype */
void usr_init(void);
UWORD Read_LDR(void);
void vcharge(void);
UWORD vdischarge(void);
void main(void)
{
UWORD ldrv ;
UBYTE x ;
/* initialize */
usr_init();
/* endless loop */
while (ON) {
/* measure */
ldrv = Read_LDR();
/* judge */
x = OFF ;
if ( ldrv > THRESHOLD ) { x = ON ; }
/* impress */
PORTB.F0 = x ;
}
}
UWORD Read_LDR(void)
{
UWORD result ;
/* charge */
vcharge();
/* discharge */
result = vdischarge();
return result ;
}
void usr_init(void)
{
/* disable analog comparator */
CMCON = 0x07 ;
/* initialize PORT values */
PORTA = 0x00 ;
PORTB = 0x00 ;
/* set directions */
TRISA = 0x00 ;
TRISB = 0x00 ;
}
void vcharge(void)
{
/* PA0 : output */
TRISA.F0 = 0 ;
/* charge */
PORTA.F0 = 1 ;
/* delay */
Delay_ms(DCNT);
/* RA0 : input */
TRISA.F0 = 1 ;
}
UWORD vdischarge(void)
{
UWORD result ;
/* clear */
result = 0 ;
/* discharge */
while ( PORTA.F0 == ON ) {
result++;
}
/* adjust */
result >>= 1 ;
return result ;
}
関数Read_LDRを定義し、下位関数を新たに定義していく
トップダウンの手法を採用しています。
LED点滅を、LDSによる光の検出で制御するコードは以下。
#define OFF 0
#define ON OFF+1
#define DCNT 10
#define XFREQ 10
#define THRESHOLD 180
typedef unsigned char UBYTE ;
typedef unsigned short UWORD ;
/* prototype */
void usr_init(void);
UWORD Read_LDR(void);
void vcharge(void);
UWORD vdischarge(void);
void main(void)
{
UWORD ldrv ;
/* initialize */
usr_init();
/* endless loop */
while (ON) {
/* measure */
ldrv = Read_LDR();
/* flashing */
while ( ldrv < XFREQ ) {
/* inverse */
PORTB.F0 = ~PORTB.F0;
/* measure */
ldrv = Read_LDR();
while ( ldrv < XFREQ ) {
/* measure */
ldrv = Read_LDR();
}
}
}
}
UWORD Read_LDR(void)
{
UWORD result ;
/* charge */
vcharge();
/* discharge */
result = vdischarge();
return result ;
}
void usr_init(void)
{
/* disable analog comparator */
CMCON = 0x07 ;
/* initialize PORT values */
PORTA = 0x00 ;
PORTB = 0x00 ;
/* set directions */
TRISA = 0x00 ;
TRISB = 0x00 ;
}
void vcharge(void)
{
/* PA0 : output */
TRISA.F0 = 0 ;
/* charge */
PORTA.F0 = 1 ;
/* delay */
Delay_ms(DCNT);
/* RA0 : input */
TRISA.F0 = 1 ;
}
UWORD vdischarge(void)
{
UWORD result ;
/* clear */
result = 0 ;
/* discharge */
while ( PORTA.F0 == ON ) {
result++;
}
/* adjust */
result >>= 1 ;
return result ;
}
光量によりLEDの点滅周期が変化します。
目次
前
次