目次

温度表示装置試作

 ビニルハウスの3地点の温度を表示する
 装置を試作します。

 ビニルハウスの3地点は、以下。

 ビニルハウスには、所々に支柱があり、紐を
 結べるようになっているので、温度センサー
 を吊り下げられるようにします。

 吊下げ用の容器は、半田が入っていた円筒を利用。



 キャップを下にして、温度センサーとワイヤーを入れ
 荷造り紐で、吊り下げられるようにします。



 3地点での計測が必要なので、3本用意して
 吊り下げられるようにしておきます。

 温度センサーは、TI社のLM61CIZを利用。



 マイコンは、使い慣れているのでArduinoを選択。




 Arduinoには、A/D変換器が6チャネルあるので
 セレクタを使わずに、3個の温度センサーから
 電圧を取得できます。

 シリアルインタフェースを利用して、ブレッド
 ボードに挿し込んだ温度センサーの計測温度を
 表示するスケッチを作成。

/*
  therometer.ino

  Pin assignment

  PORTB
    PB5 (output) LED
    PB4 (output) --
    PB3 (output) --
    PB2 (output) --
    PB1 (output) --
    PB0 (output) --
 
  PORTC
    PC5 (output) --
    PC4 (output) --
    PC3 (output) sensor
    PC2 (output) --
    PC1 (output) --
    PC0 (output) --
 
  PORTD
    PD7 (output) --
    PD6 (output) --
    PD5 (output) --
    PD4 (output) --
    PD3 (output) --
    PD2 (output) --
    PD1 (output) TxD
    PD0 (input)  RxD
*/
#include <MsTimer2.h>

#define OFF 0
#define ON  OFF+1

/* pin assignment */
#define LAST   3

#define XINTERVAL 1500
#define XLIMIT    35

/* function prototype */
void update_trigger();
void show_help();
void rs_putchar(char x);
void rs_puts(char *ptr);
void crlf();
void rs_print(int x);

/* variables */
boolean tflag ;
boolean eflag ;
boolean uflag ;
boolean wflag ;

char sbuf[8] ;
byte sindex ;

byte cmd ;
byte xcnt ;
int  adv ;
int  tv ;
int  temp ;

void setup()
{
  /* initialize serial */
  Serial.begin(9600);
  sindex = 0 ;
  rs_puts("Hello !");
  crlf();
  /* clear flags */
  tflag = OFF ;
  eflag = OFF ;
  uflag = OFF ;
  wflag = OFF ;
  /* initialize port values */
  PORTB = 0x00 ;
  PORTC = 0x00 ;
  PORTD = 0x00 ;
  /* initialize port direction */
  DDRB = 0xff ;
  DDRC = 0x00 ;
  DDRD = 0xfe ;
  /* variables */
  xcnt = 0 ;
  /* 1500ms period */
  MsTimer2::set(XINTERVAL,update_trigger);
  /* enable */ 
  MsTimer2::start();
}

void loop()
{
  /* command interpreter */
  if ( uflag == ON ) {
    /* clear flag */
    uflag = OFF ;
    /* get command */
    cmd = *(sbuf+0) ;
    /* help */
    if ( cmd == '?' ) { show_help(); }
    /* enable */
    if ( cmd == 'G' ) { eflag = ON ; }
    /* disable */
    if ( cmd == 'g' ) { eflag = OFF; }
    /* new line */
    crlf() ;
  }
  /* timer handling */
  if ( tflag == ON ) {
    /* clear flag */
    tflag = OFF ;
    /* get data */
    adv = analogRead(LAST);
    /* convert (voltage) */
    tv = map(adv,0,1023,0,5000);
    /* convert (temparature) */
    temp = map(tv,300,1600,-30,100);
    /* show ( serial )*/
    if ( eflag == ON ) {
      rs_print( temp );
      crlf(); 
    }
    /* judge  warning */
    wflag = OFF ;
    if ( tmep > XLIMIT ) { wflag = ON ; }
  }
}

