電子工作76 – LM61温度センサでプラスとマイナス温度を液晶に表示する
概要
今回は前回の電子工作75の続きとしてマイナス温度、例えば、冷蔵庫の冷凍室の温度を測定する方法を検討した。LM61というセンサは精度はあまりよくないが、安価でー30℃から+100℃位まで測れるので使ってみることにした。難しかったところはプログラムの作成で、とにかく、いろんな実験をしてプログラムを改造し、やっとほぼ納得できる温度表示が出来るようになった。
製作にあたって考えていたこと:
1) マイナス温度の測定、表示法の基本を学ぶ。
2) 簡易化のため出来るだけ前回の電子工作75の回路を利用する。
3) PICマイコンは前回と同じ16F819を使う。
材料:
温度センサLM61BIS: 測定範囲 ー30℃ to +100℃、 精度max +/-3 to 4℃、温度上昇率 10mV/℃、オフセット電圧 +600mV。温度T(℃)とセンサ出力Vo(mV)の間に下表のような関係がある。式で表すと; Vo(mV)=10xT(℃)+600、従ってセンサ出力Voが分かればその時の温度Tが計算できる。
温度(T) |
出力(Vo) |
+100℃ |
+1600mV |
+85℃ |
+1450mV |
+25℃ |
+850mV |
0℃ |
+600mV |
-25℃ |
+350mV |
-30℃ |
+300mV |
回路図
下に回路図を示す。 前の電子工作75のものとほぼ同じである。今回は温度センサLM61BISを1個を使用。基準電圧も分圧回路からつくった2.50Vを用いている。温度センサへの電源も16F819用の電源と同じVdd=5.0Vを用いている。温度センサLD61BISは-30℃から+100℃までと測定でき測定範囲は広いが、精度はあまり高くない。とにかくマイナス温度を測るのが主目的である。
実験中: 冷蔵庫の冷凍室の温度を測定しているところ。上に市販の温度計(数年以上前に秋葉原の秋月で購入、精度+/-0.5℃)と下の液晶上の温度とは2℃ほどの差が見られる。両者の精度から考えて実際の温度は大体この辺にあると思われる。室内にしばらく置いてあった温度計センサ部を冷凍室に入れると、室温から次第に温度が下がり0℃をスムーズに超えてマイナス温度を示しながら下がって行く。センサ部を半田ごてに当てて電源SWを入れると表示温度は次第に上がり、少なくとも105℃までは達することを確認した(破壊を恐れてこの温度で中止)。
(Photo 1)
結果&コメント
1)
マイナス温度を表示させることに成功した。+100℃前後(半田ごて)から-20℃(冷蔵庫の冷凍室)位までスムースに表示できた。
2) センサLM61BIS(4本で¥200)の精度はあまり良くないので市販の温度計と2℃程度の差が出ることが頻繁に観察された。
3) センサLM61BISは+600mVのオフセットを持たすことによって単一プラス電源でマイナス温度の測定を可能にしてある。
4) 基準電圧を下げると精度が上がる。ただし、計算式の係数をその都度変える必要がある。温度センサ出力の単位はmV、 それをPIC内蔵のADCで変換された値の単位はcount、それをしっかり頭に入れておく必要あり。
5) 2014.11.9 一部修正; 半田ごてでセンサを加熱して行くと68−70℃位から一気に94℃位にジャンプして上昇することが判明。一方、センサ出力は1.20Vあたりから1.50Vなどと連続的に上昇する。何が原因かと考え、思いついたのが Vin=(Vin*122)/50+600 の(Vin*122)の中の計算値がPicbasic Proで扱える最大値65535を超えたためではないかということ。例えば、Vin*122=65535 Vin=65535/122=537、つまりADCの変換値537に相当するセンサ出力Vxは Vx/(2500/1023)=537 Vx=537x(2500/1023)=1321mV 1321−600=721mV 721/10(mV/℃)=72℃. つまり、計算上は72℃以上でPicbasic Proで扱えない最大値65535を超えることになる。従って、観察された上記の温度上昇がジャンプする現象はこの最大値を超えたために起こったと思われる。そこで、Vin=(Vin*122)/50+600 を Vin=(Vin*61)/25+600 に代えた。 つまり、カッコ内の値が最大値を超えないように、122/50を同じ数値になる61/25に変えた。その結果、この温度上昇がジャンプする現象は消え、スムースに100℃付近まで上昇することが分かった。問題解決!
プログラム
今回は温度センサにLM61BISというプラスとマイナス温度を測定できるものを使う。センサからの出力Voと温度Tとの間にはVo(mV)=10xT(℃)+600 という関係がある。従ってセンサ出力Voが分かれば、温度Tがプログラムの中で計算できる。上に示した表にセンサがカバーする6つの温度に対応する出力が表示してある。プログラうの中でプラス域の温度はVin=(Vin*122)/50-600
Vin=(Vin*61)/25-600で計算し、得られた値を Lcdout "Temp=",Dec1 Vin DIG
2,Dec1 Vin DIG 1,".", DEC1 Vin DIG 0,"C" で抽出し表示する。すると20.4Cなどと表示される。一方、マイナス域の温度は Vin=600-(Vin*122)/50 (またはVin=600-(Vin*61)/25)で計算し、これを Lcdout
"Temp=","-", Dec1 Vin DIG 2,Dec1 Vin DIG 1,".",
DEC1 Vin DIG 0,"C"で抽出し表示する。この際マイナス符号”-“が入る。従って-20.4Cなどと表示される。両者の計算式に出てくる (Vin*61)/25や(Vin*122)/50の中のVinは10-bit
ADCから出てくる変換値(単位: count)である。61/25=122/50=244/100=2.44(mV/count)で、ほんとうはVinに2.44を直接掛けたいところだがPicbasic
Proでは小数点や、(Vin*122)内が65535以上の数値を扱えないので便宜的にこうなった。例えば、0℃ではVin=246 countsになり246x2.44(=246x(122/50))=600mV、したがってVin=600-(Vin*122)/50 Vin=600―600=0 (mV)。こうして抽出表示結果は0℃となる。 -20℃の場合だと、-20℃x10mV/℃+600mV=400mV、400mV/(2500mV/1023)=163
counts、つまりVin=163 counts、Vin=600―(163x122)/50=600―398=202、この値202の三桁をすべた抽出し、マイナス符号と小数点を付けて –20.2Cと液晶に表示する。またプログラムの中で使われているIf
Vin=<246 thenの中の246は0℃(600mV)に相当するcount値である。つまり、Vin=Samples/10の結果が246(センサ出力600mVや0℃に相当)に等しいか、小さいかによってプラス温度域かマイナス温度域かを判別して別々のルーチンで処理をさせプラスまたはマイナスの温度表示をさせる。
'****************************************************************
'Name of program: LCDtempLm61BIZ16F819A.bas - 2014.11.4 New 11.6 worked OK 11.7
'Using Picbasic Pro V2.50A and 16F819
'All pin connections to LCD display and 16F819 are the same as those shown in LCDtempLm61BIZ16F819.bas
'As Vref+, used is 2.50V which is made by a voltage divider using two 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
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, described in count value
If Vin=<246 then '0C - +600mV 600mV/(2500mV/1023)=246 counts
Goto NegativeTemp
Endif
Vin=(Vin*61)/25-600 'Key positive-temperatures calculation formula, 61/25=122/50=244/100=2.44(mV/count) modified on 2014.11.9
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
Goto Temp2loop
NegativeTemp: ‘negative-temperature: displaying routine
Vin=600-(Vin*122)/50 ‘Key negative-temperature calculation formula Vin=600-(Vin*61)/25 is OK too.
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
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
'**************************************************