Temperature Min / Max logging

russbow

Senior Member
I have a unit that records minimum and maximum temperatures measured over a period since "last reset"

The setup is :-

18m2 picaxe, LCD on pin b.3, DS18B20 sensor on pin b.7, reset button on pin c.0

All works well until the temperature goes below zero. Here is the code.

Code:
'18m2 Min/Max with reset
'Working 06/12/12
'16x2 OLED

#picaxe18M2

#No_Data

init:
symbol MINTEMP = b1
symbol MAXTEMP = b2
symbol NOWTEMP = b4


symbol LCD= b.3
symbol DEG= c.7
symbol WIPEIT= pinc.0

high c.1
serout LCD,N2400,(254,1,254,1) 'clear screen
pause 200

''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''

Main:

if WIPEIT=0 then gosub wipe    ' Reset values to zero

gosub timeit  'Get current time

gosub disp1

ReadTemp DEG, NOWTEMP
 Read 0, MINTEMP
 Read 1, MAXTEMP
 Read 2,b5:Read 3,b6:read 4,b7
 Read 5,b8:read 6,b9:read 7,b10
 
 If MINTEMP = 0 And MAXTEMP = 0 Then
   MINTEMP = 255
 End If
 
 If NOWTEMP < MINTEMP Then
   MINTEMP = NOWTEMP
   Write 0, MINTEMP
 End If
 
 If NOWTEMP > MAXTEMP Then
   MAXTEMP = NOWTEMP
   Write 1, MAXTEMP
 End If 
 
 
gosub check	'check for neg values & display



goto main   ' Doit again

''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' 
 timeit:

i2cslave %11010000, i2cslow, i2cbyte
	readi2c 0,(b0,b1,b2,b3,b4,b5,b6)
	
	pause 50

	b11=b2/16	 'hour MSD
	b12=b2 & $0F 'hour LSD
	b7=b1/16	 'min  MSD
	b8=b1 & $0F  'min  LSD
	b9=b4/16	 'day MSD
	b10=b4 & $0F 'day LSD
	b2=b5/16
	b3=b5 & $0F
	b0=b6/16:b4=b6 & $0F
	
return

''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''