void update_trigger()
{
  /* set flag */
  tflag = ON ;
  /* inrement */
  xcnt++ ;
  /* flashing */
  PORTB &= 0xdf ;
  if ( wflag == ON ) {
    if ( xcnt & ON ) { PORTB = (ON << 5) ; }
  }
}

void show_help()
{
  rs_puts("? help")    ; crlf();
  rs_puts("G enable")  ; crlf();
  rs_puts("g disable") ; crlf();
}

void rs_putchar(char x)
{
  Serial.write(x);
}

void rs_puts(char *ptr)
{
  while ( *ptr ) {
    rs_putchar( *ptr );
    ptr++;
  }
}

void crlf()
{
  rs_putchar('\r');
  rs_putchar('\n');
}

void rs_print(int x)
{
  char msg[5] ;
  int  tmp ;
  /* default */
  *(msg+4) = '\0' ;
  /* sign */
  *(msg+0) = ' ' ;
  tmp = x ;
  if ( x < 0 ) {
    tmp *= (-1) ;
    *(msg+0) = '-' ; 
  }
  /* generate code */
  *(msg+3) = tmp % 10 + '0' ; tmp /= 10 ;
  *(msg+2) = tmp % 10 + '0' ; tmp /= 10 ;
  *(msg+1) = tmp % 10 + '0' ;
  /* zero surpress */
  if ( *(msg+1) == '0' ) {
    *(msg+1) = ' ' ;
    if ( *(msg+2) == '0' ) { *(msg+2) = ' ' ; }
  }
  /* show */
  rs_puts( msg );
}

/* receive interrupt */
void serialEvent()
{
  char ch;
  if ( Serial.available() > 0 ) {
    /* get 1 character */
    ch = Serial.read();
    /* store */
    *(sbuf+sindex) = ch ;
    /* increment */
    sindex++ ;
    /* judge */
    if ( ch == '\r' ) {
      sindex = 0 ; 
      uflag  = ON ;
    }
  }
}

 スケッチには、コマンドインタプリタを用意して
 計測開始と停止を指定できるようにしています。

 温度を測定するのは、周期1秒ですが、シリアル表示は
 コマンド'G'で開始、'g'で停止します。

 常に計測しておき、必要なときにだけ値を表示する
 のは、省エネを考慮しているため。

 温度センサーは、3個あるので、複数の温度を
 測定して表示するスケッチに改定。

/*
  therometer.ino

  Pin assignment

  PORTB
    PB5 (output) LED
    PB4 (output) --
    PB3 (output) --
    PB2 (output) --
    PB1 (output) --
    PB0 (output) --
 
  PORTC
    PC5 (output) --
    PC4 (output) --
    PC3 (output) --
    PC2 (output) sensor 2(TOP)
    PC1 (output) sensor 1(MIDDLE)
    PC0 (output) sensor 0(BOTTOM)
 
  PORTD
    PD7 (output) --
    PD6 (output) --
    PD5 (output) --
    PD4 (output) --
    PD3 (output) --
    PD2 (output) --
    PD1 (output) TxD
    PD0 (input)  RxD
*/
#include <MsTimer2.h>

#define OFF 0
#define ON  OFF+1

/* pin assignment */
#define BOTTOM 0
#define MIDDLE 1
#define TOP    2
#define LAST   3

#define XINTERVAL 1500
#define XLIMIT    35

/* function prototype */
void update_trigger();
void show_help();
void rs_putchar(char x);
void rs_puts(char *ptr);
void crlf();
void rs_print(int x);

/* variables */
boolean tflag ;
boolean eflag ;
boolean uflag ;
boolean wflag ;

char sbuf[8] ;
byte sindex ;

byte cmd ;
byte xcnt ;
int  adv ;
int  tv ;
int  temp[3] ;

