ATtiny26LのA⁄D変換入力端子に温度測定用IC・LM35DZをつないで、簡単な温度計のプログラムを作ってみました。
テスト用回路は下記の通りです。LM35DZの出力端子をマイコンICのADC9(PB6, 9番ピン)につなぎました。測定した温度を表示するためにLCD・液晶ディスプレイも接続します。LM35DZは2SC1815などのトランジスタと同じ形をした3本足のICです。出力電圧は1℃あたり10mVです。つまり0℃のとき0V、10℃のとき100mV、20℃のとき200mVと、たいへんわかりやすくなっています。
まずは普通に温度を表示するプログラムです。簡単にするために端数を切り捨てて1℃単位で表示します。LM35DZの出力電圧は1℃あたり10mVなので、A⁄D変換値を2.048で割れば温度になります。「℃」の左上の丸は、LCDの文字コード表にそれらしい記号(&Hdf)があったので使いました。
プログラムファイル adc3a.bas
1 | $regfile = "at26def.dat" | ATtiny26Lを使用する。 | ||
2 | $crystal = 1000000 | クロック周波数を1MHzに設定。 | ||
3 | ||||
4 | Config Lcdpin=Pin, Db4=Porta.4, Db5=Porta.5 | LCDのピン接続の設定。DB4=PA4, DB5=PA5。 | ||
5 | Config Lcdpin=Pin, Db6=Porta.6, Db7=Porta.7 | LCDのピン接続の設定。DB6=PA6, DB7=PA7。 | ||
6 | Config Lcdpin=Pin, E=Porta.3, Rs=Porta.2 | LCDのピン接続の設定。E=PA3, RST=PA2。 | ||
7 | Config Lcd = 16 * 2 | 16文字×2行表示のLCDを使用する。 | ||
8 | Config Adc = Single , Prescaler = Auto | A⁄D変換の設定。「単独変換・分周比自動」。 | ||
9 | ||||
10 | Dim A As Word | ワード型変数「A」を使用する。 | ||
11 | Dim T As Byte | バイト型変数「T」を使用する。 | ||
12 | Cursor Off | カーソルを表示しない。 | ||
13 | ||||
14 | Do | Doループの範囲ここから。 | ||
15 | Start Adc | A⁄D変換を開始する。 | ||
16 | A = Getadc(9) | 「ADC9」の入力をA⁄D変換して「A」に代入。 | ||
17 | T = A / 2.048 | 「A÷2.048」の答えを変数「T」に代入。 | ||
18 | Cls | LCDの表示を消去する。 | ||
19 | Lcd "Temp=" ; T | LCDに「Temp=」と変数「T」の値を表示。 | ||
20 | Lcd Chr(&Hdf) ; "C" | LCDに「℃」を表示。 | ||
21 | Wait 1 | 1秒間そのまま。 | ||
22 | Loop | Doループの範囲ここまで。14行目へ戻る。 | ||
23 | ||||
24 | End | 終わり。 |
ATtiny26LのA⁄D変換は5mV程度の精度があるので、温度を0.5℃刻みで表示してみました。A⁄D変換値を2.048で割った答えの整数部分と小数部分を取り出します。小数部分の数値の大きさによって3通りの表示に分類します。
プログラムファイル adc3b.bas
1 | $regfile = "at26def.dat" | ATtiny26Lを使用する。 | ||
2 | $crystal = 1000000 | クロック周波数を1MHzに設定。 | ||
3 | ||||
4 | Config Lcdpin=Pin, Db4=Porta.4, Db5=Porta.5 | LCDのピン接続の設定。DB4=PA4, DB5=PA5。 | ||
5 | Config Lcdpin=Pin, Db6=Porta.6, Db7=Porta.7 | LCDのピン接続の設定。DB6=PA6, DB7=PA7。 | ||
6 | Config Lcdpin=Pin, E=Porta.3, Rs=Porta.2 | LCDのピン接続の設定。E=PA3, RST=PA2。 | ||
7 | Config Lcd = 16 * 2 | 16文字×2行表示のLCDを使用する。 | ||
8 | Config Adc = Single , Prescaler = Auto | A⁄D変換の設定。「単独変換・分周比自動」。 | ||
9 | ||||
10 | Dim A As Word | ワード型変数「A」(A⁄D変換値)。 | ||
11 | Dim T0 As Simgle | シングル型変数「T0」(元の温度値)。 | ||
12 | Dim Ti As Byte | バイト型変数「Ti」(「T0」の整数部分)。 | ||
13 | Dim Tf As Single | シングル型変数「Tf」(「T0」の小数部分)。 | ||
14 | Cursor Off | カーソルを表示しない。 | ||
15 | ||||
16 | Do | Doループの範囲ここから。 | ||
17 | Start Adc | A⁄D変換を開始する。 | ||
18 | A = Getadc(9) | 「ADC9」の入力をA⁄D変換して「A」に代入。 | ||
19 | T0 = A / 2.048 | 「A÷2.048」の答えを変数「T0」に代入。 | ||
20 | Ti = Int(t0) | 「T0」の整数部分を変数「Ti」とする。 | ||
21 | Tf = Frac(t0) | 「T0」の小数部分を変数「Tf」とする。 | ||
22 | Cls | LCDの表示を消去する。 | ||
23 | Lcd "Temp=" | LCDに「Temp=」と表示。 | ||
24 | ||||
25 | If Tf < 0.25 Then | 条件分岐1。「Tf<0.25」ならば、 | ||
26 | Lcd Ti ; ".0" | LCDに「Ti」の値と「.0」を表示。 | ||
27 | End If | 条件分岐1ここまで。 | ||
28 | If 0.25 <= Tf And Tf < 0.75 Then | 条件分岐2。「0.25≤Tf、かつTf<0.75」ならば、 | ||
29 | Lcd Ti ; ".5" | LCDに「Ti」の値と「.5」を表示。 | ||
30 | End If | 条件分岐2ここまで。 | ||
31 | If 0.75 <= Tf Then | 条件分岐3。「0.75≤Tf」ならば、 | ||
32 | Ti = Ti + 1 | 「Ti」に「1」を加える。 | ||
33 | Lcd Ti ; ".0" | LCDに「Ti」の値と「.0」を表示。 | ||
34 | End If | 条件分岐3ここまで。 | ||
35 | ||||
36 | Lcd Chr(&Hdf) ; "C" | LCDに「℃」を表示。 | ||
37 | Wait 1 | 1秒間そのまま。 | ||
38 | Loop | Doループの範囲ここまで。16行目へ戻る。 | ||
39 | ||||
40 | End | 終わり。 |
25行目から34行目にかけて、条件分岐プログラムが3種類あります。これは元の温度値「T0」の小数部分「Tf」の大きさによって表示の仕方を変えるプログラムです。28行目「If 0.25 <= Tf And Tf < 0.75 Then」は、「0.25 <= Tf」と「Tf < 0.75」という2つの条件の両方に当てはまれば、という意味です。つまり「0.25 ≤ Tf < 0.75ならば」という意味になります。ここを「If 0.25 <= Tf < 0.75 Then」と書いたらエラーになりました。
条件がややこしいので具体的な数字を例にとって説明します。まず、条件は下記の3つです。
ADC値(変数「A」の値)が41, 42, 43のとき、他の変数の値と最終的な温度表示は下記の表のようになります。
ADC値 | 変数T0 | 変数Ti | 変数Tf | 条件判断 | 温度表示 |
41 | 20.019 | 20 | 0.019 | 条件1に合う | 20.0℃ |
42 | 20.507 | 20 | 0.507 | 条件2に合う | 20.5℃ |
43 | 20.996 | 20 | 0.996 | 条件3に合う | 21.0℃ |
ADC値が41のとき、「T0」は41÷2.048=20.019です。整数部分「Ti」は20、小数部分「Tf」は0.019です。これは条件1「Tf < 0.25」に合致しますので、プログラム26行目「Lcd Ti ; ".0"」により、「Ti」(20)と「.0」が表示され、「20.0℃」となります。
ADC値が42の場合は小数部分が0.507になります。これは条件2「0.25 ≤ Tf < 0.75」に合っていますから、プログラム29行目「Lcd Ti ; ".5"」によって「Ti」(20)と「.5」が表示され、「20.5℃」となります。
ADC値が43のときは、整数部分が20、小数部分が0.996です。これは条件3「0.75≤Tf」に当てはまるので、まずプログラム32行目「Ti = Ti + 1」で「Ti」の値を21にして、次に33行目「Lcd Ti ; ".0"」により「21.0℃」と表示します。
温度をバーグラフで表示するプログラムを作ってみました。細かい表示をしようと思うとプログラムが複雑になりすぎるので、0℃から40℃の範囲で1℃あたり2⁄5桁分ずつバーが延びていく単純なパターンにしました。5℃刻みの目盛線もグラフがある部分だけにしか付けていません。それでもかなり面倒くさいプログラムです。きっと、もっと簡単なやり方があるはずです。
プログラムファイル adc3c.bas
1 | $regfile = "at26def.dat" | ATtiny26Lを使用する。 | ||
2 | $crystal = 1000000 | クロック周波数を1MHzに設定。 | ||
3 | ||||
4 | Config Lcdpin=Pin, Db4=Porta.4, Db5=Porta.5 | LCDのピン接続の設定。DB4=PA4, DB5=PA5。 | ||
5 | Config Lcdpin=Pin, Db6=Porta.6, Db7=Porta.7 | LCDのピン接続の設定。DB6=PA6, DB7=PA7。 | ||
6 | Config Lcdpin=Pin, E=Porta.3, Rs=Porta.2 | LCDのピン接続の設定。E=PA3, RST=PA2。 | ||
7 | Config Lcd = 16 * 2 | 16文字×2行表示のLCDを使用する。 | ||
8 | Config Adc = Single , Prescaler = Auto | A⁄D変換の設定。「単独変換・分周比自動」。 | ||
9 | ||||
10 | Declare Sub Bargraph1 | サブルーチン「Bargraph1」を使用する。 | ||
11 | Declare Sub Bargraph2 | サブルーチン「Bargraph2」を使用する。 | ||
12 | Dim A As Word | ワード型変数「A」を使用する。 | ||
13 | Dim T As Byte | バイト型変数「T」を使用する。 | ||
14 | Deflcdchar 1, 32, 32, 16, 16, 16, 16, 32, 32 | Chr(1)の文字データ。 | ||
15 | Deflcdchar 2, 32, 32, 24, 24, 24, 24, 32, 32 | Chr(2)の文字データ。 | ||
16 | Deflcdchar 3, 32, 32, 28, 28, 28, 28, 32, 32 | Chr(3)の文字データ。 | ||
17 | Deflcdchar 4, 32, 32, 30, 30, 30, 30, 32, 32 | Chr(4)の文字データ。 | ||
18 | Deflcdchar 5, 32, 32, 31, 31, 31, 31, 32, 32 | Chr(5)の文字データ。 | ||
19 | Deflcdchar 6, 32, 1 , 16, 16, 16, 16, 1 , 32 | Chr(6)の文字データ。 | ||
20 | Cursor Off | カーソルを表示しない。 | ||
21 | ||||
22 | Do | Doループの範囲ここから。 | ||
23 | Start Adc | A⁄D変換を開始する。 | ||
24 | A = Getadc(9) | 「ADC9」の入力をA⁄D変換して「A」に代入。 | ||
25 | T = A / 2.048 | 「A÷2.048」の答えを変数「T」に代入。 | ||
26 | T = T * 2 | 「T」に「2」を掛けたものを「T」とする。 | ||
27 | Cls | LCDの表示を消去する。 | ||
28 | Locate 1 , 4 : Lcd "1O" | LCDの上の行4桁目に「10」を表示する。 | ||
29 | Locate 1 , 8 : Lcd "2O" | LCDの上の行8桁目に「20」を表示する。 | ||
30 | Locate 1 , 12 : Lcd "3O" | LCDの上の行12桁目に「30」を表示する。 | ||
31 | Call Bargraph1 | サブルーチン「Bargraph1」を実行する。 | ||
32 | Call Bargraph2 | サブルーチン「Bargraph2」を実行する。 | ||
33 | Wait 1 | 1秒間そのまま。 | ||
34 | Loop | Doループの範囲ここまで。22行目へ戻る。 | ||
35 | ||||
36 | End | メインプログラム終わり。 | ||
37 | ||||
38 | Sub Bargraph1 | サブルーチン「Bargraph1」ここから。 | ||
(1桁単位のバーを表示するプログラム)。 | ||||
39 | Local Col As Byte | サブルーチン内で変数「Col」を使用する。 | ||
40 | Local Bar5 As Byte | サブルーチン内で変数「Bar5」を使用する。 | ||
41 | Bar5 = T / 5 | 「T」を「5」で割った数を「Bar5」とする。 | ||
42 | Lowerline | LCDの下の行に表示する。 | ||
43 | For Col = 1 To Bar5 | Forループ。「Bar5」回繰り返し。 | ||
44 | Select Case Col | 変数値選択。「Col」の値によって表示を変える。 | ||
45 | Case 2 : Lcd Chr(6) | 「Col=2」ならばLCDにChr(6)を表示する。 | ||
46 | Case 4 : Lcd Chr(6) | 「Col=4」ならばLCDにChr(6)を表示する。 | ||
47 | Case 6 : Lcd Chr(6) | 「Col=6」ならばLCDにChr(6)を表示する。 | ||
48 | Case 8 : Lcd Chr(6) | 「Col=8」ならばLCDにChr(6)を表示する。 | ||
49 | Case 10 : Lcd Chr(6) | 「Col=10」ならばLCDにChr(6)を表示する。 | ||
50 | Case 12 : Lcd Chr(6) | 「Col=12」ならばLCDにChr(6)を表示する。 | ||
51 | Case 14 : Lcd Chr(6) | 「Col=14」ならばLCDにChr(6)を表示する。 | ||
52 | Case 16 : Lcd Chr(6) | 「Col=16」ならばLCDにChr(6)を表示する。 | ||
53 | Case Else : Lcd Chr(5) | 「Col」が上記以外ならばChr(5)を表示する。 | ||
54 | End Select | 変数値選択ここまで。 | ||
55 | Next Col | Forループここまで。43行目へ戻る。 | ||
56 | End Sub | サブルーチン「Bargraph1」ここまで。 | ||
57 | ||||
58 | Sub Bargraph2 | サブルーチン「Bargraph2」ここから。 | ||
(1⁄5桁単位のバーを表示するプログラム)。 | ||||
59 | Local Bar1 As Byte | サブルーチン内で変数「Bar1」を使用する。 | ||
60 | Bar1 = T Mod 5 | 「T」を「5」で割った余りを「Bar1」とする。 | ||
61 | Select Case Bar1 | 変数値選択。「Bar1」の値によって表示を変える。 | ||
62 | Case 1 : Lcd Chr(1) | 「Bar1=1」ならばLCDにChr(1)を表示する。 | ||
63 | Case 2 : Lcd Chr(2) | 「Bar1=2」ならばLCDにChr(2)を表示する。 | ||
64 | Case 3 : Lcd Chr(3) | 「Bar1=3」ならばLCDにChr(3)を表示する。 | ||
65 | Case 4 : Lcd Chr(4) | 「Bar1=4」ならばLCDにChr(4)を表示する。 | ||
66 | End Select | 変数値選択ここまで。 | ||
67 | End Sub | サブルーチン「Bargraph2」ここまで。 |
1℃あたりバーの長さが2⁄5桁分なので、26行目「T = T * 2」で温度値を2倍しています。25行目を「T = A / 1.024」と書いてもいいのですが、あとから見たときに何をやっているかわからなくなりそうだったので2行に分けました。
サブルーチン「Bargraph1」は5℃分のバーを表示するプログラム、サブルーチン「Bargraph2」は1℃分のバーを表示するプログラムです。それぞれ「変数値選択」(私が勝手に付けた名前です)によって表示する文字(バーの長さや形)を変えます。「変数値選択」については「LCDの表示(その6)」を見てください。
温度値が10〜15℃のときの変数の値とLCDの表示は次のようになります。
温度(T) | x2 | Bar5 | Bar1 | 表示する文字 | LCDの表示 |
10℃ | 20 | 4 | 0 | Chr 5, 6, 5, 6 | |
11℃ | 22 | 4 | 2 | Chr 5, 6, 5, 6, 2 | |
12℃ | 24 | 4 | 4 | Chr 5, 6, 5, 6, 4 | |
13℃ | 26 | 5 | 1 | Chr 5, 6, 5, 6, 5, 1 | |
14℃ | 28 | 5 | 3 | Chr 5, 6, 5, 6, 5, 3 | |
15℃ | 30 | 6 | 0 | Chr 5, 6, 5, 6, 5, 6 |