check:

	if NOWTEMP > 127 then neg2
	serout LCD,N2400,(254,192,"Temp ",#NOWTEMP,$df,"C ")
	pause 5000
	serout LCD,N2400,(254,128,"                ")
	
goto checkmin

neg2:

	let NOWTEMP = NOWTEMP - 128 ‘ adjust neg value
	serout LCD,N2400,(254,128,"Temp -",#NOWTEMP,$df)
 
checkmin:

	if MINTEMP > 127 then neg3  'test negative
	serout LCD,N2400,(254,128,"Lo ",#MINTEMP,$df,"   ")
	
goto checkmax

neg3:

	let MINTEMP = MINTEMP - 128  'adjust neg value
	serout LCD,N2400,(254,128,"Lo -",#MINTEMP,$df)

checkmax:

	if MAXTEMP > 127 then neg4  'test for negative
	serout LCD,N2400,(254,136,"Hi ",#MAXTEMP,$df)
	
goto fini

neg4:

	let MAXTEMP = MAXTEMP - 128 ' adjust neg value
	serout LCD,N2400,(254,136,"Hi -",#MAXTEMP,$df)

fini:

	serout LCD,N2400,(254,192,"Last reset ",#b5,#b6,"/",#b7,#b8)
	pause 5000
	serout LCD,N2400,(254,1,254,1)
	
return

''''''''''''''''''''''''''''''''''''''''''''''''''''''
wipe:

gosub timeit

	write 0,0:write 1,0
	write 2,b9:write 3,b10:write 4,b2
	write 5,b3:write 6,b0:write 7,b4

return

''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''

disp1:

	serout LCD,N2400,(254,128,#b11,#b12,":",#b7,#b8,"   ") 'H/M

	serout LCD,N2400,(254,136,#b9,#b10,"/",#b2,#b3,"/",#b0,#b4)
	
return

'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
Below zero the min temp always displays 0. I can see that the sensor cannot produce an integer less than 0

At the same time, the max will show a negative value. Again I can see that the signed negative integer from the sensor is > the positive values.

My somewhat fluffy ideas to overcome this is to.

1. Scale everything up for processing and back down for display. Or
2. Run a third record for all -ve measurements.

Your thoughts would be appreciated.

R.
 

nick12ab

Senior Member
Check the sign bit when deciding whether the new temperature is higher/lower than the current max/min or not, much like you've done for decoding the temperature for the display.
Code:
	if NOWTEMP > 127 then...
You can store the min and max temperature values with the sign bits left in and decode the max/min values for the display in the same way as you're doing the current temperature.
 

russbow

Senior Member
This suggests that all sub-zero measurements are dealt with separately.
Akin to to my option 2 in the original post.
 

hippy

Technical Support
Staff member
The main problem is, because of the way negative numbers are represented by the value returned by READTEMP, negative numbers do not have a lower value than positive numbers on a PICAXE which makes simple comparisons a little awkward.

There are two primary solutions -

1) Convert the value from READTEMP to others which represent running from most negative ascending to most positive which can then be easily used in PICAXE comparisons in a natural way, converting those values back to what that mean when it comes to processing or displaying them elsewhere.

2) Alter the comparisons so they work as required with the raw values.

I'd favour (1) because it makes the comparisons simpler, which makes it easier to understand and debug, and there's probably a need to process the data later even if you do it the second way. It's also easier to do the conversion than trying to work out the complexities of comparing two not naturally ascending representations of numbers.

For example ... If ( current < 128 And minimum < current ) Or ( current >= 128 And minimum >= 128 and minimum < current ) or ( minimum < 128 and current >= 128 ) Then Let minimum=current ... is a nightmare; is it right, is any condition missed, how do we make that elegant PICAXE compatible code ?

This is much easier -

If current >= $80 Then
current = current - $80
Else
current = current + $80
End If
If current < minimum Then Let minimum = current

Or, even easier ...

current = current ^ $80
If current < minimum Then Let minimum = current

And to print the result ...

temp = minimum
If temp >= $80 Then
SerTxd( "+" )
Else
SerTxd( "-" )
End If
temp = temp & $7F
SerTxd( #temp )
 

russbow

Senior Member
I thought this part of the code

Code:
check:

	if NOWTEMP > 127 then neg2
	serout LCD,N2400,(254,192,"Temp ",#NOWTEMP,$df,"C ")
	pause 5000
	serout LCD,N2400,(254,128,"                ")
	
goto checkmin

neg2:

	let NOWTEMP = NOWTEMP - 128 ‘ adjust neg value
	serout LCD,N2400,(254,128,"Temp -",#NOWTEMP,$df)
 
checkmin:

	if MINTEMP > 127 then neg3  'test negative
	serout LCD,N2400,(254,128,"Lo ",#MINTEMP,$df,"   ")
	
goto checkmax

neg3:

	let MINTEMP = MINTEMP - 128  'adjust neg value
	serout LCD,N2400,(254,128,"Lo -",#MINTEMP,$df)

checkmax:

	if MAXTEMP > 127 then neg4  'test for negative
	serout LCD,N2400,(254,136,"Hi ",#MAXTEMP,$df)
	
goto fini

neg4:

	let MAXTEMP = MAXTEMP - 128 ' adjust neg value
	serout LCD,N2400,(254,136,"Hi -",#MAXTEMP,$df)

fini:

	serout LCD,N2400,(254,192,"Last reset ",#b5,#b6,"/",#b7,#b8)
	pause 5000
	serout LCD,N2400,(254,1,254,1)
	
return
and having set the log upper and lower values with:-

If MINTEMP = 0 And MAXTEMP = 0 Then
MINTEMP = 255
End If

and done the comparison thus

Code:
 If NOWTEMP < MINTEMP Then
   MINTEMP = NOWTEMP
   Write 0, MINTEMP
 End If
 
 If NOWTEMP > MAXTEMP Then
   MAXTEMP = NOWTEMP
   Write 1, MAXTEMP
 End If


did exactly that.

Isn't the problem that ( signs ignored ) -2 is bigger than +1, and -2 will never be less than 0.
 
Top