Searching \ for '[PIC ] if else if' in subject line. ()
Make payments with PayPal - it's fast, free and secure! Help us get a faster server
FAQ page: www.piclist.com/techref/microchip/devices.htm?key=pic
Search entire site for: 'if else if'.

Exact match. Not showing close matches.
PICList Thread
'[PIC ] if else if'
2006\10\01@114454 by Andre Abelian

flavicon
face
Hi to all engineers,

I am reading ADC to compare 10 different values  if they are matched
then each match
has it's own set value. my question is.

1. what is the different between  if else if  for example

   if (adc_x==1023)        // 5v         1023
           {
           xbyte_lsb=0xff ;
           xbyte_msb=0x01 ;
           }
           else if (adc_x==921)   // 4,5v       921
           {
           xbyte_lsb=0x9A ;
           xbyte_msb=0x01 ;
           }

or  without else if

   if (adc_x==1023)        // 5v         1023
           {
           xbyte_lsb=0xff ;
           xbyte_msb=0x01 ;
           }
           if (adc_x==921)   // 4,5v       921
           {
           xbyte_lsb=0x9A ;
           xbyte_msb=0x01 ;
           }

I do not clearly understand what does "else if"  do?

is there better way of testing ADC ?

Any feedback will appreciate.

Andre

2006\10\01@122344 by Wouter van Ooijen

face picon face
> I do not clearly understand what does "else if"  do?

In your case it might not make any difference, but in general: else if
makes that the second condition is never even considered if the first
one was true. With separate if's each condition is evaluated and the if
part executed if appropriate.

> is there better way of testing ADC ?

Yes. Never check for one value, always check for ranges.

Wouter van Ooijen

-- -------------------------------------------
Van Ooijen Technische Informatica: http://www.voti.nl
consultancy, development, PICmicro products
docent Hogeschool van Utrecht: http://www.voti.nl/hvu


2006\10\01@122650 by Harold Hallikainen

face
flavicon
face
Without all the elses, the if's after the successful test will continue to
run. That is, every test will be run every time. With the elses, tests
after the success will be skipped. Another way to do this, which is, I
believe, more readable, is to use the switch-case statement.

I am surprised that you are testing for 10 specific ADC values. It is
unlikey that successive ADC readings will land on exactly a particular
number. More likely they will be one count higher or lower, perhaps more
variation depending on circuit stability. Do yo want to test the ADC for a
range of values? If so, the if, or if else if test seem to be he only way
to go (or a very large switch-case statement or a large array where the
ADC indexes into it).

Harold


{Quote hidden}

> -

2006\10\01@134607 by Andre Abelian

flavicon
face
Harold,

thanks for your replay.
Your brought interesting point on ADC conversion.
suppose I am looking for 951  I better test for 949-953

if ((adc_x>948)&&(adc_x<954))                // looking for 951

do you think above example will work?

thanks for your help

Andre




Harold Hallikainen wrote:

{Quote hidden}

>>-

2006\10\01@135811 by Harold Hallikainen

face
flavicon
face
Sure, I think that would work. The else if would be faster, but with a
small number of comparisons, the improved readability of leaving out the
elses is probably worthwhile. If the ranges "run into each other", a quick
assembly language technique is to add negative numbers, less negative to
more negative, until the result is negative, then branch out of the
checks. A similar technique here would be to use a series of if elses with
only one check per test. For example:

if(adc<10)
   DoSomething();
 else if (adc<20)
   DoSomethingElse();
 else if(adc<30)
   DoAnotherSomethinElse();

This results in only one compare per if and skips the compares after success.

Harold



{Quote hidden}

>>>--

2006\10\01@135912 by Andre Abelian

flavicon
face
Wouter,

thanks for your fast replay.
You and Harold suggested  to use range rather then single value.
How wide range should I use? suppose I m looking for 951
is 950-952 acceptable ?

once again thank you very much for your help

Andre




Wouter van Ooijen wrote:

{Quote hidden}

2006\10\01@142619 by Wouter van Ooijen

face picon face
> You and Harold suggested  to use range rather then single value.
> How wide range should I use? suppose I m looking for 951
> is 950-952 acceptable ?

depends on what *you* want.

for instance, for a 6-key resistor-chain input I use 1/3 of the interval
as 'belonging to the adjacent value', the mid-1/3 as deadband (invalid
or illegal reading).

Wouter van Ooijen

-- -------------------------------------------
Van Ooijen Technische Informatica: http://www.voti.nl
consultancy, development, PICmicro products
docent Hogeschool van Utrecht: http://www.voti.nl/hvu


2006\10\01@145641 by Andre Abelian

flavicon
face
Harold,

