PDA

View Full Version : Conversion problem



eva
- 28th February 2004, 09:19
I'm trying to make a differential thermostat for a solar water heating system, with a 16f876
and two DS1820 connected to 2 different pins of the pic. I started using as a base the onewire.bas
in the examples. Every thing was fine until, from a default fixed (7deg) temperature difference
between the 2 sensors I tried to have a variable one, say from 7 to 20 degrees, using a button.
It works but I get strange symbols displayed instead of the set temperature difference: hard
to memorize to say the least. Surely there must be a conversion problem that I do not
understand. Can anybody help me solving the problem? Any other suggestion will be very much
appreciated.
***
' Differential thermostat


temperature VAR WORD ' Temperature storage
count_remain VAR BYTE ' Count remaining
count_per_c VAR BYTE ' Count per degree C
temperapanel VAR WORD ' Panel temperature storage
count_rempan VAR BYTE
count_per_cpan VAR BYTE
DQ VAR PORTA.4 ' One-wire data pin for tank
DP VAR PORTA.5 ' One-wire data pin for panel*
delta VAR WORD ' Delta T° btwn Panel & Tank to start pump

' Define LCD registers and bits
DEFINE LCD_DREG PORTB

DEFINE LCD_DBIT 4
DEFINE LCD_RSREG PORTA

DEFINE LCD_RSBIT 2

DEFINE LCD_EREG PORTA

DEFINE LCD_EBIT 1

DEFINE LCD_BITS 4

DEFINE LCD_LINES 2

DEFINE LCD_COMMANDUS 2000

DEFINE LCD_DATAUS 50


ADCON1 = 7 ' Set PORTA and PORTE to digital
LCDOut $fe, 1, "Diff. Thermostat"

Pause 3000
delta = 700 ' DEFAULT T° DIFFERENCE AT WHICH PUMP STARTS

mainloop: IF PORTA.3 = 0 Then pressed ' CHECK IF TEMPERATURE DIFFERENCE
' BUTTON IS PRESSED

OWOut DQ, 1, [$CC, $44] ' Start temperature conversion

waitloop: OWIn DQ, 4, [count_remain] ' Check for still busy converting
IF count_remain = 0 Then waitloop

OWOut DQ, 1, [$CC, $BE] ' Read the temperature
OWIn DQ, 0, [temperature.LOWBYTE, temperature.HIGHBYTE, Skip 4, count_remain, count_per_c]

' Calculate temperature in degrees C to 2 decimal places (not valid for negative temperature)
temperature = (((temperature >> 1) * 100) - 25) + (((count_per_c - count_remain) * 100) / count_per_c)
LCDOut $fe, 1, DEC (temperature / 100), ".", DEC1 temperature, "C Tank"


OWOut DP, 1, [$CC, $44] ' Start temperature conversion
waitloop2: OWIn DP, 4, [count_rempan] ' Check for still busy converting
IF count_rempan = 0 Then waitloop2

OWOut DP, 1, [$CC, $BE] ' Read the temperature
OWIn DP, 0, [temperapanel.LOWBYTE, temperapanel.HIGHBYTE, Skip 4, count_rempan, count_per_cpan]

' Calculate temperature in degrees C to 2 decimal places (not valid for negative temperature)
temperapanel = (((temperapanel >> 1) * 100) - 25) + (((count_per_cpan - count_rempan) * 100) / count_per_cpan)
LCDOut $fe, $c0, DEC (temperapanel / 100), ".", DEC1 temperapanel, "C Panel"

Pause 3000 ' Display about once every 3 seconds

IF temperapanel < 1800 Then mainloop 'Less than 18°C? Pump stays off

IF temperapanel > (temperature + delta) Then 'Checks T diff. for the pump to start (default 7°C)

High PORTC.4 'Start pump
EndIF
IF PORTC.4 Then 'Check for PORTC pin 4 high
LCDOut $fe,$c0+4, " h2o PUMPING" 'It's high so pump is on
EndIF
IF temperapanel < (temperature +300) Then 'Checks if T difference < 3°C
Low PORTC.4 'Stop pump
EndIF
Pause 3000 ' Refresh time =~3 seconds
GoTo mainloop ' Do it forever
End


pressed: Pause 30 'debounce
IF PORTA.3 = 0 Then setdelta 'IF STILL PRESSED GO TO SETDELTA
setdelta: For delta = 700 TO 2000 STEP 100 ' STEP SIZE 1°C
LCDOut $fe, 1, "Delta ", delta 'CLEAR LCD AND DISPLAY DELTA VALUE
Pause 3000
IF PORTA.3 = 1 Then mainloop 'if not pressed go to mainloop
Next delta
GoTo setdelta

Melanie
- 28th February 2004, 21:32
I can see a number of defects in your code. In the subroutine 'Pressed:'... herein you have some ambiguous statements... the first is...

IF PORTA.3 = 0 Then setdelta

Since the next line is SETDELTA anyway, it seems a little pointless.

The next problem is your use of the pressed subroutine. You adjust the variable DELTA from 700 to 2000 (7 to 20 Celsius) in steps of 100 with a delay of three seconds between them… 13 steps x 3 seconds means the user waits 39 seconds… a little long I would have thought.

Then (this is your main problem) you are displaying the raw value of Delta with…

LCDOut $fe, 1, "Delta ", delta

Whereas you should have displayed…

#delta

The # symbol makes all the difference…

And the routine always sets Delta to 700 and counts up, wouldn't it be better to adjust from the last value of Delta and roll back to 700 once 2000 has been exceeded?

So, may I suggest the code is changed perhaps to something like...

. . .

PortA.3 var PressButton ‘ Define adjustment Button

. . .

Pressed:
LCDOut $FE,1,"Delta : ",#Delta
Pause 3000 ' Wait 3 seconds
PressedLoop:
If PressButton=1 then goto Mainloop
Delta=Delta+100
If Delta>2000 then Delta=700
LCDOut $FE,$88,#Delta," "
Pause 1000
Goto PressedLoop

Here we wait 3 seconds displaying the current value of Delta, thereafter if the button is still pressed we advance the value of Delta at a 1 second rate. Finally, NOT clearing the display, but simply overwriting the previous displayed value prevents the annoying flicker on the LCD.

Melanie

eva
- 29th February 2004, 18:00
Thank you very much Melanie,
your solution and suggestion have been
put succesfully at work!
Eva

pasicr
- 15th March 2007, 16:26
Hi,
I am new in this forum, and I have question abouth this:
You replay massage to EVA with comment about errors on his software (differential thermostat for a solar water heating system using a 16f876 and two DS1820),
I send post to EVA but no replay,
can you help me with this,
On Eva post is attached *.bas file. I need hex file but I do not have converter to do this,
can you please do this for me.
*.bas to hex for pic16f876)

paul borgmeier
- 15th March 2007, 19:21
Again, try
http://compilespot.com/
for your hex code