void setup()
{
  /* initialize serial */
  Serial.begin(9600);
  sindex = 0 ;
  rs_puts("Hello !");
  crlf();
  /* clear flags */
  tflag = OFF ;
  eflag = OFF ;
  uflag = OFF ;
  wflag = OFF ;
  /* initialize port values */
  PORTB = 0x00 ;
  PORTC = 0x00 ;
  PORTD = 0x00 ;
  /* initialize port direction */
  DDRB = 0xff ;
  DDRC = 0x00 ;
  DDRD = 0xfe ;
  /* variables */
  xcnt = 0 ;
  /* 1500ms period */
  MsTimer2::set(XINTERVAL,update_trigger);
  /* enable */ 
  MsTimer2::start();
}

void loop()
{
  /* command interpreter */
  if ( uflag == ON ) {
    /* clear flag */
    uflag = OFF ;
    /* get command */
    cmd = *(sbuf+0) ;
    /* help */
    if ( cmd == '?' ) { show_help(); }
    /* enable */
    if ( cmd == 'G' ) { eflag = ON ; }
    /* disable */
    if ( cmd == 'g' ) { eflag = OFF; }
    /* new line */
    crlf() ;
  }
  /* timer handling */
  if ( tflag == ON ) {
    /* clear flag */
    tflag = OFF ;
    /* loop */
    for ( int ii = TOP ; ii > -1 ; ii-- ) {
      /* get data */
      adv = analogRead(ii);
      /* convert (voltage) */
      tv = map(adv,0,1023,0,5000); 
      /* convert (temparature) */
      *(temp+ii) = map(tv,300,1600,-30,100);
      /* show ( serial )*/
      if ( eflag == ON ) {
        if ( ii == BOTTOM ) { rs_putchar('B'); } 
        if ( ii == MIDDLE ) { rs_putchar('M'); }
        if ( ii == TOP    ) { rs_putchar('T'); }
        rs_print( *(temp+ii) );
        if ( ii == BOTTOM ) { crlf(); }
        else                { rs_puts(" : ") ; }
      }
    }
    /* judge  warning */
    wflag = OFF ;
    if ( *(temp+BOTTOM) > XLIMIT ) { wflag = ON ; }
    if ( *(temp+MIDDLE) > XLIMIT ) { wflag = ON ; }
    if ( *(temp+TOP)    > XLIMIT ) { wflag = ON ; }
  }
}

void update_trigger()
{
  /* set flag */
  tflag = ON ;
  /* inrement */
  xcnt++ ;
  /* flashing */
  PORTB &= 0xdf ;
  if ( wflag == ON ) {
    if ( xcnt & ON ) { PORTB = (ON << 5) ; }
  }
}

void show_help()
{
  rs_puts("? help")    ; crlf();
  rs_puts("G enable")  ; crlf();
  rs_puts("g disable") ; crlf();
}

void rs_putchar(char x)
{
  Serial.write(x);
}

void rs_puts(char *ptr)
{
  while ( *ptr ) {
    rs_putchar( *ptr );
    ptr++;
  }
}

void crlf()
{
  rs_putchar('\r');
  rs_putchar('\n');
}

void rs_print(int x)
{
  char msg[5] ;
  int  tmp ;
  /* default */
  *(msg+4) = '\0' ;
  /* sign */
  *(msg+0) = ' ' ;
  tmp = x ;
  if ( x < 0 ) {
    tmp *= (-1) ;
    *(msg+0) = '-' ; 
  }
  /* generate code */
  *(msg+3) = tmp % 10 + '0' ; tmp /= 10 ;
  *(msg+2) = tmp % 10 + '0' ; tmp /= 10 ;
  *(msg+1) = tmp % 10 + '0' ;
  /* zero surpress */
  if ( *(msg+1) == '0' ) {
    *(msg+1) = ' ' ;
    if ( *(msg+2) == '0' ) { *(msg+2) = ' ' ; }
  }
  /* show */
  rs_puts( msg );
}

