Comparing 4 variables and outputting the greater

donrecardo

Senior Member
Hi
I have 4 variables, we can call them say, B0, B1, B2, B3
They hold the temperatures given by 4 sensors which I have converted to degrees F.

I need to compare them and output the value and the name of the one who's value is highest so for example, if

B0 = 72
B1 = 51
B2 = 74
B3 = 64

I wish to output to my LCD something like

" Temp = 74 F on B2 "

I tried using
if b0>b1 & b0>b2 & b0>b3 then its_b0
if b1>b0& b1>b2 & b1>b3 then its_b1
if b2>b0 & b2>b1 & b2>b3 then its_b2
if b3>b0 & b3>b1 & b0>b2 then its_b3

Thinking I could then goto sub routines called its_b0 , its_b1 etc
to output the details needed , but if b0>b1 & b0>b2 & b0>b3 then its_b0
syntax errors .

So can someone tell me please, what is the right way to achieve the required result ?

Edit..... I found my own error . I need to put " and " not " & " in the compare lines


Don
 
Last edited:

womai

Senior Member
Determining the minimum (or maximum) or a set of data values is a very common occurrence in coding. Done in the most compact and elegant way when the values are in array, but in your case:

symbol maxi = b4
symbol which_val = b5

maxi = b0
which_val = 0

if b1 > maxi then
maxi = b1
which_val = 1
endif

if b2 > maxi then
maxi = b2
which_val = 2
endif

if b3 > maxi then
maxi = b3
which_val = 3
endif

