電子工作 5 –アンプLM358を使って“電子工作4”の温度表示の精度を1桁上げる

 

概要

    前の電子工作4温度を液晶に表示する実験では、2桁の精度(例 32°C)を確保するのが限界でした。これを実用精度3桁まで(例32.4°C)にするため、温度センサの出力をオペアンプLM358で増幅し、また、プログラムにも若干の改良を加えて、安定した3桁表示が出来るようにした。

 


回路  

    下に示した図のように、温度センサLM35DZの出力端子に、新たにオペアンプLM358をつなぎ、そのオペアンプの出力端子を16F819のPin17 (PortA.0、前の電子工作4を参照)につないだ。このオペアンプLM358は、分圧器(Standard Voltage Generator)の作りだす1.000V(DMM表示値)を使って、正確に5倍の増幅をするように、VRfとVRsで調整した。したがって、LM35DZから500 mV(temp=50°Cに相当)の入力があると、オペアンプLM358は0.500x5=2.50Vの出力を16F819に供給することになる。また、1000mV(temp=100°Cに相当)の場合は、1.00x5=5.00Vの出力を16F819に供給することになる。オペアンプLM358の電源(電圧:6.50V)はLM317を使った可変電源から(この電圧以下だと、出力5.00Vが得られない)、また、16F819には、7805を用いた電源から、5.00Vを供給した。なお、この電圧5.00Vは、内臓のADコンバータ(10-bit)の基準電圧としても使われている。

 


プログラミング

今回の目標は、16文字2行の液晶上に、1行目“Volt=x.xxV”とセンサからの電圧出力をアンプで5倍に増幅した値を、そして、そのデータを用いて2行目には“Temp=xx.xC”と温度(摂氏)を3桁表示させることです。しかも、いずれの値も、最小の桁がスムーズに増減しなければいけません。下のプログラムを見てください。電子工作4のものを一部変更してあります。

Result=Vin*/12500   'Scale 1024 to 50000

Result=(Result+5)/10  'Round the result

読み込んだデータを、整数値しか扱えないPICBasic Proに理解できるようにするトリックで、この場合の12500はscaling  factor と呼ばれ、50000/1024*256を指し、(Result+5)/10は四捨五入のためのものです。

次の部分は、Volt=x.xxV、Temp=xx.xCと液晶に表示させるためのものです。

Lcdout $fe, 1  'Clear LCD

Lcdout $fe, 2, "Volt=",dec1 Result DIG 3,".",DEC1 Result DIG 2,DEC1 Result DIG 1,"V"

Lcdout $fe,$c0 'Jump to second line

Lcdout "Temp=",dec1 ResultT DIG 3,dec1 ResultT DIG 2,".",DEC1 ResultT DIG 1,"C"

 

プログラム

 

'ADLC819j.bas - 16F819  2004.8.16 completed

'This time the input was amplified by 5 times with

a home-made OpAmp LM358N so that 100°C equated to 5.00V

'(+Vref) and 3 decimal figures were used.

'Exp. to read a voltage value from PortA.0 which

'is connected to LM35DZ temp. sensor (10 mV/C), via the

'OpAmp LM358N, convert it to a voltage and a temperature and

'display both voltage (1-line) and temp. values

'on LCD(2-line display).

'Note: The points are the use of "Result=Vin*/12500 'Scale

'1024 to 50000", "dec1 Result DIG 3,".",DEC1 Result DIG 2,

'DEC1 Result DIG 1,"V" and Lcdout "Temp=", dec1 Result DIG 3,

'dec1 Result DIG 2,".",DEC1 Result DIG 1,"C"

'Here, Dec1 means to display the Result DIG 2 value in 1 digit

'number (DIG 2 - 3rd digit from LSB).

 

'Pin connections:

'LCD    PIC

'DB4     PortB.4

'DB5     PortB.5

'DB6     PortB.6

'DB7     PortB.7

'RS      PortB.1 (add 4.7K pullup resistor to 5 volts)

'E       PortB.0

'RW      Ground

'Vdd     5.00 volts (also used as +Vref)

'Vss     Ground

'Vo      Ground (or 20K potentiometer)

'DB0-3   No connect

'ADC input  PortA.0 (Pin 17)

 

'**New LCD connection setting** See p.88 in PBP Manual

