You are on page 1of 6

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

'* Universal thermostat -25/+75 C. by R.T.G. van Steenis *


'* Digital thermostat (080090-11) from Elektor july_august 2008 *
'* Compiler : PicBasic Pro 2.44 *
'* B0 = Mode switch in (In) A0 = LCD Enable (Out) *
'* B1 = + switch in (In) A1 = LCD RS (Out) *
'* B2 = - switch in (In) A2 = "Warm" Output (Out) *
'* B3 = Not connected (Out) A3 = "Cold" Output (Out) *
'* B4 = LCD Bit 4 (Out) A4 = DQ DS1820 (In) *
'* B5 = LCD Bit 5 (Out) *
'* B6 = LCD Bit 6 (Out) *
'* B7 = LCD Bit 7 (Out *
'* *
'* modify by Niculescu Dan *
'* *
'* DUAL THERMO 2xDS18B20 ; PIC 16F628A ; LCD 2x16 *
'* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *

TRISA= %11110000 ' RA0..3=Outputs RA4=Input


TRISB= %00000111 ' RB0..RB2=Inputs, RB3..RB7=Outputs
CMCON=7 ' Disable comparators

DEFINE LCD_DREG PORTB ' LCD on port B


DEFINE LCD_DBIT 4 ' Data bits B4..B7
DEFINE LCD_RSREG PORTA ' RS on PORTA
DEFINE LCD_RSBIT 1 ' RS on A1
DEFINE LCD_EREG PORTA ' E on PORTA
DEFINE LCD_EBIT 0 ' E on A0
DEFINE LCD_BITS 4 ' LCD 4 bit mode
DEFINE LCD_LINES 2 ' 2 line LCD display

Temperature1 Var Word ' Temperature storage Sensor1


Temperature2 Var Word ' Temperature storage Sensor2
TempC Var Word
Float Var Word
TargetTemp Var Word ' Desired Temperature
Hyst Var Word ' Hystereris
V Var Word ' Var. for display
V2 Var Word ' Var. for display
B1 Var Byte ' Byte for TargetTemp calculation
B2 Var Byte ' Byte for TargetTemp calculation
Sign Var Byte ' +/- sign
Mode Var Byte ' 0=Temp. display, 1=Set Temp, 2=Set Hysteresis
DQ Var PORTA.4 ' One-wire data pin
Twist Var Bit
Twist2 Var Bit
Dummy Var Byte

DS18B20_9bit CON %00011111 ; 93.75ms, 0.5C


DS18B20_10bit CON %00111111 ; 187.5ms, 0.25C
DS18B20_11bit CON %01011111 ; 375ms, 0.125C
DS18B20_12bit CON %01111111 ; 750ms, 0.0625C (default)
DS18B20_1_12bit CON %01111111 ; 750ms, 0.0625C
DS18B20_2_12bit CON %01111111 ; 750ms, 0.0625C

DATA 46, 224, 20 ' Temp MSB, TEMP LSB, Hysteresis DIV 10

PORTA.2=0 ' Warm Output Low


PORTA.3=0 ' Cold Output Low
Mode=0 ' Temperature display mode
Twist = 0
Twist2 = 0

Pause 500
LCDOUT $FE, 1, $FE, $0C ' Clear display, cursor off
Pause 250

Read 0, B1 ' Read TargetTemp MSB


Read 1, B2 ' Read TargetTemp LSB
TargetTemp=B1*256+B2 ' Calculate TargetTemp value (Default=20.0
C.)
Read 2, B1 ' Read Hysteresis
Hyst=10*B1 ' Calculate Hysteresis value (Default= 2.0
C.)

OWOut DQ, 1, [$55, $28, $DD, $06, $49, $1, $0, $0, $D4, $4E, $FF, $FF, $7F] '
Init Sensor 1
OWOut DQ, 1, [$55, $28, $DD, $06, $49, $1, $0, $0, $D4, $48]
OWOut DQ, 1, [$55, $28, $DD, $06, $49, $1, $0, $0, $D4, $B8]
OWOut DQ, 1, [$55, $28, $DD, $06, $49, $1, $0, $0, $D4, $BE]
Pause 1000
OWIn DQ, 0, [Temperature1.Byte0, Temperature2.Byte1]
LcdOut $FE, $80, "Senzor1 INIT OK"
Pause 500