/* receive interrupt */
void serialEvent()
{
  char ch;
  if ( Serial.available() > 0 ) {
    /* get 1 character */
    ch = Serial.read();
    /* store */
    *(sbuf+sindex) = ch ;
    /* increment */
    sindex++ ;
    /* judge */
    if ( ch == '\r' ) {
      sindex = 0 ; 
      uflag  = ON ;
    }
  }
}

 シリアルインタフェースを利用しての温度値表示
 に加えて、LCDを使い、単独で動作するように
 スケッチを改定してみます。

 LCDは、2行16桁の手持ちを利用。



 LCDへの表示を含めたArduinoスケッチは、以下。

/*
  therometer.ino

  Pin assignment

  PORTB
    PB5 (output) LED
    PB4 (output) --
    PB3 (output) --
    PB2 (output) --
    PB1 (output) --
    PB0 (output) --
 
  PORTC
    PC5 (output) --
    PC4 (output) --
    PC3 (output) --
    PC2 (output) sensor 2(TOP)
    PC1 (output) sensor 1(MIDDLE)
    PC0 (output) sensor 0(BOTTOM)
 
  PORTD
    PD7 (output) D7
    PD6 (output) D6
    PD5 (output) D5
    PD4 (output) D4
    PD3 (output) E
    PD2 (output) RS
    PD1 (output) TxD
    PD0 (input)  RxD
*/
#include <MsTimer2.h>
#include <LiquidCrystal.h>

#define OFF 0
#define ON  OFF+1

/* pin assignment */
#define BOTTOM 0
#define MIDDLE 1
#define TOP    2
#define LAST   3

#define XINTERVAL 1500
#define XLIMIT    35

/* LCD rs , e , D4 , D5 , D6 , D7 */
LiquidCrystal lcd( 2, 3, 4, 5, 6, 7 );

/* function prototype */
void update_trigger();
void show_help();
void rs_putchar(char x);
void rs_puts(char *ptr);
void crlf();
void rs_print(int x);
void makeString();
void oneShot();

/* variables */
boolean tflag ;
boolean eflag ;
boolean uflag ;
boolean wflag ;
boolean oflag ;

char sbuf[8] ;
byte sindex ;

byte cmd ;
byte xcnt ;
int  adv ;
int  tv ;
int  temp[3] ;
char line0[17];

void setup()
{
  /* initialize serial */
  Serial.begin(9600);
  sindex = 0 ;
  rs_puts("Hello !");
  crlf();
  /* clear flags */
  tflag = OFF ;
  eflag = OFF ;
  uflag = OFF ;
  wflag = OFF ;
  oflag = ON ;
  /* initialize port values */
  PORTB = 0x00 ;
  PORTC = 0x00 ;
  PORTD = 0x00 ;
  /* initialize port direction */
  DDRB = 0xff ;
  DDRC = 0x00 ;
  DDRD = 0xfe ;
  /* variables */
  xcnt = 0 ;
  /* 1500ms period */
  MsTimer2::set(XINTERVAL,update_trigger);
  /* enable */ 
  MsTimer2::start();
  /* initialize LCD */
  lcd.begin( 16, 2 );
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print("Measure");
  lcd.setCursor(0, 1);
  lcd.print("Hello, world!");
  /* LCD string default */
  for ( byte i = 0 ; i < 16 ; i++ ) { *(line0+i) = ' ' ; }
  *(line0+ 0) = 'T';
  *(line0+ 4) = '/';
  *(line0+ 5) = 'M';
  *(line0+ 9) = '/';
  *(line0+10) = 'B';
  *(line0+14) = '/';
  *(line0+15) = ':';
  *(line0+16) = '\0';
}

