Go Down

### Topic: Problem with if-else ladder (Read 2607 times)previous topic - next topic

##### Jun 20, 2011, 07:53 pm
Hello, I am having very strange problem.
My program code is below:

if(val<=312)
tem=map(val,0,312,700,400);
else if(312<val<=455)
tem=map(val,312,455,400,300);
else if(455<val<=612)
tem=map(val,455,612,300,200);
else if(612<val<=745)
tem=map(val,612,745,200,100);
else if(745<val<=1023)
tem=map(val,745,1023,100,0);
Serial.println(val);
Serial.println.(tem);

I am trying to read analog reading and convert it using map function.
Now here when the analog value val is 991 the program goes to the second if in the if-else ladder.
It means that(312<val<=455) condition becomes true when val=991 !!!!! and that results in value of "tem" according to the map function in second if statement. In my case the value of tem becomes -74. The program should go to last if statement when value of val is 991. but it doesn't. Please help me out here.

My arduino board: Arduino mega(old one)
Software: Arduino 0022

#### PaulS

#1
##### Jun 20, 2011, 09:04 pm
Code: [Select]
`else if(312<val<=455)`
You can not do this. You must explicitly form two comparisons:
Code: [Select]
`else if(312 < val && val <=455)`

#### sixeyes

#2
##### Jun 20, 2011, 09:14 pm
Actually the first of the two comparisons is redundant in each case as the previous conditional tests have already accounted for those values.

I would modify your code to be:

Code: [Select]
`  if(val<=312)    tem=map(val,0,312,700,400);  else if(val<=455)    tem=map(val,312,455,400,300);  else if(val<=612)    tem=map(val,455,612,300,200);  else if(val<=745)    tem=map(val,612,745,200,100);  else    tem=map(val,745,1023,100,0);`

Note I've also removed the final if since it's redundant.

Iain

#### pantonvich

#3
##### Jun 20, 2011, 09:18 pm
I also think you want greater than and not less than
I also think that you don't need the greater than's because of your order

Code: [Select]
`else if(312 > val && val <=455)`

Code: [Select]
`else if(val <=455)`

#### PaulS

#4
##### Jun 20, 2011, 09:54 pm
Code: [Select]
`else if(312 > val && val <=455)`
If 312 is greater than val, that means that val is less than 312. That is not consistent with the original, but incorrect, code.

#### pantonvich

#5
##### Jun 20, 2011, 10:26 pm
sorry about transposing: val > 312

but if it's checked before (as in the example given) then it's useless to check again

#### robtillaart

#6
##### Jun 21, 2011, 12:02 am

unless the type of val is volatile ....  (sorry to make it difficult)

if the else part was missing the first condition is mandatory
Code: [Select]
`if(val<=312) tem=map(val,0,312,700,400);if(312 > val && val<=455) tem=map(val,312,455,400,300);if(455 > val && val<=612) tem=map(val,......etc`
but the code of sixeyes is optimized => more efficient as the number of tests is minimized
Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)

#7
##### Jun 21, 2011, 05:10 am
I just removed all "else" statements ad everything is working cool now. I think if(x<val<=y) type of condition checking is supported in arduino. I also tried other methods and they worked as well.. Thanks guys....

#### sixeyes

#8
##### Jun 21, 2011, 08:11 am
Quote
I think if(x<val<=y) type of condition checking is supported in arduino

If you really want this check you can write it as:

Code: [Select]
`if (x < val && val <= y)`

The code you wrote was a mathematical expression but in C/C++ (as used on the arduino) you have to use binary expressions (i.e. only two values to an operator. So to implement what you want needs three bits (x < val), (val <= y) and &&. The && is C's logical and operator combining the two comparisons.

BTW the code I posted in reply #3 is much more efficient that your original (see below) as you are performing many more comparisons that is necessary. In the first else if you have already performed the 312 < val in the preceding if (as val <= 312 is the opposite of 312 < val) so this part of the expression will always be true if it is executed (a waste of clock cycles and code memory). It is the same for each else if. This final else if if should be replaced by an else as the analog read will produce a value between 0 - 1023 (so the test in this expression will always be true).

As a side issue: if val was not limited to the range 0 - 1023, for values outside this range tem would be uninitialised. When I initialise a variable in a if/else if ladder, I always have an else or initialise the variable before the first if.

Code: [Select]
`  if (val <= 312)    tem = map(val, 0, 312, 700, 400);  else if(312 < val && val <= 455)    tem = map(val, 312, 455, 400, 300);  else if (455 < val && val <= 612)    tem = map(val, 455, 612, 300, 200);  else if (612 < val && val <= 745)    tem = map(val, 612, 745, 200, 100);  else if(745 < val && val <= 1023)    tem = map(val, 745, 1023, 100, 0);`

Hope that helps.

Iain

#### robtillaart

#9
##### Jun 21, 2011, 08:40 am

Quote
if(x<val<=y)

As sixeyes said this is a correct mathematical expression but is doesn't do what you want.

try this sketch
Code: [Select]
`void setup(){  Serial.begin(115200);  int val = 100;    if (10 < val <= 50) Serial.println("BUG");  else Serial.println("OK");}void loop(){} `

It prints BUG because the precedence/order of comparison operators is from left to right and the outcome of a compression is either 0(false) or 1(true).
1) 10 < 100 <=50 is evaluated:
2) 10<100 ?? => true so (10<100) is replaced by 1
3) 1 <= 50 ?? => true  ==> print bug

Another variation:
Code: [Select]
`void setup(){  Serial.begin(115200);  int val = 100;  if (10 > val > -1 ) Serial.println("BUG");  else Serial.println("OK");}void loop(){} `

Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)

Go Up