最低・最高温度記憶機能つきLCD表示温度計 (PIC 16F690)

戻る一つ前のメニューに戻る

PIC 16F690とLM35を用いて、最低・最高温度記憶機能の付いた温度計ユニットの製作。

電流や気圧など電圧で測定値を取り出すタイプのセンサーと交換して、一般的な測定デバイスとして用いることも可能な汎用的な測定ユニットとして使える。

この記事を含め3種類のシリアル接続タイプの測定ユニットの設計を公開している。

機能 記事名
シリアル出力 シリアル接続温度計 (PIC 12F675)
シリアル出力,パラレル接続LCD 最低・最高温度記憶機能つきLCD表示温度計 (PIC 16F690) この記事
シリアル出力,I2C接続LCD,EEPROM記録 ログデータ保存機能つきLCD表示温度計 (PIC 12F1822)

目次

主な機能

  • 温度測定範囲 0℃ ~ 50℃ (有効桁:小数点以下1桁)
  • LCD表示(現在温度、A/D変換生データ、最低温度、最高温度)
  • シリアル接続(RS232C接続)によるPCへのデータ転送
  • 最高温度・最低温度のリセット機能

回路図・部品表

pic16f690-thermometer-circuit.png

BSch3V用回路図ファイルをダウンロードする

名称 型番・仕様 個数・価格
PICマイコン 16F690 1個(290円)
温度センサーIC LM35DZ 1個(250円)
汎用オペアンプ LM358 1個(60円)
半固定抵抗 203 (20kΩ) 1個
炭素皮膜抵抗 27kΩ 1個
炭素皮膜抵抗 3kΩ 1個
炭素皮膜抵抗 10kΩ 2個
炭素皮膜抵抗 1kΩ 1個
プッシュスイッチ PUSHでON 1個


PIC 16F690のI/Oピン接続対応表
PIC側 I/Oピン番号と名称 接続先 I/O方向
17:RA2/AN2 温度センサー I
04:RA3 プッシュスイッチ(最低・最高温度初期化) I
03:RA4 LED(状態表示用) O
12:RB5/RX RX(シリアル受信) I
10:RB7/TX TX(シリアル送信) O
16:RC0 LCD DB4 O
15:RC1 LCD DB5 O
14:RC2 LCD DB6 O
07:RC3 LCD DB7 O
06:RC4 LCD RS O
05:RC5 LCD R/W O
08:RC6 LCD E O

完成写真

pic16f690-thermometer-photo.jpg


ソースコード

XC8 C言語ソースコード、ビルド済みHEXファイル、回路図のダウンロード

リポジトリ内の16f690-serial-lcdディレクトリ内に収められている。

動作確認済み開発環境
  • Microchip MPLAB X IDE ver 1.30
  • Microchip MPLAB XC8 ver 1.01
メイン関数部分の抜粋
Thermometer-main.c
#include <stdio.h>
#include <stdlib.h>
 
#include<xc.h>
#include"Lib-rs232c.h"
#include"Lib-lcd.h"
 
/* PIC Configuration */
__CONFIG(CP_OFF &        // Program memory code protection is disabled
        CPD_OFF &        // Data memory code protection is disabled
        BOREN_OFF &      // BOR(Brown-out Reset) disabled
        MCLRE_OFF &      // MCLR pin function is digital input
        WDTE_OFF &       // WDT(Watchdog Timer) disabled
        PWRTE_ON &       // PWRT(Power-up Timer) disabled
        FOSC_INTRCIO);   // INTOSCIO oscillator: I/O function on RA4 and RA5
 
#ifndef _XTAL_FREQ
    /* 例:4MHzの場合、4000000 をセットする */
    #define _XTAL_FREQ 4000000
#endif
 
/* printf関数の出力先のスタブ関数を定義する */
void putch(unsigned char ch){
    lcd_putch(ch);
    rs232c_putch(ch);
    return;
}
 