void loop()
{
  /* one time handling */
  if ( oflag == ON ) {
    /* clear flag */
    oflag = OFF ;
    /* default */
    lcd.setCursor(0,1);      
    lcd.print("Namara Firm    ");
  }
  /* command interpreter */
  if ( uflag == ON ) {
    /* clear flag */
    uflag = OFF ;
    /* get command */
    cmd = *(sbuf+0) ;
    /* help */
    if ( cmd == '?' ) { show_help(); }
    /* enable */
    if ( cmd == 'G' ) { eflag = ON ; }
    /* disable */
    if ( cmd == 'g' ) { eflag = OFF; }
    /* one shot */
    if ( cmd == 'T' ) { oneShot(); }
    /* new line */
    crlf() ;
  }
  /* timer handling */
  if ( tflag == ON ) {
    /* clear flag */
    tflag = OFF ;
    /* loop */
    for ( int ii = TOP ; ii > -1 ; ii-- ) {
      /* get data */
      adv = analogRead(ii);
      /* convert (voltage) */
      tv = map(adv,0,1023,0,5000); 
      /* convert (temparature) */
      *(temp+ii) = map(tv,300,1600,-30,100);
      /* show ( serial )*/
      if ( eflag == ON ) {
        if ( ii == BOTTOM ) { rs_putchar('B'); } 
        if ( ii == MIDDLE ) { rs_putchar('M'); }
        if ( ii == TOP    ) { rs_putchar('T'); }
        rs_print( *(temp+ii) );
        if ( ii == BOTTOM ) { crlf(); }
        else                { rs_puts(" : ") ; }
      }
      /* show ( LCD )*/
      makeString();
      lcd.setCursor(0,0);
      lcd.print( line0 );
    }
    /* judge  warning */
    wflag = OFF ;
    if ( *(temp+BOTTOM) > XLIMIT ) { wflag = ON ; }
    if ( *(temp+MIDDLE) > XLIMIT ) { wflag = ON ; }
    if ( *(temp+TOP)    > XLIMIT ) { wflag = ON ; }
  }
}

void update_trigger()
{
  /* set flag */
  tflag = ON ;
  /* inrement */
  xcnt++ ;
  /* flashing */
  PORTB &= 0xdf ;
  if ( wflag == ON ) {
    if ( xcnt & ON ) { PORTB = (ON << 5) ; }
  }
}

void show_help()
{
  rs_puts("? help")    ; crlf();
  rs_puts("G enable")  ; crlf();
  rs_puts("g disable") ; crlf();
  rs_puts("T one shot"); crlf();
}

void rs_putchar(char x)
{
  Serial.write(x);
}

void rs_puts(char *ptr)
{
  while ( *ptr ) {
    rs_putchar( *ptr );
    ptr++;
  }
}

void crlf()
{
  rs_putchar('\r');
  rs_putchar('\n');
}

void rs_print(int x)
{
  char msg[5] ;
  int  tmp ;
  /* default */
  *(msg+4) = '\0' ;
  /* sign */
  *(msg+0) = ' ' ;
  tmp = x ;
  if ( x < 0 ) {
    tmp *= (-1) ;
    *(msg+0) = '-' ; 
  }
  /* generate code */
  *(msg+3) = tmp % 10 + '0' ; tmp /= 10 ;
  *(msg+2) = tmp % 10 + '0' ; tmp /= 10 ;
  *(msg+1) = tmp % 10 + '0' ;
  /* zero surpress */
  if ( *(msg+1) == '0' ) {
    *(msg+1) = ' ' ;
    if ( *(msg+2) == '0' ) { *(msg+2) = ' ' ; }
  }
  /* show */
  rs_puts( msg );
}

void makeString()
{
  int tmp ;
  byte i ;
  byte j ;
  
  for ( i = BOTTOM ; i < LAST ; i++ ) {
    /* get value */
    tmp = *(temp+TOP-i) ;
    /* calculate offset */
    j = (i << 2) + i ;
    /* sign handling */
    *(line0+1+j) = ' ' ;
    if ( tmp < 0 ) {
      *(line0+1+j) = '-' ;
      tmp *= (-1); 
    }
    /* x1 */
    *(line0+3+j) = tmp % 10 + '0' ;
    /* x10 */
    tmp /= 10 ;
    *(line0+2+j) = tmp % 10 + '0' ;
  }
}

