目次

光センサー利用

 書籍の付録には、光センサーとなる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の点滅周期が変化します。


目次

inserted by FC2 system