'****************************************************************
'* Name : Terarium
'* Version : 1.0 *
'* Notes : PIC 16F648A *
'****************************************************************
@ device intrc_osc, mclr_off, wdt_off, pwrt_on, lvp_off, protect_off, cpd_off, bod_off
DEFINE OSC 4 ' Default 4MHz
CMCON = 7
INTCON 0.7 = 0 ' Turn interrupts OFF
'T2CON = %00010100 ' Turn on Timer2, Prescale = 4
'T2CON = %00000100 ' Turn on Timer2, Prescale = 1 00010101
'CCP1CON = %00001100 ' Set CCP1 to PWM
'PR2 = 25 ' Set PR2 for 38.4kHz PWM [26uS period]
OPTION_REG 0.7 = 0 ' Turn ON PortB pullups
RprtTime con 5 'Âðåìå â ñåê. çà èçïðàùàíå äàííè êúì ÐÑ
Ser_Mode con 82
Ser_ModeRX Con 80
MaxRead con 250
MaxB con 80 'Ìàêñèìàëíà äúëæèíà íà Buffer
'INPUTS
RX Var PortA.0
Button2 VAR PORTA.4
Button1 VAR PORTA.5
DQ Var PortA.6 'Alias DS1820 data pin
DQ_Dir Var TrisA.6
'OUTPUTS
TX Var PortA.1
Rel1 var PortA.3
Rel2 Var PortA.2
LED VAR PORTA.7
Lamp var PortB.3
TrisA = %01110001
TrisB = %11110111
Buffer Var Byte [MaxB]bank2
LenB Var Buffer[0]
Addrr Var byte [8]
Char var Byte
Comm Var Byte 'Âèä êîìóíèêàöèÿ çà OneWire
I Var byte: I1 Var Byte
J var byte: J1 Var Byte
K Var Byte: K1 Var Byte
B1 Var Byte: B2 Var Byte: B3 Var Byte : B4 var Byte
W1 var WOrd: W2 var Word
H2A Var byte
A2H Var Byte
C2H Var byte
CharL var byte
CharH var Byte
Seconds Var Byte
Counter Var Byte
TmpBit Var bit
TmpWord Var Word
TmpByte Var Byte
Temp var word ' Storage for temperature
Stat VAR bit ' Count remaining
T_Count var Byte ' Áðîé äàò÷èöè
Relays Var Word ' Âñåêè áèò ïîêàçâà ñúñòîÿíèåòî íà ñúîòâ. ðåëå
ForceR Var Word ' Âñåêè áèò ïîêàçâà ïðèíóä. âêë. ñúîòâ. ðåëå
Hist Var byte 'Õèñòåðåçèñ ì/ó òåìï. çà âêë/èçêë
Night var word[16]'Íàìàëÿâàíå ñ Night ãðàä. ïðåç íîùòà
Mode Var Byte '0-Äíåâåí ðåæèì, 1-Íîùåí ðåæèì, 3-Ìîíèòîðèíã
Lmp Var Byte 'Ñúñòîÿíèå íà ëàìïàòà
Day Var word[16] 'Ìàñèâ îò çàäàäåíè òåìïåðàòóðè
Data @0,0 'Mode
Data @1, 20 'Õèñòåðåçèñ â 1/10 îò ãðàäóñ
Data @2,0 'Ñúñòîÿíèå íà ëàìïàòà
Data @4,Word $0 'Ñúñòîÿíèå Ðåëåòà
Data @6,Word $0 'Forced Relays
Data @9,0 'Íåèçïîëçâàíî çàñåãà
'Data @10, $E0,$20,$AE,$01,$40,$00,$F8,$FA 'ROM Dalas 1
'Data ..............
Data @170,Word 200'Ò1 çà äàò÷èê 1 â 1/10 îò ãðàäóñ
Data @172,Word 250'Ò2 çà äàò÷èê 2 â 1/10 îò ãðàäóñ
Data @174,Word 300'Ò3 çà äàò÷èê 3 â 1/10 îò ãðàäóñ
Data @176,Word 320'Ò4 çà äàò÷èê 4 â 1/10 îò ãðàäóñ
'Data ..............
Data @210,word 160 'Night1 â 1/10 îò ãðàäóñ
Data @212,word 185 'Night2 â 1/10 îò ãðàäóñ
Data @214,word 190 'Night3 â 1/10 îò ãðàäóñ
Data @216,word 200 'Night4 â 1/10 îò ãðàäóñ
'Data...............
INIT:
Rel1 = 0: Rel2 = 0: Lamp = 0: Led = 0: TX = 1
Pause 500
Clear
'Ïðîâåðêà çà èíèöèàëèçàöèÿ èëè ÷åòåíå íà àäðåñ íà OneWire ó-âî
If Button1 = 0 Then
Led = 1
If Button2 = 0 Then 'Àêî ñà íàòèñíàòè Áóòîí 1 è Áóòîí 2
For J=10 to 159:Write J,$FF:Next J
End
End If
For I = 0 To 15 'Àêî å íàòèñíàò ñàìî Áóòîí 1
Char = 0: J = (I + 1) * 10: Read J, Char
If Char=$FF Then
Led = 0
GoSub Read_Adr: Pause 250
GoSub WriteROM: Pause 250
For J1 = 0 To 5: Toggle Led: Pause 200: Next J1
Led = 1
End
End If
Next I
End If 'Button1=0
If Button2 = 0 Then 'Íóëèðàíå íà Mîde, Lamp è ForceR
Lamp = 0: Mode = 0: ForceR = 0
GoSub Write_L: GoSub Write_M: GoSub Write_R
End If
'*********************************************************************
Init1820: ' Initialize DS1820 and check for presence
Low DQ ' Set the data pin low to init
Pauseus 500 ' Wait > 480us
DQ_DIR = 1 ' Release data pin (set to input for high)
Pauseus 100 ' Wait > 60us
If DQ = 1 Then
Error: B1 = "E": B2 = 0: B3 = 0: B4 = 0: GoSub Report_ANY: Led = 1: End 'Íÿìà âúðçàíè óñòðîéñòâà OneWire
End If
Check: 'Êîëêî óñòðîéñòâà ñà âúðçàíè?
For I = 0 To 15
Char = 0: Read (I + 1) * 10, Char
If Char=$FF Then
If I = 0 Then
B1 = "E": B2 = 1: B3 = 0: B4 = 0: GoSub Report_ANY: Led = 1: End
Else
GoTo End_Check
End If
End If
Next I
End_Check:
T_Count = I - 1
MAIN:
GoSub Read_Data:
'Èíèöèàëèçàöèÿ íà ëàìïà è ðåëåòa
Lamp = Lmp: GoSub ON_OFF_R: GoSub Report_S
Goto LOOP
'*********************************************************************
OW_Comm: 'Comm - $44-Temperature measure, $BE-Read ROM, Addrr-address OneWire
OWOut DQ, 1, [$55]
For J = 0 To 7: OWOut DQ, 0, [Addrr[J]]: Next J
OWOut DQ, 0, [Comm]
Return
''*********************************************************************
Report_ANY:
H2A = B2: GoSub Hex2ASC: B2 = H2A
C2H = B3: GoSub Char2Hex: W1.HighByte = CharH: W1.LowByte = CharL
C2H = B4: GoSub Char2Hex: W2.HighByte = CharH: W2.LowByte = CharL
Serout2 TX, Ser_Mode, [B1,B2," ",W1.highbyte,W1.Lowbyte,W2.HighByte,W2.LowByte,13,10]
Return
'*********************************************************************
Report_S: 'Ïîêàçâà Ñúñòîÿíèåòî íà âñè÷êî
GoSub Report_M
GoSub Report_L
GoSub Report_H
For I = 0 To T_Count
GoSub Report_R
GoSub Report_F
GoSub Report_N
GoSub Report_D
Next I
Return
'*********************************************************************
Char2Hex: 'Ïðåâðúùà C2H â äâå HEX öèôðè CharL è CharH
H2A=C2H&%00001111
GoSub Hex2ASC
CharL = H2A
H2A=C2H&%11110000
H2A=H2A>>4
GoSub Hex2ASC
CharH = H2A
Return
'*********************************************************************
Hex2ASC: 'Ïðåâðúùà H2A îò ÷èñëî(0-15) â HEX öèôðà(0-F)
If H2A < 10 Then
H2A = H2A + 48
Else
H2A = H2A + 55
End If
Return
'*********************************************************************
ASC2Hex: 'Ïðåâðúùà A2H ot HEX öèôðà(0-F) â ÷èñëî(0-15)
If A2H > 57 Then
A2H = A2H - 55
Else
A2H = A2H - 48
End If
Return
'*********************************************************************
ReadROM: '×åòå àäðåñ íà äàò÷èê íîìåð I
For J = 0 To 7
J1=(I+1)*10+J:Read J1,Addrr[J]
Next J
Return
'*********************************************************************
WriteROM: 'Çàïèñâà àäðåñ íà äàò÷èê íîìåð I
For J = 0 To 7
J1=(I+1)*10+J:Write J1,Addrr[J]:Pause 10
Next J
Return
'*********************************************************************
Read_Adr: '×åòå îò OneWire óñòðîéñòâî àäðåñà
OWOut DQ, 1, [$33] ' Issue Read ROM command
OWIn DQ, 0, [STR Addrr\8] ' Read 64-bit device data into the 8-byte array "ROM"
Return
'*********************************************************************
Report_T: 'Ïîêàçâà òåìï. íà äàò÷èê íîìåð I
B1 = "T": B2 = I: B3 = Temp.HighByte: B4 = Temp.LowByte
GoSub Report_ANY
Return
'*********************************************************************
Report_R: 'Ïîêàçâà ñúñòîÿíèåòî íà ðåëå íîìåð I
B1="R":B2=I:B3=0:B4=Relays.0[I]
GoSub Report_ANY
Return
'*********************************************************************
Report_F: 'Ïîêàçâà ñúñòîÿíèåòî íà ðåëå íîìåð I
B1="F":B2=I:B3=0:B4=ForceR.0[I]
GoSub Report_ANY
Return
'*********************************************************************
Report_M: 'Ïîêàçâà ðåæèìà íà ðàáîòà
B1 = "M": B2 = Mode: B3 = 0: B4 = 0
GoSub Report_ANY
Return
'*********************************************************************
Report_L: 'Ïîêàçâà ðåæèìà íà ëàìïàòà
B1 = "L": B2 = Lamp: B3 = 0: B4 = 0
GoSub Report_ANY
Return
'*********************************************************************
Report_H: 'Ïîêàçâà Õèñòåðåçèñà
B1 = "H": B2 = 0: B3 = 0: B4 = Hist
GoSub Report_ANY
Return
'*********************************************************************
Report_N: 'Ïîêàçâà Night s Íîìåð I
TmpWord=Night[i]
B1 = "N": B2 = I: B3 = TmpWord.HighByte: B4 = TmpWord.LowByte
GoSub Report_ANY
Return
'*********************************************************************
Report_D: 'Ïîêàçâà Day ñ Íîìåð I
TmpWord=Day[i]
B1 = "D": B2 = I: B3 = TmpWord.HighByte: B4 = TmpWord.LowByte
GoSub Report_ANY
Return
'*********************************************************************
'Report_A: 'Ïîêàçâà àäðåñà íà äàò÷èê íîìåð I
' For I=1 to T_Count
' Gosub Read_Adr
' For K1=0 to 7
' Serout2 TX,Ser_Mode,[Hex2 Addrr[K1]," "]
' next K1
' Serout2 TX,Ser_Mode,[13,10]
' next i
'Return
'*********************************************************************
Read_Data:
Read 0, Mode: Read 1, Hist: Read 2, Lmp
'Read 4,Relays.LowByte:Read 5,Relays.HighByte
Read 6, ForceR.LowByte: Read 7, ForceR.HighByte
For k = 0 To 15 'T_Count
Read 170 + k * 2, TmpWord.LowByte
Read 171 + k * 2, TmpWord.HighByte
Day [k] = TmpWord
Read 210 + k * 2, TmpWord.LowByte
Read 211 + k * 2, TmpWord.HighByte
Night [k] = TmpWord
Next k
Return
'*********************************************************************
ON_OFF_R: 'Âêëþ÷âàíå/èçêëþ÷âàíå ðåëåòà
For k = 0 To T_Count
If forcer.0[k]=1 then 'Âêëþ÷åíî å ïðèíóäèòåëíî
If k = 0 Then high Rel1
If k = 1 Then high Rel2
Relays.0[K]=1 'Âêëþ÷âà ðåëå íîìåð Ê
Else 'Íå å âêëþ÷åíî ïðèíóäèòåëíî
if k=0 Then Rel1=Relays.0[0]
If K=1 Then Rel2=Relays.0[1]
End If
Next k
Return
'*********************************************************************
Write_M: 'Çàïèñâà Mode
Write 0,Mode
Return
'*********************************************************************
Write_L: 'Çàïèñâà Lamp
Write 2,Lamp
Return
'*********************************************************************
Write_N: 'Çàïèñâà Night ñ Íîìåð I
TmpWord=Night[I]
Write 210+I*2,tmpWord.LowByte
Write 211+I*2,TmpWord.HighByte
Return
'*********************************************************************
Write_D: 'Çàïèñâà Temp ñ íîìåð I
TmpWord=Day[i]
Write 170+i*2,TmpWord.LowByte:
Write 171+I*2,TmpWord.HighByte
Return
'*********************************************************************
Write_H: 'Çàïèñâà õèñòåðåçèñ
Write 1,HIst
Return
'*********************************************************************
Write_R: 'Çàïèñâà ñúñòîÿíèåòî íà ðåëåòàòà è ForcedR
' Write 4,Relays.LowByte:Write 5,Relays.HighByte
Write 6,ForceR.LowByte:Write 7,ForceR.HighByte
Return
'*********************************************************************
Report_B: 'Èçïðàùà áóôåðà, ïðèåò ïî RS232
Serout2 TX, Ser_Mode, ["W"]
For K=1 to LENB
Serout2 TX, Ser_Mode, [Buffer[K]]
Next k
Serout2 TX, Ser_Mode, [13,10]
Return
'*********************************************************************
Loop:
If Button1 = 0 Then 'Ñìÿíà Äåí/Íîù
Pause 100
If Button1 = 0 Then 'Debounce
If Mode = 0 Then
Mode = 1
Else
Mode = 0
End If
GoSub Report_M
GoSub Write_M
End If
End If
If Button2 = 0 Then 'Ïàëåíå/ãàñåíå íà ëàìïàòà
Pause 100
If Button2 = 0 Then 'Debounce
If Lamp = 0 Then
Lamp = 1
Else
Lamp = 0
End If
GoSub Report_L
GoSub Write_L
End If
End If
Char = 0: Serin2 RX, Ser_ModeRX, 125, Time, [WAIT("+"),Char]
If Char <> 0 Then 'Èç÷èòàíå íà áóôåðà
I=1:LenB=0
While I < MaxB
Serin2 RX, Ser_ModeRX, MaxRead, Clean_RX, [Char]
Buffer [I] = Char: Toggle Led
LenB=I
I = I + 1
Wend
Clean_RX:
Serin2 RX, Ser_ModeRX, MaxRead, Buffer_OK, [Char]
GoTo Clean_RX
Buffer_OK:
Char=Buffer[1]
If Char = "S" Then
GoSub Report_B
GoSub Report_S 'Èçïðàùàíå âñè÷êè íàñòðîéêè
Goto LOOP
End If
A2H=Buffer[2]:Gosub ASC2Hex:I=A2H
'Ïðåâðúùàíå â äåñåòè÷íî ÷èñëî íà ÕÕÕÕ îò áóôåðà
A2H=Buffer[4]:Gosub ASC2Hex:TmpWord=4096*A2H
A2H=Buffer[5]:Gosub ASC2Hex:TmpWord=TmpWord+256*A2H
A2H=Buffer[6]:Gosub ASC2Hex:TmpWord=TmpWord+16*A2H
A2H=Buffer[7]:Gosub ASC2Hex:TmpWord=TmpWord+A2H
If Char = "L" Then
Lamp = I: GoSub Report_L: GoSub Write_L ':Goto LOOP
End If
If Char = "M" Then
Mode = I: GoSub Report_M: GoSub Write_M ':Goto LOOP
End If
If Char = "H" Then
Hist = TmpWord: GoSub Report_H: GoSub Write_H ':Goto LOOP
End If
If Char = "D" Then
Day [I] = TmpWord: GoSub Report_D: GoSub Write_D ':Goto LOOP
End If
If Char = "N" Then
Night [I] = TmpWord: GoSub Report_N: GoSub Write_N ':Goto LOOP
End If
If Char = "F" Then
ForceR.0[I]=TmpWord:Relays.0[I]=TmpWord:Gosub ON_OFF_R:Gosub Report_R
GoSub Report_F: GoSub Write_R ':Goto LOOP
End If
GoSub Report_B 'Àêî å ïðèåòî íåùî äà ãî âúðíå çà ïðîâåðêà
End If 'Êðàé íà èç÷èòàíåòî
Time: 'Ïðîìÿíà âðåìå
Counter = Counter + 1
If Mode = 0 Then Toggle Led
If Counter >= 8 Then
Counter = 0: Seconds = Seconds + 1: Toggle Led
If Seconds >= RprtTime Then
Seconds = 0: GoTo ReadTemp
End If
End If
Goto LOOP
ReadTemp: '×åòåíå îò äàò÷èöè
OWOut DQ, 1, [$CC,$44]: Pause 800
For I = 0 To T_Count 'Îáõîæäàíå íà âñè÷êè äàò÷èöè
GoSub ReadROM: '×åòåíå àäðåñ íà I-òèÿ äàò÷èê
Comm=$BE:Gosub OW_Comm 'Ïîäãîòîâêà çà ÷åòåíå îò òîçè äàò÷èê
OWIn DQ, 2, [Temp.lowByte,Temp.HighByte]
Temp=(Temp>>1)*10 + Temp.0*5
'DEBUG
'serout2 TX,Ser_Mode,[#Temp,13,10]
GoSub Report_T
'------------------------------------------
If Mode = 0 Then 'Äíåâåí ðåæèì
If Temp<=(Day[I]-Hist) Then
If Relays.0[I]=0 Then 'Àêî å èçêëþ÷åíî
Relays.0[I]=1:Gosub ON_OFF_R:Gosub Report_R:
End If
End If 'Temp<=(Day[I]-Hist)
If Temp >=(Day[I]) Then
If Relays.0[I]=1 Then 'Àêî å âêëþ÷åíî
Relays.0[I]=0:Gosub ON_OFF_R:Gosub Report_R:
End If
End If 'Temp >=(Day[I])
End If ' Äíåâåí ðåæèì
If Mode = 1 Then 'Íîùåí ðåæèì
If Temp<=(Night[I]-Hist) Then
If Relays.0[I]=0 Then 'Àêî å èçêëþ÷åíî
Relays.0[I]=1:Gosub ON_OFF_R:Gosub Report_R:
End If
End If 'Temp<=(Night[I]-Hist)
If Temp >=(Night[I]) Then
If Relays.0[I]=1 Then 'Àêî å âêëþ÷åíî
Relays.0[I]=0:Gosub ON_OFF_R:Gosub Report_R:
End If
End If 'Temp >=(Night[I])
End If ' Íîùåí ðåæèì
Next I
Goto LOOP