serout 0, ("Temp =", #maxi, " F on b", #which_val, cr, lf)
 

lbenson

Senior Member
Womai's solution is more elegant, but the method which you suggest doesn't take care of the instance in which the highest value is shared by two or more variables. You would need to use ">=" to cover that circumstance.
 

hippy

Ex-Staff (retired)
Most simply to find the highest value ...

result = b0 MIN b1 MIN b2 MIN b3

For "X MIN Y" : X can never be less than Y, so the result is always the greater of the two.

To determine which is highest then as womai suggests.
 
Last edited:

donrecardo

Senior Member
Thanks all for your replies but in truth I didn't really understand what your code was doing, I think it was a little too advanced for me just yet .

What I had written so far was

Code:
main:
serout 6,n2400,(254,1) 'initialise display
pause 500

Reading:               'Routines to sample temperature sensors
	readtemp 0,b0 ‘ read value into b0
		b4=100*b0*9/50//10		'Convert to degrees F and isolate decimal part
		b0=b0*9/5+32			'Convert to degrees F and isolate integer part
	readtemp 1,b1 ‘ read value into b1
		b5=100*b1*9/50//10		'Convert to degrees F and isolate decimal part
		b1=b1*9/5+32			'Convert to degrees F and isolate integer part
	readtemp 2,b2 ‘ read value into b2
		b6=100*b2*9/50//10		'Convert to degrees F and isolate decimal part
		b2=b2*9/5+32			'Convert to degrees F and isolate integer part
	readtemp 3,b3 ‘ read value into b3
		b7=100*b3*9/50//10		'Convert to degrees F and isolate decimal part
		b3=b3*9/5+32			'Convert to degrees F and isolate integer part

Compare:    'Compare to see which sensor is hottest

	if b0 >= b1 and b0 >= b2 and b0 >= b3 then its_b0 'Go to relevant display routine
	if b1 >= b0 and b1 >= b2 and b1 >= b3 then its_b1 'Go to relevant display routine
	if b2 >= b0 and b2 >= b1 and b2 >= b3 then its_b2 'Go to relevant display routine
	if b3 >= b0 and b3 >= b1 and b3 >= b2 then its_b3 'Go to relevant display routine
	

its_b0: 
	serout 6,n2400,(254,128,"Temp ",#b0,".",#b4," F ","On 0")  'B0 was the highest temperature
	pause 30
	goto reading
	
its_b1: 
	serout 6,n2400,(254,128,"Temp ",#b1,".",#b5," F ","On 1")  'B1 was the highest temperature
	pause 30
	goto reading

its_b2: 
	serout 6,n2400,(254,128,"Temp ",#b2,".",#b6," F ","On 2")  'B2 was the highest temperature
	pause 30
	goto reading

its_b3: 
	serout 6,n2400,(254,128,"Temp ",#b3,".",#b7," F ","On 3")  'B3 was the highest temperature
	pause 30
	goto reading
Basically it is doing ( though I accept maybe not elegantly ) what I was asking it to do
I dont have all 4 sensors yet , I am waiting for them to arrive but if I connect just one sensor , and in my room its reading 64 Degs F , and leave the other 3 sensors off ( so they read 32 degs F ) then the LCD should display that the temperature is 64 Degs and also display which port that the sensor was on.
It does in fact do that If I put the sensor on pin0 it says " Temp 64.0F on 0"
and if I move the sensor to pin 2 then sure enough it says " Temp is 64.0F on 2 " . The problem is the way it displays it.

I assumed it would make the display , take a new sample and replace the display with a new updated display at regular intervals . but its any thing but regular.
I start it up and it displays the info for any thing between 3 and 8 seconds
then it blanks for between 1 and 10 seconds and then displays again for another random time .
I cant see why it doesnt run at a regular rate but it certainly doesn't.
I just tried it a few moments ago and it went ...
display 4 seconds , blank 2 seconds , display 3 seconds, blank 9 seconds, display 6 seconds , blank 1 second and so on
There seems no pattern to it .
I am using a 40X1 and an Axe033 LCD display

Any Ideas why its behaving so irregular ?

Don
 

BeanieBots

Moderator
At a quick glance, your looks OK, at least as far as the LCD bit is concerned.
Try to eliminate parts of the code.
For example, what happens if you just send numbers to the display?

eg

..initialise LCD bits here...

main:
For b1=1 to 40
For b5=0 to 9
serout 6,n2400,(254,128,"Temp ",#b1,".",#b5," F ","On 1")
pause 500
next b5
next b1
goto main
 
Last edited:

eclectic

Moderator
@Donr

How strange. I've just tried your code using an AXE022 board.

Two LCD's in parallel on o/p 6 (AXE033 and firmware LCD)

28X1 on input C0. Works fine, with NO blanking.

Changed to a 40X1.
One DS18B20 on input 0 (D0). Works fine.
Moved to 1, then 2 then 3. Always shows correct input and a 'F value.

Added another DS18B20. Moved them around, warming one then another.

The outputs always show the winner, in the correct place.
Steady displays.

Sorry, but I can't seem to make it go wrong.

Time to check your power supply and wiring?

e
 

donrecardo

Senior Member
Hi lads
and thanks for your input

I think you were right about a dodgy connection on the bread board

I rebuilt it and added the second DS18b20 and its all working great now

As I warm each in turn they take over as winner and display the correct output.

The axe033 is all soldered up on its pcb and has always worked fine
the 40X1 is on a home made pcb and all works ok but the DS18b20 was plugged into a bread board and I think maybe one of the contacts was not so good.
The bread board was a cheapy of Ebay so maybe cheap isn't always the best idea

The main thing is it works fine now , so thanks for the help

Don
 

westaust55

Moderator
Just for the hell of it and not the most ocmpact but here is one solution

B0 = 72
B1 = 51
B2 = 74
B3 = 64



b4 = b0
If b1 > b0 then : b4 = b1 : ENDIF
If b2 > b4 then : b4 = b2 : ENDIF
If b3 > b4 then : b4 = b3 : ENDIF
SEROUT 7, N2400, ("Highest is: ",#b4)
 

donrecardo

Senior Member
Just for the hell of it and not the most ocmpact but here is one solution

B0 = 72
B1 = 51
B2 = 74
B3 = 64



b4 = b0
If b1 > b0 then : b4 = b1 : ENDIF
If b2 > b4 then : b4 = b2 : ENDIF
If b3 > b4 then : b4 = b3 : ENDIF
SEROUT 7, N2400, ("Highest is: ",#b4)

Hi , I just tried your WestUbble sort and it worked fine . much easier than my
original idea which was very clumsy compared to yours.

One small problem with your sort was it only shows the value of the highest temp a sensor had measured where originally I had wanted to display highest temp and also which sensor had detected it. but that was easy to fix . I just added

Code:
Compare:    'Compare to see which sensor is hottest

	b4=b0 : b5=0                ' b4 holds value of sensor and b5 holds the sensor number
	if b1>=b4 then :b4=b1 :b5=0 endif
	if b2>=b4 then :b4=b2 :b5=2 endif
	if b3>=b4 then :b4=b3 :b5=3 endif
	
	

show_it: 
	serout 6,n2400,(254,128,"Temp ",#b4," C ","On ",#b5)
Thanks for all your help, I'm sure I will have more questions soon

Don
 

kevrus

New Member
Donrecardo,

If you put '223' in you serout line, it will give you the 'degree' sign before the letter C or F

i.e. change
serout 6,n2400,(254,128,"Temp ",#b4," C ","On ",#b5)

to
serout 6,n2400,(254,128,"Temp ",#b4,223,"C ","On ",#b5)

Apologies if you already know this (i'm sure you do...)
 

donrecardo

Senior Member
Donrecardo,

If you put '223' in you serout line, it will give you the 'degree' sign before the letter C or F

i.e. change
serout 6,n2400,(254,128,"Temp ",#b4," C ","On ",#b5)

to
serout 6,n2400,(254,128,"Temp ",#b4,223,"C ","On ",#b5)

Apologies if you already know this (i'm sure you do...)

Actually , no I didnt ,, but I do now. I just added it to my code and it looks great now.
Thanks for that
Don
 
Top