電子工作54 – 経過時間LED表示付きで、30分、1、2、3、4、5、6時間に設定可能な簡易タイマの製作
概要
前の電子工作51の簡易タイマの改良版である。今回は選択できる時間を1個増やして7個にし、さらに5個のLEDを使って各選択した時間の経過の状態を目視出来るようにした。前回と同様に時間の基準に4MHzの内部クロックを使ったが得られた結果はすごく正確だった。
注意: 危険なので製作は自分の責任で行うこと。
製作にあたって;
1) 最長6時間位まで設定可能なこと。
2) 設定時間が来たら電源が“切れる”または“入る”モードを選択出来ること。
3) 駆動するLEDsの数が増えたので28ピンの16F886を使う。
4) 経過時間を表示する精度は高くなくてよい。
5) 時間の精度は電子工作51の場合と同じ程度でよい。
回路図と動作原理
回路図を下に示す。今回は結構高機能な16F886を使った。ADCの入力電圧を変えるVR100Kを回すとLED1−7のいずれが点灯する。各LEDに設定時間が割り当てられている(LED1=30min,LED2=1hr、LED3=2hrs、LED4=3hrs、LED5=4hrs、LED6=5hrs、LED7=6hrs)。設定した時間が来たらタイマが“切れる”または“入る”の設定はMode SWで行う(L:“切れる”、H:“入る”)。設定した時間が終了したらSSRとLED(G)をON/OFFする。経過時間レベル表示LEDsは時間を設定すると5個のLEDsが全て点灯し、時間の経過とともに点灯するLEDs数が上から減って行き、時間が終了すると全てが消える。Reset SWを押すと同じLED表示時間でまた時間の計数が始まる。VR100Kを回して別の(または同じ)時間を選択すると、その瞬間をゼロして時間の計数がまた始まる。電源には出力DC5V位(>200mA)のACアダプタを使う。
)
実験中: 16F886の右手が経過時間レベル表示用の5個のLEDL5−1。時間の経過とともに
上から順次消灯して行く。左下が時間設定用の7個のLED1−7。左上の丸いものがVR。
これを回して時間を選択する。その下にはMode SWが見える。このボードには差当り
SSRの代わりにブザーを載せている。
結果&コメント
1) Internal Clock 4MHzを基準にしているにもかかわらず、下表のように時間の精度は大変高いことが分かった。コマンドPauseを使って遅延をつくっているので精度はそれほどでもないと思っていた。実測時間値(3,4,5,6時間値)は原則1回だけの測定(数日間にわたり)で得られた値である。
設定時間 |
30 min |
1 hr |
2 hrs |
3 hrs |
4 hrs |
5 hrs |
6 hrs |
実測時間 |
30m 0s |
1hr 4s |
2hr 3s |
3hr 8s |
4hr 9s |
5hr 7s |
6hr 8s |
時間差 |
0s |
1s |
3s |
8s |
9s |
7s |
8s |
(測定時環境温度:10−20°C、クオーツ時計で時間測定)
2) 30分の遅延ルーチンFor m=1 to 177で、繰返し数177は実験的に見出した。この値を基準にして1、2、3、4、5、6時間値を作成した。例えば、2時間では177x4=708回。
3) 経過時間と5個のLEDL5-1表示の関係 {設定時間が1時間の場合} − 時間の経過と共にLEDL5、LEDL4、...LEDL1が順次消灯して行く。例えば、上からLEDL5とLEDL4が消灯していて残りの3つのLEDが点灯している場合は残りの時間は36−24minの範囲と考える。設定時間が2時間以上の場合も、各時間値を下表の各数値に掛け算してやれば残り時間や時間範囲が計算できる。
設定時間が1時間の場合
消灯するLED |
残り時間 |
時間範囲 |
LEDL5 |
48min |
60-48min |
LEDL4 |
36min |
48-36min |
LEDL3 |
24min |
36-24min |
LEDL2 |
12min |
24-12min |
LEDL1 |
0 |
12-0min |
4) VR100Kを回して、ある時間表示LEDを選択した瞬間からその時間の計数が始まる。したがって、1時間に設定しておいて途中で3時間などに設定し直すとその時点から3時間の計数が始まる。
5) この簡易タイマでは、例えば30分と1時間の間の時間設定は出来ない(市販のシンクロナスモータを使ったものは出来る)。
6) 最初12時間タイマを同じ16F886を使って試みたがプログラムが長すぎたようで動作しなかった。プログラムが大分コンパクトになってきたので次回はうまく行くかも知れない。
7) 少ない部品でかなり使えそうだ。総材料費は1000円ほど。16F886は¥190だった。、
プログラム
このプログラムではVR100Kを使う分圧器からの入力電圧をもとに7個のLED1−7で設定時間の表示・選択が出来るようにした。 今回は5Vに対応する1024を7つに分割し1間隔を146(1024/7)にしてある。それとMode SWで時間が来たら“切れる”と“入る”を選択できるようにしたので合計14の時間の計数ルーチンが必要になるが、サブルーチンを使って7個に減らした。どのLED表示時間にあってもVRを回して途中で自由に変更し再スタート出来るのがポイントの一つである。すなわち現在計数しているルーチンの中に“まだ同じLED表示時間の中にいるか?”を常時チェックする部分を加えることでそれが可能になった。今回の最大特徴である経過時間を5個のLED(LEDL5-LEDL1)を使って表示する機能は次の様な原理による。すなわち、各時間を計数中の秒数を6範囲に分けて選択させ、サブルーチンを使って最初は点灯しているLEDL5-LEDL1を順次消灯させて行き、設定時間が終了すると同時に最後のLEDL1も消灯させる仕組みである。以下の例(斜体字で表示)は30分の計数の場合で、経過時間を5個のLED(LEDL5-LEDL1)を使って表示する部分である。
Next n
If (m>=1)
and (m<35) Then GOSUB Level5
If
(m>=35) and (m<70) Then GOSUB Level4
If
(m>=70) and (m<106) Then GOSUB Level3
If
(m>=106) and (m<141) Then GOSUB Level2
If
(m>=141) and (m<177) Then GOSUB Level1
If m=177 Then GOSUB Level0
Next m
‘********************************************
'SimpleTimer16F886LvlsmlC.bas - Compact version of SimpleTimer16F886Lvlsml.bas (2011.4.9) works OK!
'16F886 (28pins) with internal clock 4MHz (default)
'Timer - ON or OFF when time expires (30 min, 1,2,3,4,5,6 hour - 7 settings)
'********Pin connections************
'Pin 1: MCLR (Reset)
'Pin 2: PORTA.0: input - analogue input of 0-5.0V from VR 100K
'Pin 3: PORTA.1: input - connected to Mode SW
'Pin 4: PORTA.2: output - connected to LED (G) - SSR drive
'Pin 5: PORTA.3: output - connected to LED1
'Pin 6: PORTA.4: output - connected to LED2
'Pin 7: PORTA.5: output - connected to LED3
'Pin 8: Vss (GND)
'Pin 9: PORTA.7: output - connected to LED5
'Pin 10: PORTA.6: output - connected to LED4
'Pin 11: PORTC.0: output - connected to LED6
'Pin 12: PORTC.1: output - connected to LED7
'Pin 19: Vss (GND)
'Pin 20: Vdd (+5V)
'Pin 21: PORTB.0 output - LEDL1 (0-20%)
'Pin 22: PORTB.1 output - LEDL2 (20-40)
'Pin 23: PORTB.2 output - LEDL3 (40-60)
'Pin 24: PORTB.3 output - LEDL4 (60-80)
'Pin 25: PORTB.4 output - LEDL5 (80-100)
'*********** Program **********
Define ADC_BITS 10 '10-bit ADC used 以下の10行はADCの設定
Define ADC_CLOCK 3 'Internal RC clock used
Define ADC_SAMPLEUS 50 'Sample timing
ADCON0=%01000011
'bit7-6=01(Fosc/8), bit5-2=0000(Channel An0 selected)
'bit1=1(GO/DONE starts right away),bit0=1(ADC enable)
ADCON1=%10000000
'bit7=right justIfied),bit6=0(unimplemented)
'bit5-4=00(Vss & Vdd used as refererence voltage)
'bit3-0=0000(unimplemented)
ANSEL=%00000001 'Channel AN0 for ADC used as analog Pin2のAN0をアナログに設定
ANSELH=0 ‘necessary?
OSCCON=%01100001 'Internal 4MHz clock used 内蔵4MHzを使用
CM1CON0=0 'Comparator Off コンパレータは使用しない。16F886ではこの2個を設定しないといけない
CM2CON0=0 'Comparator Off
TRISA=%00000011 '2 inputs - from An0 and divider
TRISB=%00000000 'All are outputs (5 ports)
TRISC=%00000000 'All are outputs
Vin var word 'AD input value from VR 100K ADC値は最大で1024(5V)なのでWORDで変数宣言
ModeSWInput var PORTA.1 'Mode SW input from Mode SW (ON or OFF when time expires) 設定時間が終了したらSSRが“切れる”なたは“入る”を選択
SSRSW var PORTA.2 'SSRSW - ON/OFF of SSR (LED G) SSRとLED(G)のON/OFFを行う
LED1 var PORTA.3 'ON/OFF of LED1 (30min) 以下の7個のLED1−LED7で設定時間を表示
LED2 var PORTA.4 'ON/OFF of LED2 (1hr)
LED3 var PORTA.5 'ON/OFF of LED3 (2hrs)
LED4 var PORTA.6 'ON/OFF of LED4 (3hrs)
LED5 var PORTA.7 'ON/OFF of LED5 (4hrs)
LED6 var PORTC.0 'ON/OFF of LED6 (5hrs)
LED7 var PORTC.1 'ON/OFF of LED7 (6hrs)
LEDL1 var PORTB.0 'ON/OFF of LEDL1 以下の5個のLEDL1-5で経過時間を表示
LEDL2 var PORTB.1 'ON/OFF of LEDL2
LEDL3 var PORTB.2 'ON/OFF of LEDL3
LEDL4 var PORTB.3 'ON/OFF of LEDL4
LEDL5 var PORTB.4 'ON/OFF of LEDL5
m var word ‘counter
n var byte ‘counter
Loop:
Adcin 0, Vin ‘Read analog value from AN0 (Pin2) Pin2よりアナログ値を読込む
Pause 5 'Wait 5ms
SSRSW=0
LOW LEDL1: LOW LEDL2: LOW LEDL3: LOW LEDL4: Low LEDL5 'OFF LEDL1-5 ‘LEDL1-5を消灯しておく
'Selecting time (voltage) range (5V - 1024/7 fraction=146)
If (146>=Vin) Then LED1ON '30 min 上で読込んだアナログ値を大きさによって以下の7つの範囲に分類して飛ばす
If (146<Vin) AND (Vin=<292) Then LED2ON '1 hr
If (292<Vin) AND (Vin=<438) Then LED3ON '2 hrs
If (438<Vin) AND (Vin=<584) Then LED4ON '3 hrs
If (584<Vin) AND (Vin=<730) Then LED5ON '4 hrs
If (730<Vin) AND (Vin=<876) Then LED6ON '5 hrs
If (876<Vin) Then LED7ON '6 hrs
'Indicating selected time (voltage) ranges on LED1-7
LED1ON: '30 min 30分の場合
High LED1: Low LED2: Low LED3: Low LED4: Low LED5: Low LED6: Low LED7 ‘先ずLED1-7を消灯する
If ModeSWInput=0 Then LED1Tcount ‘Check the state of Mode SW モードSWをチェックし、LED1TcountまたはLED1TcountDownに飛ぶ
Goto LED1TcountDown
LED2ON: '1 hr
Low LED1:High LED2:Low LED3:Low LED4:Low LED5:Low LED6:Low LED7
If ModeSWInput=0 Then LED2Tcount
Goto LED2TcountDown
LED3ON: '2 hrs
Low LED1:Low LED2:High LED3:Low LED4:Low LED5:Low LED6:Low LED7
If ModeSWInput=0 Then LED3Tcount
Goto LED3TcountDown
LED4ON: '3 hrs
Low LED1:Low LED2:LOW LED3:High LED4:Low LED5:Low LED6:Low LED7
If ModeSWInput=0 Then LED4Tcount
Goto LED4TcountDown
LED5ON: '4 hrs
Low LED1:Low LED2:LOW LED3:LOW LED4:High LED5:Low LED6:Low LED7
If ModeSWInput=0 Then LED5Tcount
Goto LED5TcountDown
LED6ON: '5 hrs
Low LED1:Low LED2:LOW LED3:LOW LED4:Low LED5:High LED6:Low LED7
If ModeSWInput=0 Then LED6Tcount
Goto LED6TcountDown
LED7ON: '6 hrs
Low LED1:Low LED2:LOW LED3:LOW LED4:Low LED5:Low LED6:High LED7
If ModeSWInput=0 Then LED7Tcount
Goto LED7TcountDown
'Counting time 以下で時間の計数を行う
LED1Tcount: '30 min OFF when time expires 30分の場合でSSRを30分間ONにし、そしてOFFにするルーチン(時間が来たら“切れる”)
High LEDL1: High LEDL2: High LEDL3: High LEDL4: High LEDL5 'ON LEDL1-5 ‘先ずLEDL1-5を全て点灯する
High SSRSW 'SSR -> ON SSRをONにする
Gosub A30mTcount ‘Jump to A30mTcount サブルーチンA30mTcountに飛んで正確に30分したら戻れ
Low SSRSW 'SSR -> OFF SSRをOFFにする。これでSSRを30分間ONにした後でOFFにする動作が終了する
Goto Finishing
LED1TcountDown: '30 min ON when time expires 30分の場合でSSRを30分間OFFにし、そしてONにするルーチン(時間が来たら“入る”)
High LEDL1: High LEDL2: High LEDL3: High LEDL4: High LEDL5 'ON LEDL1-5 ‘先ずLEDL1-5を全て点灯する
Low SSRSW 'SSR -> OFF SSRをOFFにする
Gosub A30mTcount ‘Jump to A30mTcount サブルーチンA30mTcountに飛んで正確に30分したら戻れ
High SSRSW 'SSR -> ON SSRをONにする。これでSSRを30分間OFFにした後でONにする動作が終了する
Goto Finishing
LED2Tcount: '1 hour 1時間の場合。30分の場合と同じ
High LEDL1: High LEDL2: High LEDL3: High LEDL4: High LEDL5 'ON LEDL1-5
High SSRSW 'SSR -> ON
Gosub A1hTcount
Low SSRSW 'SSR -> OFF
Goto Finishing
LED2TcountDown: '1 hour
High LEDL1: High LEDL2: High LEDL3: High LEDL4: High LEDL5 'ON LEDL1-5
Low SSRSW 'SSR -> OFF
Gosub A1hTcount
high SSRSW 'SSR -> ON
Goto Finishing
LED3Tcount: '2 hours
High LEDL1: High LEDL2: High LEDL3: High LEDL4: High LEDL5 'ON LEDL1-5
High SSRSW 'SSR -> ON
Gosub A2hTcount
Low SSRSW 'SSR -> OFF
Goto Finishing
LED3TcountDown: '2 hours
High LEDL1: High LEDL2: High LEDL3: High LEDL4: High LEDL5 'ON LEDL1-5
Low SSRSW 'SSR -> OFF
Gosub A2hTcount
High SSRSW 'SSR -> ON
Goto Finishing
LED4Tcount: '3 hours
High LEDL1: High LEDL2: High LEDL3: High LEDL4: High LEDL5 'ON LEDL1-5
High SSRSW 'SSR -> ON
Gosub A3hTcount
Low SSRSW 'SSR -> OFF
Goto Finishing
LED4TcountDown: '3 hours
High LEDL1: High LEDL2: High LEDL3: High LEDL4: High LEDL5 'ON LEDL1-5
Low SSRSW 'SSR -> OFF
Gosub A3hTcount
High SSRSW 'SSR -> ON
Goto Finishing
LED5Tcount: '4 hours
High LEDL1: High LEDL2: High LEDL3: High LEDL4: High LEDL5 'ON LEDL1-5
High SSRSW 'SSR -> ON
Gosub A4hTcount
Low SSRSW 'SSR -> OFF
Goto Finishing
LED5TcountDown: '4 hours
High LEDL1: High LEDL2: High LEDL3: High LEDL4: High LEDL5 'ON LEDL1-5
Low SSRSW 'SSR -> OFF
Gosub A4hTcount
High SSRSW 'SSR -> ON
Goto Finishing
LED6Tcount: '5 hours
High LEDL1: High LEDL2: High LEDL3: High LEDL4: High LEDL5 'ON LEDL1-5
High SSRSW 'SSR -> ON
Gosub A5hTcount
Low SSRSW 'SSR -> OFF
Goto Finishing
LED6TcountDown: '5 hours
High LEDL1: High LEDL2: High LEDL3: High LEDL4: High LEDL5 'ON LEDL1-5
Low SSRSW 'SSR -> OFF
Gosub A5hTcount
High SSRSW 'SSR -> ON
Goto Finishing
LED7Tcount: '6 hours
High LEDL1: High LEDL2: High LEDL3: High LEDL4: High LEDL5 'ON LEDL1-5
High SSRSW 'SSR -> ON
Gosub A6hTcount
Low SSRSW 'SSR -> OFF
Goto Finishing
LED7TcountDown: '6 hours
High LEDL1: High LEDL2: High LEDL3: High LEDL4: High LEDL5 'ON LEDL1-5
Low SSRSW 'SSR -> OFF
Gosub A6hTcount
High SSRSW 'SSR -> ON
Goto Finishing
'Subroutines サブルーチン
A30mTcount: ‘30min time counting 30分間計数するルーチン
For m=1 to 177 '30 min adjusted after actual measurement (180 in theory) この数値177は実験的に見出した
For n=1 to 40 '10 sec For n=1 to 40 とNext nが1回終了するのに約10秒かかる
Adcin 0, Vin ‘Read Vin again and check if 146>=Vin is still valid Vinを読込んで146>=Vinであるかどうか確かめる。YesならEndifへ、NoならLoopへ飛ぶ
Pause 5 'Wait 5ms この部分は時間の計数の途中でVRを回してLED1−7(時間選択)の位置を変えても、その位置で最初から計数が始まるようにするためである。重要!!
If (146>=Vin) Then
Pause 250 '250 ms
Else
Goto Loop
Endif
Next n
If (m>=1) and (m<35) Then GOSUB Level5 ‘Checking m value and turning off LEDL5-1 one by one mの値をチェックしながらサブルーチンに飛んでLEDL5-1を順次OFFにする
If (m>=35) and (m<70) Then GOSUB Level4
If (m>=70) and (m<106) Then GOSUB Level3
If (m>=106) and (m<141) Then GOSUB Level2
If (m>=141) and (m<177) Then GOSUB Level1
If m=177 Then GOSUB Level0
Next m
Return
A1hTcount: ‘1 hr time counting 1時間計数するルーチン 以下30分間計数するルーチンの場合と同じ
For m=1 to 354 '177 x 2
For n=1 to 40 '10 sec
Adcin 0, Vin
Pause 5 'Wait 5ms
If (146<Vin) AND (Vin=<292) Then
Pause 250 '250 ms
Else
Goto Loop
Endif
Next n
If (m>=1) and (m<70) Then GOSUB Level5
If (m>=70) and (m<141) Then GOSUB Level4
If (m>=141) and (m<211) Then GOSUB Level3
If (m>=211) and (m<282) Then GOSUB Level2
If (m>=282) and (m<354) Then GOSUB Level1
If m=354 Then GOSUB Level0
Next m
Return
A2hTcount:
For m=1 to 708 '2 hours (354 x 2, 2011.4.7)
For n=1 to 40 '10 sec
Adcin 0, Vin
Pause 5 'Wait 5ms
If (292<Vin) AND (Vin=<438) Then
Pause 250 '250 ms
Else
Goto Loop
Endif
Next n
If (m>=1) and (m<140) Then GOSUB Level5
If (m>=140) and (m<280) Then GOSUB Level4
If (m>=280) and (m<420) Then GOSUB Level3
If (m>=420) and (m<560) Then GOSUB Level2
If (m>=560) and (m<708) Then GOSUB Level1
If m=708 Then GOSUB Level0
Next m
Return
A3hTcount:
For m=1 to 1062 '3 hours (354 x 3, 2011.4.7)
For n=1 to 40 '10 sec
Adcin 0, Vin
Pause 5 'Wait 5ms
If (438<Vin) AND (Vin=<584) Then
Pause 250 '250 ms
Else
Goto Loop
Endif
Next n
If (m>=1) and (m<210) Then GOSUB Level5
If (m>=210) and (m<420) Then GOSUB Level4
If (m>=420) and (m<630) Then GOSUB Level3
If (m>=630) and (m<840) Then GOSUB Level2
If (m>=840) and (m<1062) Then GOSUB Level1
If m=1062 Then GOSUB Level0
Next m
Return
A4hTcount:
For m=1 to 1416 '4 hours (354 x 4, 2011.4.7)
For n=1 to 40 '10 sec
Adcin 0, Vin
Pause 5 'Wait 5ms
If (584<Vin) AND (Vin=<730) Then
Pause 250 '250 ms
Else
Goto Loop
Endif
Next n
If (m>=1) and (m<280) Then GOSUB Level5
If (m>=280) and (m<560) Then GOSUB Level4
If (m>=560) and (m<840) Then GOSUB Level3
If (m>=840) and (m<1120) Then GOSUB Level2
If (m>=1120) and (m<1416) Then GOSUB Level1
If m=1416 Then GOSUB Level0
Next m
Return
A5hTcount:
For m=1 to 1770 '5 hours (354 x 5, 2011.4.7)
For n=1 to 40 '10 sec
Adcin 0, Vin
Pause 5 'Wait 5ms
If (730<Vin) AND (Vin=<876) Then
Pause 250 '250 ms
Else
Goto Loop
Endif
Next n
If (m>=1) and (m<350) Then GOSUB Level5
If (m>=350) and (m<700) Then GOSUB Level4
If (m>=700) and (m<1050) Then GOSUB Level3
If (m>=1050) and (m<1400) Then GOSUB Level2
If (m>=1400) and (m<1770) Then GOSUB Level1
If m=1770 Then GOSUB Level0
Next m
Return
A6hTcount:
For m=1 to 2124 '6 hours (354 x 6, 2011.4.7)
For n=1 to 40 '10 sec
Adcin 0, Vin
Pause 5 'Wait 5ms
If (876<Vin) Then
Pause 250 '250 ms
Else
Goto Loop
Endif
Next n
If (m>=1) and (m<420) Then GOSUB Level5
If (m>=420) and (m<840) Then GOSUB Level4
If (m>=840) and (m<1260) Then GOSUB Level3
If (m>=1260) and (m<1680) Then GOSUB Level2
If (m>=1680) and (m<2124) Then GOSUB Level1
If m=2124 Then GOSUB Level0
Next m
Return
Level5: High LEDL1: High LEDL2: High LEDL3: High LEDL4: High LEDL5: Return ‘LED5-1 ON/OFF subroutines 以下のサブルーチンでLED5-1を順次 ON/OFFさせる
Level4: High LEDL1: High LEDL2: High LEDL3: High LEDL4: Low LEDL5: Return
Level3: High LEDL1: High LEDL2: High LEDL3: LOW LEDL4: Low LEDL5: Return
Level2: High LEDL1: High LEDL2: LOW LEDL3: LOW LEDL4: Low LEDL5: Return
Level1: High LEDL1: LOW LEDL2: LOW LEDL3: LOW LEDL4: Low LEDL5: Return
Level0: LOW LEDL1: LOW LEDL2: LOW LEDL3: LOW LEDL4: Low LEDL5: Return
Finishing:
End
'****** End of Program ********
'Note:
'melabs U2 Programmer's configurations for 16F886
‘Oscillator - INTOSCIO, WDTE - Enable; Power-up Timer – Disable, MCLR Pin Function - Reset, Brown-out Reset - Enable
‘Internal External Switch Over – Enable, Fail-Safe Clock Monitor – Enable, Low Voltage Programming – Enable,
‘Code – Not Protected, Dtata EPPROM – Not Protected, Brown-out Reset Voltage – 4.0V, Flash Program Memory Write - all
'*******************************************************************************