電子工作75 – 3つの温度センサから得られた温度を液晶に順次表示する試み

 

 

概要

   およそ10年前に電子工作4と5で温度センサLM35DZを使って液晶上に表示する実験を行った。今回は温度測定に関する“おさらい”をしたいという思いもあって、昔のデータをもとに差し当って3つの温度センサからの温度を小さな液晶上に1個ずつ繰り返し表示してみることにした。

 

製作にあたって考えていたこと

1)     過去の電子工作4や5のデータを利用する。

2)     温度関係のテーマを長くやっていないので先ず習熟に心がける。

3)     古くて割高だがPICマイコンは前と同じ16F819を使う。

4)     この実験の先にはマイナス温度の測定&表示という目的があるので、実験はブレッドボードを使って行う。

3) いつものようにPicBasic ProというBASICコンパイラを使ってプログラムを作成する。

 

材料

バックライト付き液晶デスプレイ(16x2 5V 1602A−V2)¥400、16F819 ¥210、 温度センサ LM35DZ x3 計¥300、その他の部品含め合計¥1500ほど

 

回路図

下に回路図を示す。 前の電子工作4をもとに作成した。温度センサの数を1個から3個に増やしてある。アナログ入力ポートが空いているのであと2個増やせる。回路図の作成ではPicBasic Proの日本語マニュアル(PicBasic Pro Compiler ver. 2.50  日本語説明書 microtechnica社作成 p.66−69)を参考にした。電源はLM317三端子レギュレータを使った可変電源を 5.0Vで使い、ADC(Analog Digital Converter)の基準電圧にも使った。電源も基準電圧も3VにしてADCの精度を上げたかったが、液晶が5Vを要求するので出来なかった。温度センサは006P型の9V電池で駆動した。温度センサLM35DZの測定温度範囲は0−100°C、 精度+/-1°C、 温度係数10.0mV/°C、 電源電圧4−20V、それに消費電流は60uAと低い優れた特性を持つ。 基準電圧が5Vなのであまり高い精度は望めなく、したがって今回は温度の小数点以下の表示はしないことにした。リセットSWは暴走した場合への対策である。

 

実験中: 上方の左端に可変電源があり、その右脇に3個の温度センサA、B、Cが見える。同じく上方右端には9Vのセンサ電源用電池がある。ボードの真ん中の黒いICが16F819。最下部の右端に見えるのが16文字2行表示可能な液晶である。 (Photo 1)

 

  温度表示例: 下の3枚の写真のように、液晶上に5秒毎に温度センサA, B, Cの温度が繰り返し表示される。今回はたまたま3本の温度センサを1ヶ所にまとめて置いたので皆同一温度を表示する結果になった。温度センサ間の精度のばらつきが小さいことを示しているとも言える。 (Photo 2)

 

 

 

結果&コメント

1)     3個の温度センサを読み込み液晶上に表示することが出来た。勿論、3個以上も可能。対応するプログラムの作成が大きい目的であった。

2)     液晶が5V駆動を要求すること、表示温度は小数点以下なしであることなどから、簡単なので16F819やADCの基準電圧にも5.0Vを使った。

3)     温度センサLM35DZは10.0mV/°C、 つまり1°C上昇する毎に10.0mVの電圧が発生する、例えば50°Cで10.0x50=0.50Vの電圧になる。ADCの基準電圧が5.0Vなので測定温度の精度は高くない。電子工作5ではアンプで5倍に増幅して精度を上げる試みをしている。今回は温度の精度は2の次であった。

4)     通常の温度計よりちょっと低めに(1−2C)温度が表示される。また冷蔵庫の5−6Cが2C位に表示された。センサからの電圧を測定すると48mV。センサ出力はADCで正しく変換されていない可能性がある。いろいろ検討してみたがまだ正しく、例えば、センサ出力250mVを25C表示に、変換できる方法が見つかっていない。要検討!!!

5)     温度センサの1個当たりの電流消費は60uA、3個でも60x3=180uAとかなり小さい。9V電池の容量が400mAh位なので400/0.18=2500h 2500/24=104days とかなり持つ。

6)     サブルーチンを導入すればプログラムは大分短くなるはず。

7)     2014.10.20 一部修正: (Vin=(Vin*/500)>>2  500を560に変えたが、根拠不確かでもとの500に戻した。従って文章の関連する一部も変えた。

8)     2014.10.21 サブルーチンを使って少し簡略化したプログラムを追加: 元のプログラムの下に示すADLC819h141003ABCsensNew.bas である。

