PDA

View Full Version : Thermostat for refrigerator



fratello
- 6th August 2012, 15:18
I wrote code for thermostat, with settings of lower und upper threshold...Work fine, but I can not settings those thresholds under 0.0 'C :( . Under "0.0 'C" (in settings menu, for temp_up & temp_down) on display I have "+655 'C" and minus-button decrease this value ...
Please, can give someone a hand of help ?! Thanks in advance !

'* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
@ DEVICE pic16F628A, intOSC_osc_noclkout, WDT_OFF, PWRT_OFF, BOD_OFF, MCLR_ON
define osc 4
INTCON = 0
include "D:\pbp\alldigital.pbp"

PORTA.7 = 0
TRISA= %00100000
TRISB= %00001111
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 0 ' RS on A1
DEFINE LCD_EREG PORTA ' E on PORTA
DEFINE LCD_EBIT 1 ' E on A0
DEFINE LCD_BITS 4 ' LCD 4 bit mode
DEFINE LCD_LINES 2 ' 2 line LCD display
Define LCD_COMMANDUS 2000 ' Command Delay (uS)
Define LCD_DATAUS 50 ' Data Delay (uS)


Temperature Var Word ' Temperature storage
TempC Var Word
Float Var Word
V Var Word ' Var. for display
Sign Var Byte ' +/- sign
DQ Var PORTb.3
Twist Var Bit
Dummy Var Byte
Delay var byte
Mode VAR BYTE
DS18B20_12bit CON %00111111 ' 0,25°C
AlarmUp VAR BIT
AlarmDn VAR BIT

B1 Var Byte ' Byte for Temp_Up calculation
B2 Var Byte ' Byte for Temp_Up calculation
B3 Var Byte
B4 Var Byte
Temp_Up Var Word
Temp_Down Var Word

Read 0, B1 ' Read Temp_Up MSB
Read 1, B2 ' Read Temp_Up LSB
Temp_Up=B1*256+B2 ' Calculate Temp_Up value

Read 2, B3
Read 3, B4
Temp_Down= B3*256+B4 ' Calculate Temp_Down value

PORTA.7 = 0
PORTA.2 = 0 ' Warm Output Low
PORTA.3 = 0 ' Cold Output Low
Mode = 0 ' Temperature display mode


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

' Init Sensor
OWOUT DQ, 1, [$CC, $4E, 0, 0, DS18B20_12bit]
OWOut DQ, 1, [$CC, $48] ' Start temperature conversion
OWOut DQ, 1, [$CC, $B8]
OWOut DQ, 1, [$CC, $BE]
Pause 50
OWIn DQ, 2, [Temperature.Lowbyte, Temperature.Highbyte]
Pause 50


MainLoop:
If PORTB.0=0 then ' Mode switch pressed
Pause 50 ' Debounce
If PORTB.0=0 then MainLoop ' Wait until button is released
Mode=Mode+1 ' Increment mode
ENDIF


If Mode=2 then ' SET Temp_Up
LcdOut $FE, $80, " TEMP_UP : "
LcdOut $FE, $C0, " ", Sign, DEC (Temp_Up / 100), 223,"C "
if portb.1=0 then
Temp_Up=Temp_Up + 100
Gosub Debounce
endif

if portb.2=0 then
Temp_up=Temp_up - 100
Gosub Debounce
endif
EndIf

If Mode=1 then ' SET Temp_Down
LcdOut $FE, $80, " TEMP_DOWN : "
LcdOut $FE, $C0, " ", Sign, DEC (Temp_Down / 100), 223,"C "
if portb.1=0 then
Temp_Down=Temp_Down + 100
Gosub Debounce
endif

if portb.2=0 then
Temp_Down=Temp_Down - 100
Gosub Debounce
endif
EndIf

If Mode > 2 then
LCDOUT $FE, 1, $FE, $0C
LCDOUT $FE, $C0, "END SETTING"
PAUSE 1000
LCDOUT $FE, 1, $FE, $0C
Write 0, Temp_Up / 256 ' TargetTemp MSB
Pause 50
Write 1, Temp_Up MOD 256 ' TargetTemp LSB
Pause 50

Write 2, Temp_Down / 256
Pause 50
Write 3, Temp_Down MOD 256
Pause 50
mode=0
EndIf

If Mode > 0 then Mainloop


Main :
PORTA.7 = 0
if portb.0=0 then Gosub MainLoop

OWOut DQ, 1, [$CC, $44]
Pause 760
WaitLoop:
While not DQ
Wend

OWOut DQ, 1, [$CC, $BE]
OWIn DQ, 2, [Temperature.Lowbyte, Temperature.Highbyte]

Convert_Temp:

If Temperature.15 then
Temperature= ~Temperature +1
Twist = 1
Endif

Dummy = 625 * Temperature
TempC = DIV32 10
TempC = (Temperature & $7FF) >> 4
Float = ((Temperature.Lowbyte & $0F ) * 25 )>>2
Temperature = TempC*100 + Float

If Twist then
V= 10000 - Temperature ' 25 C=12500 0 C=10000 -10 C=9000
Twist = 0
else
V= 10000 + Temperature
EndIf
GoSub SelectSign ' +/blank/- Sign
GoSub DisplayTemp ' Temperature to LCD
Gosub Checking
Goto Main

' 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
Return

'====================================
DisplayTemp:
If V >= 10000 then ' Above 0 C.
Temperature=V-10000
Else
Temperature=10000-V ' Below 0 C.
EndIf
LcdOut $FE, $80, "TEMP : ", Sign," ", DEC (Temperature / 100), ".", DEC1 Temperature dig 1 , 223,"C "
LcdOut $FE, $C0, "DN:",Sign, DEC (Temp_Down / 100), 223, " UP:", Sign, DEC (Temp_Up / 100), 223
Return
'====================================
Checking:
If temperature < Temp_Down then ' Below Target temperature - Hysteresis
PORTA.2=1 ' Activate Warm Output
if AlarmDn = 0 then
sound porta.7, [80, 150]
low porta.7
alarmDn = 1
endif
else
alarmDn = 0
Porta.2 = 0
EndIf

If Temperature > Temp_Up then ' Above Target temperature + Hysteresis
PORTA.3=1 ' Activate Cold Output
if AlarmUp = 0 then
sound porta.7, [110, 150]
low porta.7
alarmUp = 1
endif
else
alarmUp = 0
porta.3 = 0
EndIf
Return
'====================================
Debounce :
For Delay= 1 to 200
Pause 1
next Delay
Return
'===================================
END ' Of program

HenrikOlsson
- 7th August 2012, 07:45
Hi,
Normally PBP doesn't handle signed values very well, 1-2=255 so that's probably where the problem is comming from. If you're only displaying values then you can use the SDEC modifier in LCDOUT etc statements, it will give you -1 for the above example. This is only for display purposes though, the actual math operations are still treated as unsigned.

What to do. Well, you could switch to LONG variables - these are signed. Or you can apply an offset to all your values so that instead of the value 0 meaning 0 degrees you say that 10000 means 0 degrees. 10001 is 0.1 degrees and 9999 is -0.1 degrees - for example.

I haven't looked very cloesly at your actual code in order to say which would be best.

/Henrik.

fratello
- 8th August 2012, 22:58
Thanks for reply ! As usual, I know You are right, but ...
I trying different variants (applying an offset, like v=10000 + temp_up) ...still no results. I will keep trying ...harder !