int main(int argc, char** argv) {
 
    // 基本機能の設定
    OSCCON = 0b01100000;    // 内部オシレーター 4MHz
    TRISA = 0b00001100;     // IOポートRA2(温度センサー),RA3(プッシュスイッチ)を入力モード
    TRISB = 0b00100000;     // IOポートRB4,RB6,RB7(TX)を出力モード、RB5(RX)を入力モード
    TRISC = 0;              // IOポートRC0...RC7を出力モード
    INTCONbits.PEIE = 0;    // 割り込み機能をOFF
    PORTA = 0;              // RA0...RA5をV-low
    PORTB = 0;              // RB4...RA7をV-low
    PORTC = 0;              // RC0...RC7をV-low
    CM1CON0 = 0;            // コンパレーター1 無効
    CM2CON0 = 0;            // コンパレーター2 無効
    ANSEL = 0b00000100;     // AN2 A/Dコンバータのみ有効
    ANSELH = 0;             // AN8...AN11 A/Dコンバータを無効
    ADCON1 = 0b00010000;    // ADコンバータ クロック Fosc/8
 
    // 0.5秒待つ
    __delay_ms(500);
 
    // LCD初期化
    lcd_init();
    lcd_goto(0);
    lcd_puts("Thermometer");
    lcd_goto(0x40);
    lcd_puts("PIC 16F690 and LM35");
 
    // RS232C初期化
    rs232c_init();
    rs232c_puts("\r\nThermometer start ...\r\n");
 
    // 1秒待つ
    __delay_ms(1000);
 
    // ■■ RS232C受信機能(割り込み)を使う場合に次の2行を有効化する
//    INTCONbits.PEIE = 1;    // 割り込み機能をON
//    INTCONbits.GIE = 1;     // 割り込み機能をON
 
    // 最低・最高温度の記憶
    unsigned long int value2_min = 500L;
    unsigned long int value2_max = 0L;
 
    for(;;)
    {
        PORTAbits.RA5 = 1;               // 動作中LEDを点灯
 
        int flag_ra3 = PORTAbits.RA3;    // プッシュボタンを検出
 
        ADCON0 = 0b10001001;             // 1-0-0010-0-1: 右詰め,AN2,AD有効化
        __delay_us(10);                  // A/D変換器チャージ時間待つ
        ADCON0bits.GO = 1;               // A/D変換開始
        while(ADCON0bits.GO_DONE){}      // A/D変換完了を待つ
        unsigned int value = ADRESH << 8 | ADRESL;
        // 10bit ADの最大値0x3ffが5.0V、さらにLM35の10倍増幅値では50℃になるように変換
        unsigned long int value2 = value * 500L / 0x3ffL;
        if(value2 > value2_max) value2_max = value2;
        if(value2 < value2_min) value2_min = value2;
        ADCON0bits.ADON = 0;             // A/Dを一旦無効化(節電)
 
        lcd_clear();
        printf("%02lu.%01lu deg-C (%04X)", value2/10, value2%10, value);
        rs232c_puts("\r\n");
        lcd_goto(0x40);
        printf("Min %02lu.%01lu Max %02lu.%01lu", value2_min/10, value2_min%10, value2_max/10, value2_max%10);
        rs232c_puts("\r\n");
 
        // AD変換前後で連続してプッシュボタン押し下げを検知した場合、最小・最大値をリセット
        if(flag_ra3 == 0 && PORTAbits.RA3 == 0)
        {
            value2_min = value2;
            value2_max = value2;
        }
 
        PORTAbits.RA5 = 0;                // 動作中LEDを消灯
 
        // 5秒待つ
        for(int i=0; i<5; i++)
            __delay_ms(1000);
    }
 
}

温度センサーLM35

ic-lm35.jpg
LM35

オペアンプで10倍増幅した値をA/D変換して読み取っている。

テキサスインスツルメンツLM35仕様書(LM35 Datasheet)のTypical Applicationsに説明されているように、

lm35-typical-app.png

Vout(V) = Temperature(℃) * 0.01(V)
但し、+2℃ <= Temperature <= +150℃、誤差0.5℃ @25℃

これをオペアンプで10倍してA/D変換器に入力すれば

A/D入力値(V) = Temperature(℃) * 0.1(V)

Voutが次のグラフの青い線、A/D入力値が赤い線となる。

lm35-amp-curves.png


オペアンプLM358

ic-lm358.jpg
LM358

今回は単純な増幅回路を使っている。次のような回路の場合、10倍の増幅値を得られる。

詳しくはテキサスインスツルメンツのLM358仕様書(LM358 Datasheet)を参照のこと。

lm358-gain.png


関連記事

 

戻る一つ前のメニューに戻る