9)     2014.10.29基準電圧2.50Vを使って精度を上げた改良版を作成。 新しい配線図(分圧回路追加)とプログラムADLC819h141003ABCsensNewTST.bas)を追加した。今回のものが最も正しい結果が出る

 

プログラム

このプログラムは電子工作4のプログラムをもとに作成した。温度センサが3個に増えたので、個々のセンサからのアナログ値(電圧)を16F819のADCに読み込んで液晶上に温度の表示をさせる部分が1個から3個に増えた。後日読んで分かる様に設定の部分の説明が詳細に記述してある。 液晶LCDと16F819のADCの設定は定番のようなもので必須、怠ると勿論動かない。OSCCONの設定では8MHzのInternal clockを選択した。ADCON1は16F819の複数ポートをアナログ値の入力に使うことや、電源電圧VddをADCの基準電圧に使用することなどを設定する。ADCON0は実際にどの温度センサからのアナログ値を読み込むかを設定するので、各温度測定ルーチンTemp at Point A、B or C routineの中に入れた。これで各温度センサからの値が液晶上に5秒ごとに繰り返し表示される。

'****************************************************************

'Name of program:  ADLC819h141003ABCsens.bas

‘(16F819 2014.10.3 2014.10.1 worked OK!, 2014.9.26 modified)                                    

'Using 16F819 and PicBasic Pro V2.50A

'2014/10/3

'This time no digits below decimal point were used.

'Exp. to read a voltage value from PortA.0, 1 and 2 which

'are connected to three LM35DZ temp. sensors (10 mV/C),

'convert it to a temperature, displaying the individual temp. values

'on LCD (2x16 display) one by one.

'Note: The points are the use of "Vin=(Vin*/500)>>2"

'Lcdout "Temp=",Dec2 Vin," degree C"

'Here, Dec2 means to display the Vin value in a 2-digit number.

'********* Pin connections********

'--LCD--

'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 via 20K potentiometer)

'DB0-3   No connect

 

'--16F819--

'Pin 14 - Vdd (5.0V)

'Pin 5 – Vss (GND)

'Pin 4 (RA5) - Reset

'Pin 17 (RA0) - ADC input  PortA.0 - Sensor A

'Pin 18 (RA1) - ADC input  PortA.1 - Sensor B

'Pin 1 (RA2) - ADC input  PortA.2 - Sensor C

 

'**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**  ADCの設定

Define ADC_BITS 10     '10-bit ADC used

Define ADC_CLOCK 3     'Internal clock used

Define ADC_SAMPLEUS 50 'Sample timing

 

OSCCON=%01110100  '=116 (decimal) - Internal OSC setting to 8MHz 内部クロックを8MHzに設定

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

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

'bit1-0=00(unimplemented)

 

'---Detail of three ADCON0 settings---

'ADCON0=%10000101  'for ADC setting of Sensor A (AN0), included in Program. アナログ入力ポートをAN0に設定、その詳細 (下で温度表示ルーチン中に入る)

'bit7-6=10(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)

 

'ADCON0=%10001101  'for ADC setting of Sensor B (AN1), included in Program アナログ入力ポートをAN1に設定、その詳細 (下で温度表示ルーチン中に入る)

'bit5-4-3=001(channel 1 (RA1/AN1))

 

'ADCON0=%10010101  'for ADC setting of Sensor C (AN2), included in Program アナログ入力ポートをAN2に設定、その詳細 (下で温度表示ルーチン中に入る)

'bit5-4-3=001(channel 2 (RA2/AN2))

 

ADCON1=%10000000  'ADC pin selection setting アナログ入力ポートと基準電圧の選択設定

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

'(unimplemented), bit3-2-1-0=0000 (AN4-3-2-1-0=AAAAA all 5 pins analog inputs)

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

 

TRISA=%00100111   'PortA.0 and 1 - 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

T var Byte       'T (=Time)

 

Temp2loop:

'---Temp at Point A routine--- Point Aを表示させるルーチン(約5秒間費やす)

Sample=0

Samples=0

T=0

For T=1 to 5

ADCON0=%10000101  'for ADC setting of Sensor A (AN0)

For Sample=1 to 10 'Take 10 samples                   精度を期すためアナログ入力値10個の平均をとっている

ADCIN 0, Vin   'Read ADC ch-0 and save in Vin, Range 0-1023  ch−1(AN0)ポートからアナログ値を読んでAD変換しVinに保存する

Samples=Samples + Vin

