How do I do a nested if/else statement?

I figured out the hardware portion of my project tonight (Yay!), and my sketch passed verification, but it doesn't work like I want.
What I am trying to do is monitor 3 buttons, each has a narrow voltage range (which was converted to a number via an analogRead() ), so I need to do something that says "If the value is greater than 300 and less than 305, do this, else if it is greater than 400 and less than 405) then do this else ... and so on. I just used those numbers for an example.

Here's the sketch:

int swcIn;                      //Set variable name for SWC reading
int swcOut;                     //Set variable name for SWC output
int swcPinin = 3;               //Set pin for SWC read
int swcPinout = 2;              //Set pin for SWC passthrough output (in case we need it later)

void setup()                    // run once, when the sketch starts
{
  Serial.begin(9600);           // Set up serial  
}


void loop()                     // run over and over again
{
  swcIn = analogRead(swcPinin); // look at SWC input pin, store it in swcIn

if (swcIn < 609)                // is swcIn < 609
  {
    if (swcIn > 606)            // and > 606?
    {
      Serial.println ("Vol Dn");  //Yes? Print "Vol Dn" to serial monitor
    }                             //No? Then continue on... 
  }
else if (swcIn < 512)             //Is swcIn < 510? 
  {
    if (swcIn > 505)              //and > 506?
    {
      Serial.println ("Vol Up");  //Yes? Print "Vol Up" to serial monitor
    }                              
  }
else if (swcIn < 320)             //Is swcIn < 320?
  {
    if (swcIn > 317)              // and > 317?
    {
      Serial.println ("Mode");    // Yes? Print "Mode" to serial monitor
    }
  }
else 
  {
    analogWrite (swcPinout, swcIn);  // otherwise pass signal to radio using PWM output on Pin 2
  }
}

From the tutorial, it seems like it should have worked. What am I doing wrong?

Jay

you can only have one else statement for an if statement

if (something == 1) {
   do this...
} else {do this}

What if you put the 2 conditions in one if statement ? Like that:

if ( swcIn < 609 && swcIn > 606 )
  ...
else if ( swcIn < 512 && swcIn > 505 )
  ...
else
  ...

02660:
you can only have one else statement for an if statement

Hmm, no...Well, yes, one "else" but "else if" is valid :slight_smile:

also have a look at a switch

http://arduino.cc/en/Reference/SwitchCase

02660:
you can only have one else statement for an if statement

Hmm, no :slight_smile:
[/quote]

An else if is not an else XD

if (swcIn < 609) // is swcIn < 609
{
if (swcIn > 606) // and > 606?
{
Serial.println ("Vol Dn"); //Yes? Print "Vol Dn" to serial monitor
} //No? Then continue on...
}

Typically, rather than nesting the ifs like that, you would do something like this:

If ((swcIn > 606) && (swcIn < 609))
{
Serial.println ("Vol Dn"); //Yes? Print "Vol Dn" to serial monitor
}
else if ...

There's nothing wrong with a series of else-ifs to check against a set of ranges like that.

What is it doing wrong?

patduino, I believe this won't work, suppose swcIn is 500:

if (swcIn < 609) // true

else if (swcIn < 512) // since first condition was true, this one isn't even checked

He should have used a serie of if's instead of if-else if:

if (swcIn < 609) // true

if (swcIn < 512) // also true

But the range checking method is better :slight_smile:

The original code would never accept a 500 value. After it passed the initial < 609 test (and failed the > 606 test), it would never get into the 609's else block... The logic is reversed.

The code doesn't work because he is testing the values backwards. It could be fixed, but I suggest that he clean it up and use range tests. That'll make it work AND make it easy to follow.

(Also -- 500 isn't a legal value in his code.)

guix:
What if you put the 2 conditions in one if statement ? Like that:

if ( swcIn < 609 && swcIn > 606 )

...
else if ( swcIn < 512 && swcIn > 505 )
 ...
else
 ...






> 02660:
> you can only have one else statement for an if statement



Hmm, no...Well, yes, one "else" but "else if" is valid :)

That seems to be what I was looking for. I figured there was a way to do it, but it wasn't explained in the tutorial I read.

Thanks,

Jay

patduino:

if (swcIn < 609) // is swcIn < 609
{
if (swcIn > 606) // and > 606?
{
Serial.println ("Vol Dn"); //Yes? Print "Vol Dn" to serial monitor
} //No? Then continue on...
}

Typically, rather than nesting the ifs like that, you would do something like this:

If ((swcIn > 606) && (swcIn < 609))
{
Serial.println ("Vol Dn"); //Yes? Print "Vol Dn" to serial monitor
}
else if ...

There's nothing wrong with a series of else-ifs to check against a set of ranges like that.

What is it doing wrong?

