PDA

View Full Version : DS18B20 thermostat



snuff28
- 17th April 2013, 00:13
I have been racking my brains trying to get a output to go high if the temp falls below a certian degree but just cant quite figure it out. I am using a modified version of Bruces DS18B20 code that I found on here (Sorry I forgot who it came from, was a while ago I found it) and heres what I have:


Start:
sensor= TEMPSENSOR ' i have 5 DS18B20
GOSUB GetID 'go look up each sensors address
ID[hexbyte]=col 'load the ID array with the retrieved address byte
NEXT hexbyte ' get the rest of the address bytes
OWOUT DQ, 1, [$55,STR ID\8,$44] 'match[$55] this[ID] rom code and
'initiates[$44] temperature conversion on matching sensor
CkAgn:
OWIN DQ, 4, [Busy] ' Check for still busy converting
IF Busy = 0 THEN CkAgn ' Still busy?, then loop
OWOUT DQ,1,[$55,STR ID\8,$BE] 'instructs sensors to match[$55] this[ID] and start sending back scratchpad[$BE]
OWIN DQ, 2, [Raw.LOWBYTE,Raw.HIGHBYTE] ' Read two temperature bytes, then end communications
Dummy = 1125 * Raw
TempF = DIV32 100
MTtemp = TempF
MTtemp = (MTtemp + 3200) + tankoffset
SEROUT2 TX, 84, [DEC MTtemp DIG 3,DEC MTtemp DIG 2,".",DEC2 MTtemp,$DF,"F"]
return


I want to be able to take the MTtemp and compare it to a number like 78 (78 is the var for "setpoint" var Byte)
I have tried along with tons of other ways to get it to work, but basically what I am trying to do is:


MTtemp >>4
if MTtemp <= setpoint then
high heater
else
low heater
endif


There are so many ways I have tried this, just need a little push in the right direction...
Thanks!

Ioannis
- 17th April 2013, 07:16
Can you post all your code?

I see that you have a NEXT command inside a subroutine. Where is FOR?

Also, are you getting good results from your serial output?

Ioannis

snuff28
- 17th April 2013, 13:16
I am getting good results from the serial output, the temperature displayed is within .5*F of the actual temperature. The VAR "tankoffset" allows me to adjust the tenths of a degree so I can dial it in to within .1*F, seems to work pretty good.
There is a look up for each DS18B20 (there are 5 total) that loads each byte of the address for the DS18B20 that is selected.

I will post the whole code when I get home today. But I don’t have any good code to work with for turning the heater on; it either turns on the heater all the time or not at all. There was one time that it cycled the heater on and off but at the wrong temperature, but in my frenzy to get this working I can’t remember what that was.

Thanks

snuff28
- 17th April 2013, 23:25
Here is the code:


Busy VAR BIT ' Busy Status-Bit
Raw VAR WORD ' RAW Temperature readings
TempF VAR WORD ' Temp in deg F
Dummy VAR BYTE ' Dummy for Div32
ID VAR BYTE[8] ' Array storage variable for 64-bit ROM code
sensor VAR BYTE
hexbyte VAR byte
col VAR BYTE
TankOffSet var byte

;*** MAIN TANK TEMP********************************************** ************

ReadTankTemp:
TEMPSENSOR = 1
GOSUB Begin
MTtemp = TempF
RETURN

;************************************************* *************************


Begin:
sensor= TEMPSENSOR 'I am reading 5 DS18b20 sensors...
FOR hexbyte=0 TO 7 'each sensor address is 8 bytes
GOSUB GetID 'go look up each sensors address
ID[hexbyte]=col 'load the ID array with the retrieved address byte
NEXT hexbyte 'go get the rest of the address bytes

OWOUT DQ, 1, [$55,STR ID\8,$44] 'instructs sensors to match[$55] this[ID] rom code and
'initiates[$44] temperature conversion on matching sensor
CkAgn:
OWIN DQ, 4, [Busy] ' Check for still busy converting
IF Busy = 0 THEN CkAgn ' Still busy?, then loop
OWOUT DQ,1,[$55,STR ID\8,$BE] 'instructs sensors to match[$55] this[ID] and start sending back scratchpad[$BE]
OWIN DQ, 2, [Raw.LOWBYTE,Raw.HIGHBYTE]' Read two temperature bytes, then end communications
; Dummy = 1125 * Raw
; TempF = DIV32 100
RETURN