Pause 200      'Wait for LCD to startup, Seems to be appropriate.

Next sample

Vin=Samples/10 'Mean of 10 Vin values

Vin=(Vin*/500)>>2  ‘この公式は広く使われている。

Lcdout $fe, 1  'Clear LCD

Lcdout $fe, 2, "Point A"

LCDOUT $FE,$C0 'Jump to second line

Lcdout "Temp=",Dec2 Vin," degree C"  'Temp=を表示し、そのあとにVinを10進法で2桁表示し、1コマ空けてdegree Cを表示せよ

Samples=0

Next T

 

'---Temp at Point B routine---  Point Bを表示させるルーチン

Vin=0

T=0

Sample=0

Samples=0

For T=1 to 5

ADCON0=%10001101  'for ADC setting of Sensor B (AN1)

For Sample=1 to 10 'Take 10 samples

ADCIN 1, Vin   'Read ADC ch-1 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

Vin=(Vin*/500)>>2

Lcdout $fe, 1  'Clear LCD

Lcdout $fe, 2, "Point B"

LCDOUT $FE,$C0 'Jump to second line

Lcdout "Temp=",Dec2 Vin," degree C"

Samples=0

Next T

 

'---Temp at Point C routine--- Point Cを表示させるルーチン

Vin=0

T=0

Sample=0

Samples=0

For T=1 to 5

ADCON0=%10010101  'for ADC setting of Sensor C (AN2)

For Sample=1 to 10 'Take 10 samples

ADCIN 2, Vin   'Read ADC ch-2 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

Vin=(Vin*/500)>>2

Lcdout $fe, 1  'Clear LCD

Lcdout $fe, 2, "Point C"

LCDOUT $FE,$C0 'Jump to second line

Lcdout "Temp=",Dec2 Vin," degree C"

Samples=0

Next T

Goto Temp2loop  '元に戻って温度表示ルーチンを繰返す

 

'Note: melabs U2 Programmer's configuration for 16F819 (2014.10.1)

'FOSC-INTRC(INTIO2), WDTE-Enable, PWRTE-Enable, MCLRE-Reset,

'BODEN-Enable, LVP-Disable, CCP Multi With-RB2,

'Flash Pogram Meory Write Enable-All,

'Code-Not Protected, Data EEPROM-Not Protected

'********************************************************

 

サブルーチンを使って上記のものを少し簡略化したプログラム  - Slightly simplified program using a subroutine -

'Name of program: ADLC819h141003ABCsensNew.bas - 2014.10.21 simplified using subroutine  works OK

'All pin connections to LCD display and 16F819 are the same as those shown in ADLC819h141003ABCsens.bas

 

'**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  'Internal OSC setting to 8MHz

ADCON1=%10000000  ‘Right justified

 

TRISA=%00100111   'PortA.0, 1, 2 and 5 - analog input, others-output

TRISB=%00000000   'All PortBs are output

Samples var word 'Samples

Sample var byte  'Sample

Vin var Word     'Vin is variable

Ch var byte      'Ch is channel

 

Temp2loop:

'---Temp at Point A routine---

Vin=0

Sample=0

Samples=0

ADCON0=%10000101  'for ADC setting of Sensor A (AN0)

Ch=0

Gosub SmplCollect

Lcdout $fe, 1  'Clear LCD

Lcdout $fe, 2, "Point A"

Lcdout $fe,$C0 'Jump to second line

Lcdout "Temp=",Dec2 Vin," degree C"

Pause 3000

 

'---Temp at Point B routine---

Vin=0

Sample=0

Samples=0

ADCON0=%10001101  '(AN1)

Ch=1

Gosub SmplCollect

Lcdout $fe, 1  'Clear LCD

Lcdout $fe, 2, "Point B"

Lcdout $fe,$C0

Lcdout "Temp=",Dec2 Vin," degree C"

Pause 3000

 

'---Temp at Point C routine---

Vin=0

Sample=0

Samples=0

ADCON0=%10010101  '(AN2)

Ch=2

gosub SmplCollect

Lcdout $fe, 1  'Clear LCD

Lcdout $fe, 2, "Point C"

Lcdout $fe,$C0

Lcdout "Temp=",Dec2 Vin," degree C"

Pause 3000

Goto Temp2loop

 

SmplCollect:

For Sample=1 to 10 'Take 10 samples

ADCIN Ch, Vin   'Read ADC Ch 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

Vin=(Vin*/500)>>2

Return

 

