help "if...else" and "if...if... "

Discussion in 'Embedded Systems and Microcontrollers' started by oookey, Nov 7, 2014.

  1. oookey

    Thread Starter Member

    May 24, 2010
    62
    0
    Hi all,

    I got problem with “IF… ELSE” & ”IF… IF”

    Chip 12F615, pins 3 & 7 as analog inputs, pin 5 output PWM.

    Internal osc 8MHZ, using MIKROC version 6.0.0 to compile.

    _______________[1] [8]
    _______________ [2] [7] <--= (ref1) gpio.f0
    (ref2) gpio.f4 =-->[3] [6]
    _______________[4] [5] =--> (op2) gpio.f2

    The following source codes could not work:
    #define op2 gpio.f2
    unsigned ref1,ref2;
    void init(){
    ansel=0b010001; // analog gpio.f0; f4
    trisio=0b010001; // input gpio.f0; f4
    pwm1_init(50000);
    ref1=ref2=0;
    }//end init()
    void main() {
    init();
    while(1){
    adc_init();
    ref1=adc_read(0);
    ref1/=4;
    ref2=adc_read(4);
    ref2/=4;

    // if ref1 OR ref2 >=8 stop pwm, ELSE pwm start.
    if(ref1||ref2>=8){pwm1_stop();}else{pwm1_set_duty(64);
    }// end while(1)
    }// end main()

    The following is workable, by observing the blinking light:
    void main() {
    init();
    while(1){
    adc_init();
    ref1=adc_read(0);
    ref1/=4;
    ref2=adc_read(4);
    ref2/=4;

    if(ref1||ref2>3){pwm1_stop();delay_ms(500);} // if ref1 OR ref2 >3 pwm stop, delay 0.5sec

    if(ref1||ref2<1){pwm1_set_duty(128);pwm1_start();} // if ref1 OR ref2 <1 pwm start.
    }// end while(1)
    }// end main()

    Where went wrong with the if…else command?

    Thanks

    oookey
     
  2. tshuck

    Well-Known Member

    Oct 18, 2012
    3,531
    675
    1. Use code tags when posting code.
    2. Explain what you want the code to do.
    3. Explain what it does.
    4. The code does not work in what way?
     
    ErnieM likes this.
  3. oookey

    Thread Starter Member

    May 24, 2010
    62
    0
    The code is to sense the voltages at ref1 and ref2 by ADC, if ref1 or ref2 exceeded the preset (>=8) the output (PWM) halt, else continue output hence on the LED.
    Two branches of LED strings, ref1 and ref2 are voltages of resistors in each branch,.

    i tried:
    “if(ref2||ref1<1){pwm1_set_duty(128);pwm1_start();} else{pwm1_stop();delay_ms(2000);}”
    The light would ON a split second, OFF about 2sec cycle,
    Then: “if(ref2||ref1<2){pwm1_set_duty(128);pwm1_start();} else{pwm1_stop();delay_ms(2000);}”
    The light stay ON all the way, never go OFF.
    Please any suggestion?
    "Use code tags when posting code." -- please enlighten how to use the code tags.
     
  4. NorthGuy

    Active Member

    Jun 28, 2014
    604
    121
    Code (Text):
    1. if (ref1 >= 8 || ref2 >= 8) ...
     
  5. LDC3

    Active Member

    Apr 27, 2013
    920
    160
    "(ref1||ref2>=8)"

    Is this ( (ref1) || ( ref2 >= 8 ) )
    or is it this ( ( ref1 || ref2 ) >= 8 )?
    What is he order of precedence for the operators ?

    Again, you have ambiguous code:
    (ref1||ref2>3)
    (ref1||ref2<1)
     
  6. oookey

    Thread Starter Member

    May 24, 2010
    62
    0
    I want to check that the voltage of ether one ref1 or ref2 is exceeded the preset then off the output.

    It seems that the problem is not lie on here " if (ref1 >= 8 || ref2 >= 8) ..."
    i tried as follow, the light never goes off.
    " if(ref2<8||ref1<8){pwm1_set_duty(128);pwm1_start();}
    else{pwm1_stop();delay_ms(2000);}"

    Only this "<1" , "if(ref2||ref1<1){pwm1_set_duty(128);pwm1_start();}else{pwm1_stop();delay_ms(2000);}" the light goes on and off 2sec cycle.

    any advice please.
     
  7. WBahn

    Moderator

    Mar 31, 2012
    17,748
    4,796
    When you say (ref2||ref1<1), what you are really wanting is for the compiler to read your mind and see that what you are wanting it to do is if (ref1 < 1) or if (ref2 < 1). But compilers aren't mind readers and you have to tell them in terms they can understand.

    Just like when you say x = 3 + 2 * 4; the compiler sees three operands and two operators and so it applies the defined order of operations to determine how to evaluate them. Since multiplication has higher precedence than addition, the compiler interprets this as x = 3 + (2 * 4). The same applies to your (ref2||ref1<1) expression and since relational operations have higher precedence than logical ones, this will be interpreted as (ref2||(ref1<1)). The (ref1<1) will evaluate to a 1 if true and a 0 if false. You will then be left with either (ref2||1) or with (ref2||0). If ref2 is exactly (and I mean exactly, not 1e-10, but exactly) zero, it will be viewed as a logical false, otherwise it will be viewed as a logical true. So what you have actually told the compiler is that you want to execute the if clause if either ref1 is less than 1 or if ref2 is anything other than exactly zero.

    This is related to another common mistake that programmers make, and that's wanting to check if the value b is between the values a and c by using (a<b<c). Well, this might work well on paper when a human is interpreting what this means within the context of which it is used, but a computer is stupid and applies rigid rules in evaluating expressions and will see this as ((a<b)<c) since relational operations are left associative.
     
  8. djsfantasi

    AAC Fanatic!

    Apr 11, 2010
    2,809
    834
    What WBahn said. Great explanation.

    I'd like to add that it's good practice to include parentheses to explicitly define what you mean. Even if the order of operations precedence appears to be sufficient, there may be differences due to the compiler used.

    Hence, I'd write your example as:
    If ((ref2<8)||(ref1<8))…
     
  9. NorthGuy

    Active Member

    Jun 28, 2014
    604
    121
    Opposite of this:

    is not this:

    but this:

     
  10. oookey

    Thread Starter Member

    May 24, 2010
    62
    0
    Many thanks to the advises, i got my circuit running properly now. :)
    yes putting the parentheses in the right position plays a significant role in programming.

    oookey
     
Loading...