void oneShot()
{
    for ( int ii = TOP ; ii > -1 ; ii-- ) {
      /* show ( serial )*/
      if ( ii == BOTTOM ) { rs_putchar('B'); } 
      if ( ii == MIDDLE ) { rs_putchar('M'); }
      if ( ii == TOP    ) { rs_putchar('T'); }
      rs_print( *(temp+ii) );
      if ( ii == BOTTOM ) { crlf(); }
      else                { rs_puts(" : ") ; }
    }
}

/* receive interrupt */
void serialEvent()
{
  char ch;
  if ( Serial.available() > 0 ) {
    /* get 1 character */
    ch = Serial.read();
    /* store */
    *(sbuf+sindex) = ch ;
    /* increment */
    sindex++ ;
    /* judge */
    if ( ch == '\r' ) {
      sindex = 0 ; 
      uflag  = ON ;
    }
  }
}

 このスケッチでは、1回限りの計測温度値を表示する
 コマンド'T'を用意しました。

 試作装置は、次のようにまとめるとよいでしょう。



 ビニルハウスの中で、散水もありえるので
 タッパーの中に入れて簡易防水とします。

 温度センサーは、上段、中段、下段に配置するので
 表示のLCDとは、距離があるので上段までワイヤーを
 用意して、配線しておきます。

 マイコンとは、3ピンの凹凸コネクタ、ヘッダで
 接続します。



 端末ソフトで、温度計測をモニタすると
 次のようになります。



 端末ソフトによるモニタがなくても、LCDには
 温度を表示しています。

 上から散水でも、温度センサーがおかしくならない
 ように、キャップを下にして吊り下げ。




 左から赤、黄、青のキャップをつけていますが
 上段、中段、下段と区別できます。

 温度センサー、LCDを接続すると、以下。



 使うときには、タッパーに電池と一緒に組込みます。

 温度の他に、ビニルハウス内で太陽光があるのか
 ないのかを判断できた方が良いと、要求があった
 ので、フォトトランジスタを追加。

 基板上では、ダイオードのように見えます。



 フォトトランジスタ周辺の回路は以下。




 A/D変換値は電圧なので、フォトトランジスタに
 流れる電流を電圧に変換しておきます。

 Arduinoスケッチを、変更して次のようにしました。

/*
  therometer.ino

  Pin assignment

  PORTB
    PB5 (output) LED
    PB4 (output) --
    PB3 (output) --
    PB2 (output) --
    PB1 (output) --
    PB0 (output) --
 
  PORTC
    PC5 (output) --
    PC4 (output) --
    PC3 (output) day sensor
    PC2 (output) sensor 2(TOP)
    PC1 (output) sensor 1(MIDDLE)
    PC0 (output) sensor 0(BOTTOM)
 
  PORTD
    PD7 (output) D7
    PD6 (output) D6
    PD5 (output) D5
    PD4 (output) D4
    PD3 (output) E
    PD2 (output) RS
    PD1 (output) TxD
    PD0 (input)  RxD
*/
#include <MsTimer2.h>
#include <LiquidCrystal.h>

#define OFF 0
#define ON  OFF+1

/* pin assignment */
#define BOTTOM  0
#define MIDDLE  1
#define TOP     2
#define LAST    3
#define SENSORD 3

#define XINTERVAL 1500
#define XLIMIT    35
#define YLIMIT    375

/* LCD rs , e , D4 , D5 , D6 , D7 */
LiquidCrystal lcd( 2, 3, 4, 5, 6, 7 );

