ようこそNICのホームページへ(なが〜い試運転中 from 2001/5/12)  
HP パソコン 健康 落語 海外 思うまま 電子工作


サーミスタを用いた温度計のブレッドボードテスト
(LCD表示とシリアルポートからデータ取込)(2011/03/09)

Last update:2011/03/09    Build:2011/03/09

 3年近く前(2008/04/07)に購入したサーミスタを活用したいと思っていた。  外気温をはかりたいと思っている。まずはブレッドボードでのテストを行った。  うまくいったのでハードウェアは完成していないが忘れないために載っけることにした。  

 
ブレッドボードを用いた実験の全体です。配線が短いため、ボードが重なって 写真の見栄えが良くない状態です。
上にあるのは先日作ったLCD表示器SC1602Bを用いた電流計です。
写真左の半分隠れたボードがRS232Cにデータを渡すためのコンバーター(ADM3202使用)。
斜めになったブレッドボードが今回の実験対象です。PIC16F88を用いて電圧表示、温度表示、RS232C経由で PCにデータを取り込めるようにしています。
   
左側の写真が電圧(mV)と温度表示、そばに単体で購入した温度計。ほぼ同じです。 右側の画像は秀TERMを使ってシリアルポートから温度を取り込んだ状態です。
     

1.LCD表示器 SC1602BS−Bの購入

バックライトなしタイプの液晶文字表示装置を秋月電子で500円/個で購入
PIN配置とPIN番号は下表のとおり
 
 
PIN番号 名称 種類   説明
Vdd 電源 電源+5V
Vss 電源 電源グランド
V0 入力 コントラスト調整
RS 入力 レジスター選択
R/W 入力 リード/ライト
入力 イネーブル
DB0 入出力 データバス(ビット0)
DB1 入出力 データバス(ビット1)
DB2 入出力 データバス(ビット2)
10 DB3 入出力 データバス(ビット3)
11 DB4 入出力 データバス(ビット4)
12 DB5 入出力 データバス(ビット5)
13 DB6 入出力 データバス(ビット6)
14 DB7 入出力 データバス(ビット7)
 
   ページ上部に移動します

2.回路図は”電子工作etc”さんのページを参考に作成

回路図は ”電子工作etc”さんのページ を参考に作成しました。

回路図の作成には水魚堂さんの BSch3Vを を使わせて貰っています。


EXCELで描いた部品配置です

ブレッドボードを用いたテストではオペアンプによる2倍増幅は行いませんでした。

 ページ上部に移動します

3.電圧から温度への換算

サーミスター(103AT)のデーターシートを元に温度と抵抗値から回路Vo点の電圧と温度の関係を 近似式で表し、PICの中で計算しました。
PC本体に取り込むだけならば、温度換算はPC側で行っても良かったのですが、LCD表示をさせたいので、 気温を測ることを考慮してー20℃〜50℃あたりを中心に、エクセルで近似式を求めて 6次の多項式近似としました。

 1)データシートの温度と標準抵抗値から想定回路のVoの値を求める
 2)Voと温度をエクセルでグラフ化
 3)エクセルでこのグラフの近似式を求める

 6次近似式は以下の通りです。
 y:温度(℃)
 X:中間電圧(Vo)(ボルト)

y  0.2305*x6 +5.9753*x5 -39.125*x4 +101.59*x3 -134.65*x2 +131.89*x -51.375


 ページ上部に移動します

4.16F88用のプログラム

16F88用のプログラムは ”電子工作etc”さんのページ を参考に試行錯誤しました。特にmikroC(フリー版)で書いていますので2kワードに納める必要があります。 実数の多項式の計算はコンパイル後のプログラム量が多くなるようです。

mikroCのプログラムです
// **********************************************************************
/*
  サーミスターを持いた温度計測 LCD表示  RS232C経由でデータ取込可能 
     2011/02/10 ---> 2011/03/07 (完成) 
      基本はhttp://www8.plala.or.jp/InHisTime/page053.html 
      からコピーし修正を加えた
   私が自分に理解のためにコメントを追加    

     LCD  SC1602B を使用 
     PIC  16F88 使用 

     mikroCを使用
     file name 110227_16F88_LCD_2.c
     コンパイル後 プログラム 2,063Word RAM 64Word 


*/