GetID:
SELECT CASE sensor
CASE 1 :LOOKUP hexbyte,[$28,$A0,$44,$EA,$03,$00,$00,$02], col 'MAIN TANK SENSOR
CASE 2 :LOOKUP hexbyte,[$28,$2F,$44,$EA,$03,$00,$00,$CC], col 'SUMP TANK SENSOR
CASE 3 :LOOKUP hexbyte,[$28,$D4,$17,$EA,$03,$00,$00,$9D], col 'SALT RES TEMP
CASE 4 :LOOKUP hexbyte,[$28,$96,$35,$EA,$03,$00,$00,$FD], col '?? TEMP
CASE 5 :LOOKUP hexbyte,[$28,$45,$F8,$24,$03,$00,$00,$82], col 'AMBIANT AIR TEMP
END SELECT
RETURN


And to display the temperature on the LCD:


SEROUT TX, T9600,["TANK TEMP"]
GOSUB ReadTankTemp
SEROUT TX, T9600,[$FE, $0C, 2,12] ; SET CURSOR TO ROW2 COL12
MTtemp = (MTtemp + 3200) + tankoffset
SEROUT2 TX, 84, [DEC MTtemp DIG 3,DEC MTtemp DIG 2,".",DEC2 MTtemp,$DF,"F"]

Ioannis
- 18th April 2013, 07:17
Could you please make a test for me?

Inside the test code part, put a Serout command to monitor the two values MTemp and setpoint

[code]
MTtemp >>4
if MTtemp <= setpoint then
high heater
else
low heater
endif
Serout TX, T9600,[dec MTemp, dec setpoint] 'Please put at the preffered place on your LCD
[code]

Ioannis

falingtrea
- 18th April 2013, 18:56
Are you comparing the temp sensor output data to the value "78" or "780"? If I understand the data format of the temp sensor read code, the data is (temperature * 10) so that you have a resolution of 0.1 deg. Which means 78.0 degrees is 780 decimal returned by the temp sensor read code.

Also in your compare code you are right shifting the temp sensor reading by 4 which is like dividing by 16. This changes the decimal value 780 to 48 which is not what I think you wanted to do. You need to actually divide the temp sensor data by 10 decimal, and then compare. Or multiply the test value by 10 and then compare.

I think what is confusing you is the DEC function. The DEC take a value and returns the specified decimal digit. Kind of like this: [value / (10 ^ n) ] // 10.

snuff28
- 19th April 2013, 00:19
You are absolutely right falingtrea, I just figured that out. Several things I was doing wrong and will explain later, but right now I am taking my wife out to dinner.
Thanks!

snuff28
- 19th April 2013, 13:52
Ok, many many things I did wrong here. First was that I was trying to shift it >>4 to get the number in the lowbyte then trying to compare. Now the code is:


MTtemp = (MTtemp + 3200)
IF MTtemp/100 <= HeaterSetTemp THEN
HIGH MainHeater
ELSE
LOW MainHeater
ENDIF

I figured since I was trying to compare a word (data from DS18B20) to a byte (HeaterSetTemp) that I should shift the data >>4 and put it in the lowbyte then compare, but since I'm not working with a negative tempature reading I guess it doesn't really matter since all the leading bites are all zeros. The values displayed on the LCD was let’s say: MTtemp=6610 which is 66.10*F. I divided by10 to get rid of the .10 then compaired to 78 (HeaterSetTemp). Works perfect! The other problem was... it seems that I forgot to set the HeaterSetTemp variable to point to anything, so the HeaterSetTemp that was displayed was 146. I don't know where that came from since after looking at the code the HeaterSetTemp var was not pointed to anything, I would think it should have showed "0". For testing I did:


HeaterSetTemp = 78

I thank you to both Ioannis and falingtrea for forcing me to display the data to see what I was dealing with. I should have done that in the first place and I knew that, but I guess I was looking for and easy fix, as a manager for a team of technicians I am huge on proper diagnosing and preach it all the time... but I failed to follow my own words this time.

Ioannis
- 19th April 2013, 14:19
No problem. Glad you did solve it.

Ioannis