It only sees the first part. So it only ever responds to the Volume Dn command...it never does Volume Up, or Mode.

Jay

You need to write those... Add them in the else-if block after the one I supplied.

[Educational question] Do you see where your original code was wrong?

OK. I won't get a chance to check it til tomorrow after work, but I reworked the sketch a little.
Hopefully it will work like this:

int swcIn;                      //Set variable name for SWC reading
int swcOut;                     //Set variable name for SWC output
int swcPinin = 3;               //Set pin for SWC read
int swcPinout = 2;              //Set pin for SWC passthrough output (in case we need it later)

void setup()                    // run once, when the sketch starts
{
  Serial.begin(9600);           // Set up serial  
}


void loop()                     // run over and over again
{
  swcIn = analogRead(swcPinin); // look at SWC input pin, store it in swcIn

if ((swcIn < 609) && (swcIn > 606)) // is swcIn < 609 and > 606
  {
      Serial.println ("Vol Dn");  //Yes? Print "Vol Dn" to serial monitor
  }
else if ((swcIn < 512) && (swcIn > 505))  //Is swcIn < 512 and > 505
  {
      Serial.println ("Vol Up");  //Yes? Print "Vol Up" to serial monitor                              
  }
else if ((swcIn < 320) && (swcIn > 317))  //Is swcIn < 320 and > 317
  {
      Serial.println ("Mode");    // Yes? Print "Mode" to serial monitor
  }
else 
  {
    analogWrite (swcPinout, swcIn);  // otherwise pass signal to radio
  }
}
if ((swcIn < 609) && (swcIn > 606)) // is swcIn < 609 and > 606

Is that how you would verbally describe the range of interest? I doubt it. You are more likely to say "if the value is greater than (or equal) 606 and less than (or equal) 609, do this...". Your code should express the range the same way.

patduino:
You need to write those... Add them in the else-if block after the one I supplied.

[Educational question] Do you see where your original code was wrong?

Yep. When I was searching the Arduino reference and Google looking for how to do an AND in an if...else statement,
I didn't find any reference to &&. Had I seen that earlier, I would have done it that way from the start.

In the revised sketch I posted, while the numbers are "backwards" (checking if less than the high number, and greater than the low number), they should still work, since the conditions are still being met...but I'm going to change them to make it easier to follow.

Also, while I would normally say if it is >= to 608 or <=612, the range is actually 609-611, so using >608 and <612 is still functional, it just saved me a couple of characters. That's all.

Jay

Also, while I would normally say if it is >= to 608 or <=612, the range is actually 609-611, so using >608 and <612 is still functional, it just saved me a couple of characters. That's all.

It does, but it's certainly easier to comprehend the code if the values represent the ends of the range.

For instance, looking at code like:
int randomVal = random(1, 6);
one would expect to get a random number in the range 1 to 6. Well, it will be in that range, but the value will never be 6.

Seems like a dumb decision to me. I don't recommend that you make the same mistakes.

OK. Reworked the sketch a little, and it seems to be doing what I want.
Here's the updated sketch:

int swcIn;                      //Set variable name for SWC reading
int swcOut;                     //Set variable name for SWC output
int swcPinin = 3;               //Set pin for SWC read
int swcPinout = 9;              //Set pin for SWC passthrough output

void setup()                    // run once, when the sketch starts
{
  Serial.begin(9600);           // Set up serial  
}


void loop()                     // run over and over again
{
  swcIn = analogRead(swcPinin); // look at SWC input pin, store it in swcIn

if ((swcIn >= 606) && (swcIn <= 609)) // is swcIn => 606 and =< 609?
  {
      Serial.println ("Vol Dn");  //Yes? Print "Vol Dn" to serial monitor
  }
else if ((swcIn >= 506) && (swcIn <= 509))  //Is swcIn =>506 and =< 509?
  {
      Serial.println ("Vol Up");  //Yes? Print "Vol Up" to serial monitor                              
  }
else if ((swcIn >= 317) && (swcIn <= 320))  //Is swcIn => 317 and =<320?
  {
      Serial.println ("Mode");    // Yes? Print "Mode" to serial monitor
  }
else 
  {
    analogWrite (swcPinout, swcIn/4);  // otherwise pass signal to radio
      {
        delay(150);                     // wait long enough for radio to read it
        analogWrite (swcPinout, 255); // clear the pin so it doesn't keep sending the last command
      }

}
   
}

And the output on the swcPinout (pin 9) gives me the voltage readings I measured in the beginning when I mapped the buttons with my meter (within about .1V or so)...but I believe I've run into a snag. The radio isn't reading the incoming voltage...probably because of the internal pull up resistor. Can I compensate for this via software, or do I need to open up the radio and remove the pull up resistor? Which would be easier? lol

Jay