/*  ********************* 私が追加
 2010/11/26 --------->2011/03/07
 16F88 PIN
  1:RA2/AN2/CVref/Vref-        AN2 アナログ入力2(サーミスタ電圧)で使用
  2:RA3/AN3/Vref+/C1OUT                今回 Vref+使用
  3:RA4/AN4/T0CKI/C2OUT        使用せず(入力設定)
  4:RA5/MCLR/Vpp                   使用せず(入力設定)
  5:Vss                              GND
  6:RB0/INT/CCP1(1)                使用せず(入力設定)
  7:RB1/SDI/SDA                    使用せず(入力設定)
  8:RB2/SDO/RX/DT                    RS232C RX (input)    (入力設定)
  9:RB3/PGM/CCP1(1)              デジタル出力 (LCD D5  pin 12)  
 10:RB4/SCK/SCL                  デジタル出力 (LCD D7  pin 14)
 11:RB5/SS/TX/CK                    RS232C TX (output) デジタル出力 
 12:RB6/AN5/PGC/T1OSO/T1CKI      デジタル出力 (LCD D6  pin 13)
 13:RB7/AN6/PGD/T1OSI            デジタル出力 (LCD D4  pin 11)
 14:Vdd                             +5V
 15:RA6/OSC2/CLKO                デジタル出力 (LCD E   pin  6)
 16:RA7/OSC1/CLKI                デジタル出力 (LCD R/W pin  5)
 17:RA0/AN0                      デジタル出力 (LCD RS  pin  4)
 18:RA1/AN1            使用せず(入力設定)
*/

// **********************************************************************

unsigned	int	measurement(unsigned short channel)
{
	unsigned	int		ad, cnt;
	//
	ad = 0;
	for (cnt = 0; cnt < 50; cnt++) {  // 50回の合計 
		ad += Adc_Read(channel);
	}
	return (ad);
}

// **********************************************************************