'Note: melabs U2 Programmer's configuration for 16F819 (2014.10.1)

'FOSC-INTRC(INTIO2), WDTE-Enable, PWRTE-Enable, MCLRE-Reset,

'BODEN-Enable, LVP-Disable, CCP Multi With-RB2,

'Flash Pogram Meory Write Enable-All,

'Code-Not Protected, Data EEPROM-Not Protected

'**************************************************

 

基準電圧Vref+=2.50Vを導入し精度を上げた回路とプログラム(2014.10.29)  -  -

  最初の回路図に10K抵抗2本を使った2.50Vをつくる分圧回路を加え、従ってプログラムも一部変えた。下の図で上方左部分に分圧回路が見える。これで作られた2.50Vは16F819のRA3(AN3)に供給され、基準電圧となる。他に変えた箇所はない。測定結果: 冷蔵庫の温度2−3℃から、半田ゴテに当てての102―9℃まで測定してみた。他の市販の温度計、例えば、NT-301と比べて1−2℃の差で温度変化はほぼ一致した。  (Fig. 1)

 

今回の温度表示は小数点1桁とした。Point A, B、Cの温度表示が交互に出る。+/-0.5℃から1℃位の精度のようだ。  (Photo 3)

 

プログラム

サブルーチンSmplCollectの中のVin=(Vin*122)/50の導入と、液晶への表示Lcdout "Temp=",Dec1 Vin DIG 2, Dec1 Vin DIG 1,".", DEC1 Vin DIG 0,"C"が最重要部分である。

1)    Vin=(Vin*122)/50の解説: 2.50V/1023=0.002444=2.44mV/count, 例えば、50℃だと センサ出力は50x10mV/℃=500mV=0.500V,  0..500V/0.00244=204.9 =205 counts, Vin=205x244=50020 (244=2.44x100), この値50020は50℃に相当し、プログラムで数字の50.0を抽出する。また、100℃では1.00V/0.00244=410,  Vin=410x244=100,040 この値はPicBasicでは扱えない(65、535が扱える最大値)。そこで244を半分の122にし結果を50で割ると元と同じになる(2.44mV=244/100=122/50)。Vin=410x122/50=100040/50=1000.4 この値が100℃に相当(上から3桁をプログラムで抽出)。

2)    Lcdout "Temp=",Dec1 Vin DIG 2, Dec1 Vin DIG 1,".", DEC1 Vin DIG 0,"C"の解説: Dec1 Vin DIG 2, Dec1 Vin DIG 1部分の意味はVin(整数値3桁)の1番頭の値(bit2)の整数値1桁を抽出し、次いで頭から2番目(bit1)の整数値1桁を抽出してその後にならべ、,".", DEC1 Vin DIG 0,"C"は小数点を加え、次いでVinの頭から3番目(bit0)の整数値1桁を抽出してならべ、最後にCを添付せよ、ということ。その結果、23.4Cなどと表示される。

 

'ADLC819h141003ABCsensNewTST.bas - 10.29  14.10.21 simplified using subroutne  works OK

'All pin connections to LCD display and 16F819 are the same as those shown in ADLC819h141003ABCsens.bas, except additon of a 2.50V-voltage divider circuit

'As Vref+, used is 2.50V which is made by a voltage divider using 2 10K Rs and connected to AN3 (RA3)

'**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  'Internal OSC setting to 8MHz

ADCON1=%10000001  'Right adjusted, AN3 - Vref+

 

TRISA=%00101111    'RA3 - Vref+, PortA.0, 1, 2, 3 and 5 - analog input

TRISB=%00000000   'All PortBs are output

Samples var word 'Samples

Sample var byte  'Sample

Vin var Word     'Vin is variable

Ch var byte      'Ch is channel

 

Temp2loop:

'---Temp at Point A routine---

Vin=0

Sample=0

Samples=0

ADCON0=%10000101  'for ADC setting of Sensor A (AN0)

Ch=0

Gosub SmplCollect

Lcdout $fe, 1  'Clear LCD

Lcdout $fe, 2, "Point A"

LCDOUT $FE,$C0 'Jump to second line

Lcdout "Temp=",Dec1 Vin DIG 2,Dec1 Vin DIG 1,".", DEC1 Vin DIG 0,"C"

Pause 3000

 

'---Temp at Point B routine---

Vin=0

Sample=0

Samples=0

ADCON0=%10001101  '(AN1)

Ch=1

Gosub SmplCollect

Lcdout $fe, 1  'Clear LCD

Lcdout $fe, 2, "Point B"