OWOut DQ, 1, [$55, $28, $EB, $EA, $48, $1, $0, $0, $FF, $4E, $FF, $FF, $7F] '
Init Sensor 2
OWOut DQ, 1, [$55, $28, $EB, $EA, $48, $1, $0, $0, $FF, $48]
OWOut DQ, 1, [$55, $28, $EB, $EA, $48, $1, $0, $0, $FF, $B8]
OWOut DQ, 1, [$55, $28, $EB, $EA, $48, $1, $0, $0, $FF, $BE]
Pause 1000
OWIn DQ, 0, [Temperature2.Byte0, Temperature2.Byte1]
LcdOut $FE, $C0, "Senzor2 INIT OK"
Pause 1000

MainLoop:
If PORTB.0=0 then ' Mode switch pressed
Pause 50 ' Debounce
LcdOut $FE, 1
LcdOut $FE, $8F, "*" ' Show that command is accepted
If PORTB.0=0 then MainLoop ' Wait until button is released
Mode=Mode+1 ' Increment mode
If Mode=2 then ' Save Target Temperature (Mode1 -> Mode2)
Write 0, TargetTemp / 256 ' TargetTemp MSB
Write 1, TargetTemp MOD 256 ' TargetTemp LSB
EndIf
If Mode > 2 Then ' Save Hysteresis (Mode 2 -> Mode 0)
Mode=0 ' Only 0, 1, 2 are valid
Write 2, Hyst / 10 ' Divide Hyst value to fit in Byte
EndIf
EndIf

If Mode =1 then
LcdOut $FE, $80, "SET TEMPERATURE " ' Show function
V=TargetTemp ' TargetTemp in V
Gosub SelectSign ' Select +/blank/-
Gosub DTemp ' Display Target Temperature
If (PORTB.1=0) Or (PORTB.2=0) then ' Up or Down button pushed
If PORTB.2=0 then ' Down button
If TargetTemp > 7500 then ' Not lower than -25 C. (10000-MinTemp *
100)
TargetTemp=TargetTemp-25 ' Decrease temperuture with 0.25 C.
EndIf
EndIf
If PORTB.1=0 then ' Up button
If TargetTemp < 17500 then ' Not higher than 75 C. (10000+MaxTemp *
100)
TargetTemp=TargetTemp+25 ' Increase temperature with 0.25 C.
EndIf
EndIf
GoSub SetTargetTemp ' Display TargetTemp and delay 0.25 Sec.
EndIf
EndIf

If Mode=2 then ' Set Hysteresis


LcdOut $FE, $80, "SET HYSTERESIS " ' Show function
Sign=" " ' No sign
V= 10000+Hyst ' Set value for V
Gosub DTemp ' Display Hysteresis
If (PORTB.1=0) Or (PORTB.2=0) then ' Up or down button pushed
Sign=" " ' No sign for Hysteresis
If PORTB.2=0 then ' Down button
If Hyst > 10 then Hyst=Hyst-10 ' Not less than 0.1 C.
EndIf
If PORTB.1=0 then ' Up button
If Hyst < 1000 then Hyst=Hyst+10 ' Not more than 10.0 C.
EndIf
V= 10000+Hyst ' Set value for V
Gosub DTemp ' Display Hysteresis
Pause 250 ' Delay 0.25 Sec.
EndIf
EndIf

If Mode > 0 then Mainloop ' Setting TargetTemperature or Hysteresis

Output DQ ' Make Pin Output


DQ=0 ' OneWire line Low
PauseUs 480 ' Keep down for 480 S
Input DQ ' Make Pin Input
PauseUs 70 ' Wait 70 S
If DQ=1 then ' No presence pulse from DS1820
LcdOut $FE, $1, "** No sensor! **" ' Show message
Pause 500 ' Wait 0.5 Sec.
Goto MainLoop ' Check again
EndIf

'==================================================================================
=================

Main :
Part1:
OWOut DQ, 1, [$55, $28, $DD, $06, $49, $1, $0, $0, $D4, $44] ' Start temp.
conversion Sensor1
WaitLoop:
While not DQ
Wend