In your example if adc has 0-9  it will call DoSomething();  but what we
really need
is to create spot if it get to  9-10 then DoSomething();

thank you very much for your help

Andre




Harold Hallikainen wrote:

{Quote hidden}

2006\10\01@155735 by Harold Hallikainen

face
flavicon
face
Your original code of anding two tests is fine. I generally try to look
ahead and see if I can use the results of one test to eliminate the need
for one later. At some point though, the code becomes too convoluted, and
the double test is more reliable. If this is an application where you're
interpreting button presses by having the buttons tap a voltage divider, I
think it's safe to have one ADC range run into another with no "dead band"
between them.

Harold


{Quote hidden}

2006\10\01@184540 by William Chops Westfield

face picon face

On Oct 1, 2006, at 10:46 AM, Andre Abelian wrote:

> if ((adc_x>948)&&(adc_x<954))                // looking for 951
>
This is the sort of thing that it's nice to hide inside a macro:

#define HOWNEAR 3
#define NEAR(val, target) \
    ((val) > ((target) - HOWNEAR) && (val) < ((target) + HOWNEAR))

Then you can say:

       if (NEAR(adc_x, 951)) {
               // code
    }

And it's easier to tell what you're trying to do, and you can
easily change your "pickyness" by changing HOWNEAR.

In your original code example:
{Quote hidden}

Part of your misunderstanding is because it's indented "wrong";
you didn't un-indent after the first if was done:


   if (adc_x==1023)        // 5v         1023
           {
           xbyte_lsb=0xff ;
           xbyte_msb=0x01 ;
           }
   if (adc_x==921)   // 4,5v       921
           {
           xbyte_lsb=0x9A ;
           xbyte_msb=0x01 ;
           }

BillW


2006\10\01@185403 by Gerhard Fiedler

picon face
Wouter van Ooijen wrote:

>> You and Harold suggested  to use range rather then single value.
>> How wide range should I use? suppose I m looking for 951
>> is 950-952 acceptable ?
>
> depends on what *you* want.

Which includes how stable your readings are.

Basically, you want to minimize false positives (readings that fall into
your selected range without being really the ones you want to catch) and at
the same time minimize false negatives (readings that fall outside your
selected range when they are really the ones you want to catch).

Sometimes there is a range that has almost 0% of both, sometimes you need
to live with a few percent of false results of either or both.

The degenerated range of checking for a single value usually minimizes
false positives but gives you a lot of false negatives. By broadening the
range, you include more readings and decrease the number of false
negatives. But there probably will be a point where false positives start
to appear.

Gerhard

2006\10\01@192555 by Harold Hallikainen

face
flavicon
face
Hownear reminds me of another technique. Define the diff value function
like this:

int diff(int a, int b){
 if(a>b)
   return(a-b);
 else
   return(b-a);
}

Since the ADC has an unsigned 10 bit result, you could change all the ints
to unsigned int.

Then check to see if your ADC is close enough to the DesiredValue (say,
within 3 counts) as below:

if(diff(ADC,DesiredValue)<3)
 DoSomething();


Harold


{Quote hidden}

> -

2006\10\01@200557 by William Chops Westfield

face picon face

On Oct 1, 2006, at 4:25 PM, Harold Hallikainen wrote:

> Define the diff value function like this...

I considered making NEAR use (abs(val-target) < HOWNEAR), which is
how I traditionally think of it, and which is similar to your "diff"
function, but I didn't have a lot of faith in the efficiency of PIC
C compilers/libraries WRT abs() vs the two comparisons.  YMMV, check
the produced object code, etc...

BillW

2006\10\01@211459 by Andre Abelian

flavicon
face
Willian,

I liked your macro it looks really good the only thing I do not
understand is  \   what is the backslash means or do ?
I never used it and in compiler it highlighted as red.
sorry I am new to c.

thank you very much for your help

Andre




William Chops Westfield wrote:

{Quote hidden}

2006\10\01@212732 by William Chops Westfield

face picon face

On Oct 1, 2006, at 6:15 PM, Andre Abelian wrote:

> I liked your macro it looks really good the only thing I do not
> understand is  \   what is the backslash means or do ?

The backslash is line continuation, so that the macro can span
more than one line.  (macro definitions always terminate at the
end of the line.)  In this case, I just used it so the whole
definition would fit on an 80-column line (with the "#define name"
on the previous line), but I've seen macros that span tens of
lines easily...

BillW

2006\10\01@222659 by Harold Hallikainen

face
flavicon
face
I was also originally thinking of abs(), but that implies we're using
signed numbers. diff() works with unsigned numbers.

Harold

{Quote hidden}

> -

More... (looser matching)
- Last day of these posts
- In 2006 , 2007 only
- Today
- New search...