void main()
{
		unsigned	char	buf[8], cnt, data;
		unsigned	int	v1, v2, i1 ;
		double			ad, offset, temp ;
//        const double c[7] = {0.2305, 5.9753, -39.125, 101.59, -134.65, 131.89, -51.375};
	unsigned short i ;
	
	//
	OSCCON = 0b01110000;		// クロックは8Mhz
	CMCON  = 0b00000111;		// コンパレータは使用しない。
	// A/D変換を使用する。
	ANSEL  = 0b00000100;  // AN2をアナログで使用 「1」:アナログ 「0」:デジタル
	ADCON1.VCFG1 = 1;     // Vref+ を使用
	ADCON1.VCFG0 = 0;     // GND   を使用 (Vref- を使用しない)
        // ADCON1.ADFM = 1 ;  // A/D変換結果を右詰めにする 
	// ポートを初期化する。
	TRISA  = 0b00111110;  // ポートAデータ入出力の方向 0:出力、1:入力
	  /* RA7:出力 RA6;出力 RA5:入力のみ(使用せず) RA4:入力 (使用せず)
	     RA3:入力(Vref+)  RA2;入力 RA1:入力(使用せず)    RA0:出力
	  */
	TRISB  = 0b00000111;  // ポートBデータ入出力の方向 0:出力、1:入力
	  /* RB7;出力 RB6;出力 RB5;出力(Tx) RB4;出力
             RB3:出力 RB2:入力(Rx) RB1:入力(使用せず) RB0:入力(使用せず) 
	  */
	// LCDを初期化する。
	Lcd_Custom_Config(&PORTB,4,6,3,7,&PORTA,0,7,6); // (LCD用データport,D7,D6,D5,D4, LCD用制御port,RS,WR,EN)
	Lcd_Custom_Cmd(LCD_CURSOR_OFF);
	Lcd_Custom_Cmd(LCD_CLEAR);
//	Lcd_Custom_Out(1, 1, "V&I Meter V1.0");
//	Delay_ms(500);
//	Lcd_Custom_Cmd(LCD_CLEAR);
	//
	//
//      RS232C ポートを初期化
        Usart_Init(9600); //通信速度を9600 band rateに設定 16F88はハードウェアーで通信可能 

//
	while (1) {
		// サーミスタ電圧の測定
		ad = 0.0;
		for (cnt = 0; cnt < 10; cnt++) {
			ad += measurement(2);
		}
		ad = (ad / 500.0) * 2.44140625  ; // ブレッドボードのテスト用  オペアンプ無し 
//                ad = (ad / 1000.0) * 2.44140625  ; // mV 単位 
//                 500回計測の平均を取る 
//                 2500 mV / 1024 = 2.44140625  電圧に換算 
//                 オペアンプで2倍に増幅しているので戻す 500 と2を併せて1000.0で割る 

/*
                // 電圧の四捨五入 
                ad = ad * 10000.0 ;          //   0.1mV単位を四捨五入のため、10000倍する 
                                             //   例 ad=1.3678 V --> 13678
		v1 = (unsigned int)(ad);     //   例     13678
		v2 = (unsigned int)(v1 / 10.0);  // 例 1367
		if ((v1 - (v2 * 10)) >= 5)         // 次の行と併せて四捨五入 
			v2++;                      // 例  1368  --> 1368 mVのこと 
*/
		// サーミスタ電圧の表示 LCDに出力 
                v2 = ( unsigned int ) (ad ) ;  // 四捨五入するとプログラムが2kwに収まらないので切り捨て 
		WordToStr(v2, buf);      // 数値(符号なしの16ビット)を文字(5文字)に変換 (□1368) 
		Lcd_Custom_Out(1, 1, buf);   // 1行目の1コラムからbufを表示 
		Lcd_Custom_Out(1, 7, "mV");

                ad = ad / 1000.0 ;  // mVを Vに変換 


//      中間電圧(Vo)から温度に換算
//              電圧から温度への変換に近似式を用いる 
//
         temp = ( ( ( ( (0.2305*ad+5.9753 )*ad - 39.125 )*ad + 101.59 )*ad - 134.65 )*ad + 131.89 )*ad -51.375 ;
//
//      一行で書くよりメモリー使用量が減ると思ったが、増えてしまった。 2061−−>2085 
//                temp=c[0] ;
//                for ( i=1 ; i<7 ; i++) {
//                    temp = temp*ad + c[i] ;
//                }
//      中間電圧(Vo)から温度に換算終了



                // 温度の四捨五入 
                temp = temp * 100.0 ;            //  0.01℃単位を四捨五入のため、100倍する
                                                 //  例 temp=21.36 ℃ --> 2136
		v1 = (unsigned int)(temp);       //  例     2136
		v2 = (unsigned int)(v1 / 10.0 ); //  例 213
		if ((v1 - (v2 * 10)) >= 5)     //  次の行と併せて四捨五入 
			v2++;                    //  例  214  --> 21.4℃のこと 
		// サーミスタ温度の表示 LCDに出力 
		WordToStr(v2, buf);      // 数値(符号なしの16ビット)を文字(5文字)に変換 (□□214) 
		buf[6] = 0x00;           //                                     (□□214 □) 
		buf[5] = buf[4];         //最下の桁を右へ                       (□□2144□) 
		buf[4] = '.';            //動かした後に小数点を付与             (□□21。4□) 
		Lcd_Custom_Out(2, 1, buf);       // 2行目の1コラムからbufを表示 
		Lcd_Custom_Out(2, 7, "゚C");      // ℃を表示 

// RS232C Rxに'R'があれば、温度データをRS232Cに出力する 
                //

                if( Usart_Data_Ready()) {    // RS232C 準備OK? 
                    data =  Usart_Read();    // データの読み取り 
                    if(data == 'R') {        //dataが'R'なら温度(buf)を出力 
                        buf[6] = 0x0D ;  // CR
//                        buf[7] = 0x0A ;  // LF
                        for ( i=0 ; i<7 ; i++ ) {
                          Usart_Write( buf[i] ) ; //  Send 温度 via USART
                        }
//                    Usart_Write( 0x0D ) ; //  cr
//                    Usart_Write( 0x0A ) ; //  LF

                    } 
                }  
              //

	}
}

// **********************************************************************
 ページ上部に移動します

5.できあがりの写真です

まだ作っていない(2011/03/09現在)ので、前作の電流計の写真そのままです。
右の写真はLCD表示器を取り付けた状態です
左の写真の左上から右上へ外部電流が流れます。
電流計の電源は下中央の赤黒線から006P電池で供給。
  電流測定用の基準抵抗はオリジナルの0.1Ωから変更し1Ω(1%)抵抗を使用
 ページ上部に移動します

電子工作へ     HomePage