Odd Else if behaviour

oracacle

Senior Member
Just been fiddling with min max temperature and found that my code was not working for reason.

Simulates as expected
Code:
[color=Blue]if [/color][color=Purple]checktemp [/color][color=DarkCyan]> [/color][color=Navy]2048 [/color][color=DarkCyan]and [/color][color=Purple]maxcheck [/color][color=DarkCyan]> [/color][color=Navy]2048 [/color][color=Blue]then
            if [/color][color=Purple]checktemp [/color][color=DarkCyan]> [/color][color=Purple]maxcheck [/color][color=Blue]then
                  if [/color][color=Purple]whole [/color][color=DarkCyan]< [/color][color=Navy]10 [/color][color=Blue]then
                        serout b.7[/color][color=Black], [/color][color=Blue]n2400[/color][color=Black], [/color][color=Blue]([/color][color=Navy]254[/color][color=Black],[/color][color=Navy]192[/color][color=Black], [/color][color=Purple]sign[/color][color=Black], [/color][color=Navy]32[/color][color=Black], #[/color][color=Purple]whole[/color][color=Black], [/color][color=Red]"."[/color][color=Black], #[/color][color=Purple]deci[/color][color=Blue])
                  else
                        serout b.7[/color][color=Black], [/color][color=Blue]n2400[/color][color=Black], [/color][color=Blue]([/color][color=Navy]254[/color][color=Black],[/color][color=Navy]192[/color][color=Black], [/color][color=Purple]sign[/color][color=Black], #[/color][color=Purple]whole[/color][color=Black], [/color][color=Red]"."[/color][color=Black], #[/color][color=Purple]deci[/color][color=Blue])
                  end if
                  let [/color][color=Purple]maxcheck [/color][color=DarkCyan]= [/color][color=Purple]checktemp
            [/color][color=Blue]end if
      end if
      if [/color][color=Purple]checktemp [/color][color=DarkCyan]> [/color][color=Navy]2048 [/color][color=DarkCyan]and [/color][color=Purple]mincheck [/color][color=DarkCyan]> [/color][color=Navy]2048 [/color][color=Blue]then
            if [/color][color=Purple]checktemp [/color][color=DarkCyan]< [/color][color=Purple]mincheck [/color][color=Blue]then
                  if [/color][color=Purple]whole [/color][color=DarkCyan]< [/color][color=Navy]10 [/color][color=Blue]then
                        serout b.7[/color][color=Black], [/color][color=Blue]n2400[/color][color=Black], [/color][color=Blue]([/color][color=Navy]254[/color][color=Black],[/color][color=Navy]200[/color][color=Black], [/color][color=Purple]sign[/color][color=Black], [/color][color=Navy]32[/color][color=Black], #[/color][color=Purple]whole[/color][color=Black], [/color][color=Red]"."[/color][color=Black], #[/color][color=Purple]deci[/color][color=Blue])
                  else
                        serout b.7[/color][color=Black], [/color][color=Blue]n2400[/color][color=Black], [/color][color=Blue]([/color][color=Navy]254[/color][color=Black],[/color][color=Navy]200[/color][color=Black], [/color][color=Purple]sign[/color][color=Black], #[/color][color=Purple]whole[/color][color=Black], [/color][color=Red]"."[/color][color=Black], #[/color][color=Purple]deci[/color][color=Blue])
                  end if                  
                  let [/color][color=Purple]mincheck [/color][color=DarkCyan]= [/color][color=Purple]checktemp
            [/color][color=Blue]end if
      end if[/color]
does not simulate correctly
Code:
[color=Blue]if [/color][color=Purple]checktemp [/color][color=DarkCyan]> [/color][color=Navy]2048 [/color][color=DarkCyan]and [/color][color=Purple]maxcheck [/color][color=DarkCyan]> [/color][color=Navy]2048 [/color][color=Blue]then
            if [/color][color=Purple]checktemp [/color][color=DarkCyan]> [/color][color=Purple]maxcheck [/color][color=Blue]then
                  if [/color][color=Purple]whole [/color][color=DarkCyan]< [/color][color=Navy]10 [/color][color=Blue]then
                        serout b.7[/color][color=Black], [/color][color=Blue]n2400[/color][color=Black], [/color][color=Blue]([/color][color=Navy]254[/color][color=Black],[/color][color=Navy]192[/color][color=Black], [/color][color=Purple]sign[/color][color=Black], [/color][color=Navy]32[/color][color=Black], #[/color][color=Purple]whole[/color][color=Black], [/color][color=Red]"."[/color][color=Black], #[/color][color=Purple]deci[/color][color=Blue])
                  else
                        serout b.7[/color][color=Black], [/color][color=Blue]n2400[/color][color=Black], [/color][color=Blue]([/color][color=Navy]254[/color][color=Black],[/color][color=Navy]192[/color][color=Black], [/color][color=Purple]sign[/color][color=Black], #[/color][color=Purple]whole[/color][color=Black], [/color][color=Red]"."[/color][color=Black], #[/color][color=Purple]deci[/color][color=Blue])
                  end if
                  let [/color][color=Purple]maxcheck [/color][color=DarkCyan]= [/color][color=Purple]checktemp
            [/color][color=Blue]end if
      else if [/color][color=Purple]checktemp [/color][color=DarkCyan]> [/color][color=Navy]2048 [/color][color=DarkCyan]and [/color][color=Purple]mincheck [/color][color=DarkCyan]> [/color][color=Navy]2048 [/color][color=Blue]then
            if [/color][color=Purple]checktemp [/color][color=DarkCyan]< [/color][color=Purple]mincheck [/color][color=Blue]then
                  if [/color][color=Purple]whole [/color][color=DarkCyan]< [/color][color=Navy]10 [/color][color=Blue]then
                        serout b.7[/color][color=Black], [/color][color=Blue]n2400[/color][color=Black], [/color][color=Blue]([/color][color=Navy]254[/color][color=Black],[/color][color=Navy]200[/color][color=Black], [/color][color=Purple]sign[/color][color=Black], [/color][color=Navy]32[/color][color=Black], #[/color][color=Purple]whole[/color][color=Black], [/color][color=Red]"."[/color][color=Black], #[/color][color=Purple]deci[/color][color=Blue])
                  else
                        serout b.7[/color][color=Black], [/color][color=Blue]n2400[/color][color=Black], [/color][color=Blue]([/color][color=Navy]254[/color][color=Black],[/color][color=Navy]200[/color][color=Black], [/color][color=Purple]sign[/color][color=Black], #[/color][color=Purple]whole[/color][color=Black], [/color][color=Red]"."[/color][color=Black], #[/color][color=Purple]deci[/color][color=Blue])
                  end if                  
                  let [/color][color=Purple]mincheck [/color][color=DarkCyan]= [/color][color=Purple]checktemp
            [/color][color=Blue]end if
      end [/color][color=Black]i[/color]
the
Code:
[color=Blue]else if [/color][color=Purple]checktemp [/color][color=DarkCyan]> [/color][color=Navy]2048 [/color][color=DarkCyan]and [/color][color=Purple]mincheck [/color][color=DarkCyan]> [/color][color=Navy]2048 [/color][color=Blue]then[/color]
fails for some reason, the only difference between the 2 is the first one end the if statement and starts a new statement instead of using else if, I put the same number into the memory panel (ie checktemp = 2058 and min temp = 2068)
I haven't tried this in hardware as yet, but cant see a reason why the second wouldn't work on either.
its not really an issue, I doubt it will take up any more programme space, just seemed a little hincky
 

sages

Member
Not sure exactly what you are trying to do with your code.
If your indentations are anything to go by you have mismatched if/endifs.
 

hippy

Technical Support
Staff member
It seems to simulate as expected when I simulate it -

checktemp = 9999
maxcheck = 9999
mincheck = 9999

Causes the first IF block to be executed.

checktemp = 9999
maxcheck = 0
mincheck = 9999

Causes the ELSE IF block to be executed.

Make sure you have the latest version of PE6 installed.

If that is still doing the same it would help if you could produce a short version of code which demonstrates the problem, similar to this which is what I used to determine that it works for me -

Code:
#picaxe 40x2

symbol checktemp = w0
symbol maxcheck = w1
symbol mincheck = w2
symbol whole = w3
symbol sign = w4
symbol deci = w5

checktemp = 9999
maxcheck  = 0
mincheck  = 9999

if checktemp > 2048 and maxcheck > 2048 then
  if checktemp > maxcheck then
    if whole < 10 then
      serout b.7, n2400, (254,192, sign, 32, #whole, ".", #deci)
    else
      serout b.7, n2400, (254,192, sign, #whole, ".", #deci)
    end if
    let maxcheck = checktemp
  end if
else if checktemp > 2048 and mincheck > 2048 then
  if checktemp < mincheck then
    if whole < 10 then
      serout b.7, n2400, (254,200, sign, 32, #whole, ".", #deci)
    else
      serout b.7, n2400, (254,200, sign, #whole, ".", #deci)
    end if                  
    let mincheck = checktemp
  end if
end if
 

oracacle

Senior Member
I was on 6.0.8.10, updated to 6.0.8.11, still seems to be doing it.
I have updated the code and found that it happening on all the else if statements in there, again I haven't gotten to check on hardware.
seems to work fine splitting them down to two separate if statements, not sure if it my code structure to be honest.

heres the entire code, I have been feeding values into w10 as a pretend DS18b20.
I am hoping to move this onto the firmware on an OLED for a self contained digital thermometer.

Code:
'symbol 		= w1
	symbol sys_flags	= b0
	symbol sign		= b1
'symbol		= w2
	symbol whole	= b2
	symbol deci		= b3
symbol temp		= w2
	'symbol		= b4
	'symbol		= b5
symbol adjtemp	= w3
	'symbol		= b6
	'symbol		= b7
symbol checktemp	= w4
	'symbol		= b8
	'symbol		= b9
symbol maxcheck	= w5
	'symbol		= b10
	'symbol		= b11
symbol mincheck	= w6



inti:
	serout b.7, n2400, (254,1)
	pause 3000
	
main:
	'temp = checktemp + 1
	temp = w10				'use w10 as DS18b20
	sign = 43
	if temp <> checktemp then			'check for a change in temp and update if needed
		let checktemp = temp			'update stored raw temp
		if temp > 2048 then			'check for negative
		sign = 45
		temp = - temp
		end if
		
		adjtemp = temp *10/16
		whole = adjtemp /10
		deci = adjtemp //10
		if whole < 10 then
			serout b.7, n2400, (254,128, sign, 32, #whole, ".", #deci)
		else
			serout b.7, n2400, (254,128, sign, #whole, ".", #deci)
		end if
	end if

	'check for zero values - will happen on startup
	if mincheck = 0 and maxcheck = 0 then
		gosub high_print
		gosub low_print
	end if
	
	'check for negative max and min
	if checktemp > 2048 and maxcheck > 2048 then
		if checktemp > maxcheck then
			gosub high_print
		end if
	end if
	if checktemp > 2048 and mincheck > 2048 then
	'else if checktemp > 2048 and mincheck > 2048 then	'***does not execute for some reason
		if checktemp < mincheck then
			gosub low_print
		end if
	end if
	
	'check for transition from negtive to positive max, and inverse min
	if checktemp < 2048 and maxcheck > 2048 then
			gosub high_print
	end if
	if checktemp > 2048 and mincheck < 2048 then
	'else if checktemp > 2048 and mincheck < 2048 then	'***does not execute for some reason
			gosub low_print
	end if
	
	'check for positive max and min
	if checktemp < 2048 and maxcheck < 2048 then
		if checktemp > maxcheck then
			gosub high_print
		end if
	end if
	if checktemp < 2048 and mincheck < 2048 then
	'else if checktemp < 2048 and mincheck < 2048 then	'***does not execute for some reason
		if checktemp < mincheck then
			gosub low_print
		end if
	end if
		
	goto main
	

high_print:
	if whole < 10 then
		serout b.7, n2400, (254,192, sign, 32, #whole, ".", #deci)
	else
		serout b.7, n2400, (254,192, sign, #whole, ".", #deci)
	end if
	let maxcheck = checktemp

	return
	
low_print:
	if whole < 10 then
		serout b.7, n2400, (254,200, sign, 32, #whole, ".", #deci)
	else
		serout b.7, n2400, (254,200, sign, #whole, ".", #deci)
	end if			
	let mincheck = checktemp
	
	return
 

hippy

Technical Support
Staff member
It all seems to work for me in 6.0.8.11, hits both IF and ELSE IF break points I added, so it may be a logical error of some kind.

You could try adding integrity checks after each IF and ELSEIF see if the code ever jams up ...

Code:
if checktemp > 2048 and maxcheck > 2048 then
  [b]If checktemp <= 2047 Or maxcheck <= 2047 Then
    Do : Loop
  End If[/b]
  [i]etc[/i]
You could perhaps try coding it in some other way ...

Code:
Select Case checktemp
  Case < 2048
   Select Case maxcheck
      Case < 2048
         ...
      Case > 2048
         ...
    End Select
  Case > 2048
    Select Case maxcheck
      Case < 2048
         ...
      Case > 2048
         ...
    End Select
End Select
 

oracacle

Senior Member
I will go with the two separate If statement for the time being, they simulate fine.
I have a few changes to make and I will look at moving onto hardware where things can be tested mote thoroughly.
 

stan74

Senior Member
Off topic? When speed is important use if then...if then instead of and. If the 1st statement fails it skips the rest not check all arguments.
 

hippy

Technical Support
Staff member
Off topic? When speed is important use if then...if then instead of and. If the 1st statement fails it skips the rest not check all arguments.
There is no simple answer to that ...

Code:
If b1 = 1 Then
  If b2 = 2 Then
    Do Something
  End If
End If
Code:
  If b1 = 1 And b2 = 2 Then
    Do Something
  End If
The first will likely be quicker on average if b1 is not usually 1 but the second will be quicker on average if b1 is usually equal to one.

It depends on which you want, quicker to get to the next condition, or quicker to get to the 'do something'. Two sets of conditions with two 'do something' may balance each other out no matter which is chosen.

In most cases the difference in speed is probably not really noticeable, hard to determine and even measure.
 
Top