/* function prototype */
void update_trigger();
void show_help();
void rs_putchar(char x);
void rs_puts(char *ptr);
void crlf();
void rs_print(int x);
void makeString();
void oneShot();
void getDsensor();

/* variables */
boolean tflag ;
boolean eflag ;
boolean uflag ;
boolean wflag ;
boolean oflag ;
boolean dflag ;

char sbuf[8] ;
byte sindex ;

byte cmd ;
byte xcnt ;
int  adv ;
int  tv ;
int  temp[4] ;
char line0[17];

void setup()
{
  /* initialize serial */
  Serial.begin(9600);
  sindex = 0 ;
  rs_puts("Hello !");
  crlf();
  /* clear flags */
  tflag = OFF ;
  eflag = OFF ;
  uflag = OFF ;
  wflag = OFF ;
  oflag = ON ;
  dflag = OFF ;
  /* initialize port values */
  PORTB = 0x00 ;
  PORTC = 0xf0 ;
  PORTD = 0x00 ;
  /* initialize port direction */
  DDRB = 0xff ;
  DDRC = 0x00 ;
  DDRD = 0xfe ;
  /* variables */
  xcnt = 0 ;
  /* 1500ms period */
  MsTimer2::set(XINTERVAL,update_trigger);
  /* enable */ 
  MsTimer2::start();
  /* initialize LCD */
  lcd.begin( 16, 2 );
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print("Measure");
  lcd.setCursor(0, 1);
  lcd.print("Hello, world!");
  /* LCD string default */
  for ( byte i = 0 ; i < 16 ; i++ ) { *(line0+i) = ' ' ; }
  *(line0+ 0) = 'T';
  *(line0+ 4) = '|';
  *(line0+ 5) = 'M';
  *(line0+ 9) = '|';
  *(line0+10) = 'B';
  *(line0+14) = '|';
  *(line0+16) = '\0';
}

void loop()
{
  /* one time handling */
  if ( oflag == ON ) {
    /* clear flag */
    oflag = OFF ;
    /* default */
    lcd.setCursor(0,1);      
    lcd.print("Namara Firm    ");
  }
  /* command interpreter */
  if ( uflag == ON ) {
    /* clear flag */
    uflag = OFF ;
    /* get command */
    cmd = *(sbuf+0) ;
    /* help */
    if ( cmd == '?' ) { show_help(); }
    /* enable */
    if ( cmd == 'G' ) { eflag = ON ; }
    /* disable */
    if ( cmd == 'g' ) { eflag = OFF; }
    /* one shot */
    if ( cmd == 'T' ) { oneShot(); }
    /* day or night */
    if ( cmd == 'D' ) {
      if ( dflag == ON ) { rs_putchar('D'); }
      else               { rs_putchar('N'); }
      rs_putchar(' ');
      rs_print( *(temp+LAST) );
      crlf(); 
    }
    /* new line */
    crlf() ;
  }
  /* timer handling */
  if ( tflag == ON ) {
    /* clear flag */
    tflag = OFF ;
    /* Day light sensing */
    getDsensor();
    /* loop */
    for ( int ii = TOP ; ii > -1 ; ii-- ) {
      /* get data */
      adv = analogRead(ii);
      /* convert (voltage) */
      tv = map(adv,0,1023,0,5000); 
      /* convert (temparature) */
      *(temp+ii) = map(tv,300,1600,-30,100);
      /* show ( LCD )*/
      makeString();
      lcd.setCursor(0,0);
      lcd.print( line0 );
    }
    /* show ( serial )*/
    if ( eflag == ON ) { oneShot(); }
    /* judge  warning */
    wflag = OFF ;
    if ( *(temp+BOTTOM) > XLIMIT ) { wflag = ON ; }
    if ( *(temp+MIDDLE) > XLIMIT ) { wflag = ON ; }
    if ( *(temp+TOP)    > XLIMIT ) { wflag = ON ; }
  }
}