OWOut DQ, 1, [$55, $28, $DD, $06, $49, $1, $0, $0, $D4, $BE]
Pause 500
OWIn DQ, 0, [Temperature1.Byte0, Temperature1.Byte1]
If Temperature1.15 then
Temperature1= ~Temperature1 +1
Twist = 1
Endif

Dummy = 625 * Temperature1


TempC = DIV32 10
TempC = (Temperature1 & $7FF) >> 4
Float = ((Temperature1.Lowbyte & $0F ) * 25 )>>2
Temperature1 = TempC*100 + Float
If Twist then
V= 10000 - Temperature1 ' 25 C=12500 0 C=10000 -10 C=9000
Twist = 0
else
V= 10000 + Temperature1
EndIf
If V >= 10000 then ' Above 0 C.
Temperature1=V-10000
Else
Temperature1=10000-V ' Below 0 C.
EndIf
GoSub SelectSign ' +/blank/- Sign
GoSub DisplayTemp ' Temperature to LCD

'==================================================================================
=================
Part2 :
OWOut DQ, 1, [$55, $28, $EB, $EA, $48, $1, $0, $0, $FF, $44] ' Start temp.
conversion Sensor2

WaitLoop2:
While not DQ
Wend

OWOut DQ, 1, [$55, $28, $EB, $EA, $48, $1, $0, $0, $FF, $BE]
Pause 500
OWIn DQ, 0, [Temperature2.Byte0, Temperature2.Byte1]
If Temperature2.15 then
Temperature2= ~Temperature2 +1
Twist2 = 1
Endif

Dummy = 625 * Temperature2


TempC = DIV32 10
TempC = (Temperature2 & $7FF) >> 4
Float = ((Temperature2.Lowbyte & $0F ) * 25 )>>2
Temperature2 = TempC*100 + Float
If Twist2 then
V2= 10000 - Temperature2 ' 25 C=12500 0 C=10000 -10 C=9000
Twist2 = 0
else
V2= 10000 + Temperature2
EndIf
If V2 >= 10000 then ' Above 0 C.
Temperature2=V2-10000
Else
Temperature2=10000-V2 ' Below 0 C.
EndIf

GoSub SelectSign ' +/blank/- Sign


GoSub DisplayTemp ' Temperature to LCD

Goto MainLoop ' Do it forever

' SUBROUTINES:
'==================================================================================
=================
SelectSign:
If v = 10000 then ' Temperature = 0 C.
Sign=" " ' No sign
Else
If v < 10000 then ' <> 0
Sign="-" ' Temperature below 0 C.
Else
Sign="+" ' Temperature above 0 C.
EndIf
EndIf

If v2 = 10000 then ' Temperature = 0 C.


Sign=" " ' No sign
Else
If v2 < 10000 then ' <> 0
Sign="-" ' Temperature below 0 C.
Else
Sign="+" ' Temperature above 0 C.
EndIf
EndIf

Return

'==================================================================================
=================
DisplayTemp:
If V >= 10000 then ' Above 0 C.
Temperature1=V-10000
Else
Temperature1=10000-V ' Below 0 C.
EndIf

If V2 >= 10000 then ' Above 0 C.


Temperature2=V2-10000
Else
Temperature2=10000-V2 ' Below 0 C.
EndIf

LcdOut $FE, $80, "INT : ", Sign," ", DEC (Temperature1 / 100), ".", DEC2
Temperature1, " ",223,"C "
LcdOut $FE, $C0, "EXT : ", Sign," ", DEC (Temperature2 / 100), ".", DEC2
Temperature2, " ",223,"C "
Return

'==================================================================================
=================
SetTargetTemp:
V=TargetTemp
Gosub SelectSign
Gosub DTemp
Pause 250
Return
'==================================================================================
=================
DTemp :
If V >= 10000 then ' Above 0 C.
Temperature1=V-10000
Else
Temperature1=10000-V ' Below 0 C.
EndIf
LcdOut $FE, $C0, Sign," ", DEC (Temperature1 / 100), ".", DEC2 Temperature1, "
",223,"C "
Return

'============================================= END OF PROGRAM


======================================

You might also like