LCDOUT $FE,$C0 'Jump to second line

Lcdout "Temp=",Dec1 Vin DIG 2,Dec1 Vin DIG 1,".", DEC1 Vin DIG 0,"C"

Pause 3000

 

'---Temp at Point C routine---

Vin=0

Sample=0

Samples=0

ADCON0=%10010101  '(AN2)

Ch=2

Gosub SmplCollect

Lcdout $fe, 1  'Clear LCD

Lcdout $fe, 2, "Point C"

LCDOUT $FE,$C0 'Jump to second line

Lcdout "Temp=",Dec1 Vin DIG 2,Dec1 Vin DIG 1,".", DEC1 Vin DIG 0,"C" 

Pause 3000

Goto Temp2loop

 

SmplCollect:

For Sample=1 to 10 'Take 10 samples

ADCIN Ch, 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

Vin=(Vin*122)/50  'Key formula

Return

 

'Note: melabs U2 Programmer's configuration for 16F819 (2014.10.1)

'FOSC-INTRC(INTIO2), WDTE-Enable, PWRTE-Enable, MCLRE-Reset,

'BODEN-Enable, LVP-Disable, CCP Multi With-RB2,

'Flash Pogram Meory Write Enable-All,

'Code-Not Protected, Data EEPROM-Not Protected

'**************************************************

 

 

Temperature Displaying on LCD using 3 LM35DZ sensors (English version of the above Electronics Project 75 in Japanese)

  This project is based on Electronics Project 4 that was completed about 10 years ago and described only in Japanese. One temperature sensor was used in that project but three sensors are used in this project. I wanted to review how to read a voltage from a temperature sensor and display its temperature value on LCD (Liquid Crystal Display). By using those three sensors, three temperatures are displayed on LCD one by one, for which it was required to modify the old program. My final goal is to make a program capable of displaying negative temperatures on LCD in some future projects. The circuit diagram is shown below. The wiring between 16F819 (or 16F84) and LCD was carried out referring to PicBasic Pro Manual. This wiring connection is considered simplest because only 4 wiring connections, instead of 8, are required for data transfer. The power supply to 16F819 and LCD is 5.0V from a variable voltage supply using LM317 and the same 5.0V is also used as the reference voltage for ADC (Analog Digital Converter) of 16F819. If a lower voltage than 5.0V is used as the reference voltage, higher temperature accuracy can be attained. However, since the LCD requires 5V and the main purpose of this project is to make a program capable of displaying three temperatures on LCD one by one, I decided to use 5.0V. The specification of temperature sensor LM35DZ; measurement range 0 – 100C, accuracy +/-1C, temperature coefficient 10.0mV/C, power supply 4 – 20V, power consumption 60uA. A 006P type 9V battery (400mAh) drives LM35DZ sensors. It may last about 3 months.

 

Explanation of Photo 1and 2 shown above in the section written in Japanese

Photo 1: All necessary parts are assembled on a breadboard and experiments are carried out. You can see variable voltage supply unit on the upper left corner, three temperature sensors next to it, 9V battery on the upper right side, 16F819 in the center of the board, and backlit LCD on the lower right corner.

Photo 2: A current temperature appears one by one continuously under `Temp at Point A`, `Temp at Point B` and `Temp at Point C`. In this case, because three sensors were bundled together and kept for a while at the same place, the LCD is thought to be showing the same temperatures.

 

Comments and conclusions

1)       The system works smoothly, displaying three temperatures on LCD one by one (one at a time) at an interval of about 5 seconds.

2)       Since two more analog ports are available in 16F819, the system can be modified to read and display the data from a total of 5 temperature sensors with a slight change of the program.

3)       Temperature sensor LM35DZ can generate 10.0 mV per degree C, so that at 50 degree C, for example, the voltage to be generated is 10 x 50 = 500 mV=0.50 V, which is not large when compared with the ADC reference voltage of 5.0 V (vs. 10-bit ADC - 1024). Accordingly, the accuracy of displayed temperature data is not so high.

4)       The level of displayed temperatures were compared with those of other thermometers and found to be slightly lower than their values.

5)       Newly added on 2014.10.21 See slightly simplified program using a subroutine (ADLC819h141003ABCsensNew.bas) in the above Japanese section.

6)       Newly added  on 2014.10.30. See the above Fig. 1 in which a voltage divider is added to generate 2.50V for reference voltage and the slightly modified program 'ADLC819h141003ABCsensNewTST.bas in which a new calculation formula Vin=(Vin*122)/50 is introduced. The above Photo 3 shows an example of 3-digit temperature display.

 

 