void update_trigger()
{
  /* set flag */
  tflag = ON ;
  /* inrement */
  xcnt++ ;
  /* flashing */
  PORTB &= 0xdf ;
  if ( wflag == ON ) {
    if ( xcnt & ON ) { PORTB = (ON << 5) ; }
  }
}

void show_help()
{
  rs_puts("? help")        ; crlf();
  rs_puts("G enable")      ; crlf();
  rs_puts("g disable")     ; crlf();
  rs_puts("T one shot")    ; crlf();
  rs_puts("D day or night"); crlf();
}

void rs_putchar(char x)
{
  Serial.write(x);
}

void rs_puts(char *ptr)
{
  while ( *ptr ) {
    rs_putchar( *ptr );
    ptr++;
  }
}

void crlf()
{
  rs_putchar('\r');
  rs_putchar('\n');
}

void rs_print(int x)
{
  char msg[5] ;
  int  tmp ;
  /* default */
  *(msg+4) = '\0' ;
  /* sign */
  *(msg+0) = ' ' ;
  tmp = x ;
  if ( x < 0 ) {
    tmp *= (-1) ;
    *(msg+0) = '-' ; 
  }
  /* generate code */
  *(msg+3) = tmp % 10 + '0' ; tmp /= 10 ;
  *(msg+2) = tmp % 10 + '0' ; tmp /= 10 ;
  *(msg+1) = tmp % 10 + '0' ;
  /* zero surpress */
  if ( *(msg+1) == '0' ) {
    *(msg+1) = ' ' ;
    if ( *(msg+2) == '0' ) { *(msg+2) = ' ' ; }
  }
  /* show */
  rs_puts( msg );
}

void makeString()
{
  int tmp ;
  byte i ;
  byte j ;
  /* thermometer */
  for ( i = BOTTOM ; i < LAST ; i++ ) {
    /* get value */
    tmp = *(temp+TOP-i) ;
    /* calculate offset */
    j = (i << 2) + i ;
    /* sign handling */
    *(line0+1+j) = ' ' ;
    if ( tmp < 0 ) {
      *(line0+1+j) = '-' ;
      tmp *= (-1); 
    }
    /* x1 */
    *(line0+3+j) = tmp % 10 + '0' ;
    /* x10 */
    tmp /= 10 ;
    *(line0+2+j) = tmp % 10 + '0' ;    
  }
  /* day or light */
   *(line0+15) = '_';
   if ( dflag == ON ) { *(line0+15) = '*' ; }
}

void oneShot()
{
  /* temparature */
  for ( int ii = TOP ; ii > -1 ; ii-- ) {

    if ( ii == BOTTOM ) { rs_putchar('B'); } 
    if ( ii == MIDDLE ) { rs_putchar('M'); }
    if ( ii == TOP    ) { rs_putchar('T'); }
    rs_print( *(temp+ii) );
    /* separator */
    rs_puts(" | ");
  }
  /* day or night */
  rs_print( *(temp+LAST) );
  /* new line */
  crlf();
}

void getDsensor()
{
  /* get AD values */
  *(temp+SENSORD) = analogRead(SENSORD);
  /* default */
  dflag = OFF ;
  /* judge */
  if ( *(temp+SENSORD) > YLIMIT ) { dflag = ON ; }
  
}
/* receive interrupt */
void serialEvent()
{
  char ch;
  if ( Serial.available() > 0 ) {
    /* get 1 character */
    ch = Serial.read();
    /* store */
    *(sbuf+sindex) = ch ;
    /* increment */
    sindex++ ;
    /* judge */
    if ( ch == '\r' ) {
      sindex = 0 ; 
      uflag  = ON ;
    }
  }
}

 このスケッチを使い、TeraTermで温度とフォトトランジスタ
 の電圧の変換値を計測すると、次のようになります。



 温度センサーの接続なしで、温度は出鱈目な数値です。


目次

inserted by FC2 system