DEFINE LCD_DREG PORTB  'Set LCD Data port

DEFINE LCD_DBIT 4      'Set starting Data bit

                       '(0 or 4) if 4-bit bus

DEFINE LCD_RSREG PORTB 'Set LCD Register Select port

DEFINE LCD_RSBIT 1     'Set LCD Register Select bit

DEFINE LCD_EREG PORTB  'Set LCD Enable port

DEFINE LCD_EBIT 0      'Set LCD Enable bit

DEFINE LCD_BITS 4      'Set LCD bus size (4 or 8 bits)

DEFINE LCD_LINES 2     'Set number of lines on LCD

DEFINE LCD_COMMANDUS 2000 'Set command delay time in us

DEFINE LCD_DATAUS 50   'Set data delay time in us

 

'**Setting for ADC of 16F819**

Define ADC_BITS 10      '10-bit ADC used

Define ADC_CLOCK 3     'Internal clock used

Define ADC_SAMPLEUS 50 'Sample timing

 

OSCCON=%01110100  '=100 (decimal) - Internal OSC setting

'bit7=0(unimplemented), bit6-5-4=111(internal OSC 8MHz),

'bit3=0(unimplemented), bit2=1(frequency stable?),

'bit1-0=00(unimplemented)

 

ADCON0=%10000101  '=5 (decimal) - ADC setting

'bit7-6=01(Fosc/32 atADSC2?),'bit5-4-3=000(channel 0 (RA0/AN0),

'bit2=1(Ad conversion in progress at ADOn=1),

'bit1=0(unimplemented), bit0=1(AD module is operating)

 

ADCON1=%10001110  '=142 (decimal) - ADC and pin setting

'bit7=1 (right justified), bit6=0 (disable), bit5-4=00

'(unimplemented), bit3-2-1-0=1110 (AN4-3-2-1-0=DDDDA,

'+Vref-AVdd(supply power), -Vref-AVss(GND))

 

TRISA=%00100001   'PortA.0-analog input, PortA.5-input,

                  'all others-output

TRISB=%00000000   'All PortBs are output

Samples var word 'Samples

Sample var byte  'Sample

Vin var Word     'Vin is variable

Result VAR WORD   'Result is variable

ResultT VAR WORD

Samples=0

 

ADCloop:

For Sample=1 to 10 'Take 10 samples (changed from 20)

ADCIN 0, Vin      'Read ADC ch-0 and save in Vin

                   '(range 0-1023)

Samples=Samples + Vin

Pause 200          'Wait for LCD to startup

                  'Seems to be appropriate.

Next sample

 

Vin=Samples/10     'Mean of 10 Vin values

Result=Vin*/12500   'Scale 1024 to 50000

Result=(Result+5)/10  'Round the result

ResultT=Result*2

Lcdout $fe, 1         'Clear LCD

Lcdout $fe, 2, "Volt=",dec1 Result DIG 3,".",DEC1 Result DIG 2,DEC1 Result DIG 1,"V"

lcdout $fe,$c0        'Jump to second line

Lcdout "Temp=",dec1 ResultT DIG 3,dec1 ResultT DIG 2,".",DEC1 ResultT DIG 1,"C"

 

Samples=0

 

goto ADCLoop

 

'Note: Aki Pic programmer configuration for 16F819:

'Basically same as those on 04.2.13.

'FOSC-INTRC__RA6=I/O, WDTE-Enable, PWRTE-Enable, MCLRE-RA5=I/O,

'BODEN-Enable, LVP-RB3=I/O, CPD-Disable, WRT-All-Enable,

'DEBUG-Disable, CCPMX-CCPI=RB2, CP-Disable

 

 

余談

        今回の改良(アンプの追加)で、液晶に表示される温度の小数点以下1桁目が、市販の液晶温度計並みの、大変安定した増減をするようになった (少なくとも常用温度で)。 Cooler/heater box の中に、この装置の温度センサと市販のデジタル温度計(NT-301)の針状検出部を入れ比較してみたところ、少なくとも実験した10 - 55°Cの区間では大変直線性が良く、±0.5°C程度の精度はあることが分かった。ただ、電源やオペアンプの追加が必要であった。温度の精度を1桁上げるのも結構大変であることが理解できた。

 

Menu Pageへ戻る    

Topへ戻る