Program

  As three temperature sensors are used, the program includes the similar temperature read-and-display routines. For later reference, many setting parameters were described in detail.

  Here, OSCCON was set for 16F819 to be able to run on 8 MHz internal clock.

'****************************************************************

'Name of program:  ADLC819h141003ABCsens.bas

'Using 16F819 and PicBasic Pro V2.50A

'2014/10/3

'This time no digits below decimal point were used.

'Exp. to read a voltage value from PortA.0, 1 and 2 which are connected to three LM35DZ temp. sensors (10 mV/C), convert it to a temperature, displaying the individual temp. values on LCD (2x16 display) one by one.

'Note: The points are the use of "Vin=(Vin*/500)>>2" and Lcdout "Temp=",Dec2 Vin," degree C". Here, Dec2 means to display the Vin value in a 2-digit number.

 

'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 via 20K potentiometer)

'DB0-3   No connect

 

'--16F819--

'Pin 14 - Vdd (5.0V)

'Pin 5 - Vss

'Pin 4 (RA5) - Reset

'Pin 17 (RA0) - ADC input  PortA.0 - Sensor A

'Pin 18 (RA1) - ADC input  PortA.1 - Sensor B

'Pin 1 (RA2) - ADC input  PortA.2 - Sensor C

 

'**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  '=116 (decimal) - Internal OSC setting to 8MHz

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

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

'bit1-0=00(unimplemented)

 

'---Detail of three ADCON0 settings---

'ADCON0=%10000101  'for ADC setting of Sensor A (AN0), included in Program.

'bit7-6=10(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)

 

'ADCON0=%10001101  'for ADC setting of Sensor B (AN1), included in Program

'bit5-4-3=001(channel 1 (RA1/AN1)

 

'ADCON0=%10010101  'for ADC setting of Sensor C (AN2), included in Program

'bit5-4-3=001(channel 2 (RA2/AN2)

 

ADCON1=%10000000  'ADC pin selection setting

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

'(unimplemented), bit3-2-1-0=0000 (AN4-3-2-1-0=AAAAA all 5 pins analog inputs)

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

 

TRISA=%00100111   'PortA.0 and 1 - 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

T var Byte       'T (=Time)

 

Temp2loop:

'---Temp at Point A routine---

Sample=0

Samples=0

T=0

For T=1 to 5

ADCON0=%10000101  'for ADC setting of Sensor A (AN0)

For Sample=1 to 10 'Take 10 samples

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

Vin=(Vin*/500)>>2

Lcdout $fe, 1  'Clear LCD

Lcdout $fe, 2, "Point A"

LCDOUT $FE,$C0 'Jump to second line

Lcdout "Temp=",Dec2 Vin," degree C"

Samples=0

Next T

 

'---Temp at Point B routine---

Vin=0

T=0

Sample=0

Samples=0

For T=1 to 5

ADCON0=%10001101  'for ADC setting of Sensor B (AN1)

For Sample=1 to 10 'Take 10 samples

ADCIN 1, Vin   'Read ADC ch-1 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

Vin=(Vin*/500)>>2

Lcdout $fe, 1  'Clear LCD

Lcdout $fe, 2, "Point B"

LCDOUT $FE,$C0 'Jump to second line

Lcdout "Temp=",Dec2 Vin," degree C"

Samples=0

Next T

 

'---Temp at Point C routine---

Vin=0

T=0

Sample=0

Samples=0

For T=1 to 5

ADCON0=%10010101  'for ADC setting of Sensor C (AN2)

For Sample=1 to 10 'Take 10 samples

ADCIN 2, Vin   'Read ADC ch-2 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

Vin=(Vin*/500)>>2

Lcdout $fe, 1  'Clear LCD

Lcdout $fe, 2, "Point C"

LCDOUT $FE,$C0 'Jump to second line

Lcdout "Temp=",Dec2 Vin," degree C"

Samples=0

Next T

Goto Temp2loop

 

'Note: melabs U2 Programmer's configuration for 16F819 (2014.10.1)

'FOSC-INTRC(INTIO2), WDTE-Enable, PWRTE-Enable, MCLRE-Reset,

'BODEN-Enable, LVP-Disable, CCP Multi With-RB2,

'Flash Pogram Meory Write Enable-All,

'Code-Not Protected, Data EEPROM-Not Protected

 

 

Menu Pageへ戻る

Topへ戻る