How to properly use an if statment

Hi Folks,

I am building a robot and I have this in my code

//Go Straight if the center sensors are under the line
 if ((S0==1 && S1==1 && S2==1 && S3==1 && S4==0 && S5==0 && S6==1 && S7==1 && S8==1 && S9==1) 
       
                            {
                            pwmright = 0;
                            pwmleft = 0;
                            analogWrite(analogleftPin, pwmleft);
                            analogWrite(analogrightPin, pwmright);
                            lcd.home ();   
                            lcd.print("           **STOP**                                 ");
                            //delay (500);
                            }    
                            else

So while only S4 and S5 are zero everything works as expected, however say S4 and S5 and S6 and S7 are both zero, it just continues acting as if the statment was still true, until a next true statment is found.

What can i do in order to solve this issue? Perhaps if is not the best to use?

Also is there a way I could use

else if(binary == 0b1111001111)

instead of

 if ((S0==1 && S1==1 && S2==1 && S3==1 && S4==0 && S5==0 && S6==1 && S7==1 && S8==1 && S9==1)

however say S4 and S5 and S6 and S7 are both zero

both implies 2. You list 4 variables. Try again.

Also is there a way I could use

Not exactly like that. You could construct the value in the variable called binary using bitWrite() using the values of Sn to set bit n.

if ((S0==1 && S1==1 && S2==1 && S3==1 && S4==0 && S5==0 && S6==1 && S7==1 && S8==1 && S9==1)

Should be

if ((S0==1) & (S1==1 )& (S2==1) &( S3==1 )&( S4==0 )& (S5==0)& (S6==1 )& (S7==1 )&(S8==1 )&( S9==1) )

I would be inclined towards a solution that makes the code easier to understand, unless doing so screws up performance or cause you to run out of RAM.

What about creating a variable with a meaningful name (perhaps combinedSensors) that is the sum of the pieces S0, S1 etc and then testing if that holds some particular value.

If S0 = 0 or 1, s1 = 0 or 2, s2 = 0 or 4 etc then when added together there will always be a unique value for the combination. You could store the combination tests in variable such as straightAhead = 128 and then the test would be if (combinedSensors == straightAhead) ....

...R

PaulS:

however say S4 and S5 and S6 and S7 are both zero

both implies 2. You list 4 variables. Try again.

I didnt got that one sorry

PaulS:

Also is there a way I could use

Not exactly like that. You could construct the value in the variable called binary using bitWrite() using the values of Sn to set bit n.

Could you exemplify?

I don't see the other matching parens for the one just to the left of S0. Does this compile?

Robin2:
I would be inclined towards a solution that makes the code easier to understand, unless doing so screws up performance or cause you to run out of RAM.

What about creating a variable with a meaningful name (perhaps combinedSensors) that is the sum of the pieces S0, S1 etc and then testing if that holds some particular value.

If S0 = 0 or 1, s1 = 0 or 2, s2 = 0 or 4 etc then when added together there will always be a unique value for the combination. You could store the combination tests in variable such as straightAhead = 128 and then the test would be if (combinedSensors == straightAhead) ....

...R

Yes the code is ridiculously huge for what it does!

Can you exemplify a way i could do that? What about if the condition was in between two diferent values, like 128 and 192?

Kind Regards

KeithRB:
I don't see the other matching parens for the one just to the left of S0. Does this compile?

Sure, this is just part of the code.

casemod:
Can you exemplify a way i could do that? What about if the condition was in between two diferent values, like 128 and 192?

You are in charge. It will only be between two values if you want it to be.

I don't know what extra example you want. Can you explain what you don't understand?

...R

Just a line of code to exemplify how I would do that.

Would it be something similar to:

int my_variable=(S1+S2+S3+S4...);

If my_variable == 100

{
do action a;
}

else
if my_variable == 120

{
do action b;
}

Also, how do i define a variable in between to values? Something that goes from 128 to 255, for example

Regards

Would it be something similar to:

No. Just adding up a bunch of 0s and 1s is not going to produce a useful value. Look at the bitWrite() function I mentioned.

Robin2:
I would be inclined towards a solution that makes the code easier to understand, unless doing so screws up performance or cause you to run out of RAM.

What about creating a variable with a meaningful name (perhaps combinedSensors) that is the sum of the pieces S0, S1 etc and then testing if that holds some particular value.

If S0 = 0 or 1, s1 = 0 or 2, s2 = 0 or 4 etc then when added together there will always be a unique value for the combination. You could store the combination tests in variable such as straightAhead = 128 and then the test would be if (combinedSensors == straightAhead) ....

...R

That's why there's bits.

"Sure, this is just part of the code."
A pretty important part.
You have: if ((S0....S9==1)

2 parens on one side and 1 on the other.

Oh... Yes I got the expression from this statment and forgot to take the bracket

if ((S0==1 && S1==1 && S2==1 && S3==1 && S4==1 && S5==1 && S6==1 && S7==1 && S8==1 && S9==1) || (S0==0 && S1==0 && S2==0 && S3==0 && S4==0 && S5==0 && S6==0 && S7==0 && S8==0 && S9==0))

I just removed the or statment and forgot to take the bracket off :wink: Well spotted tough!

PaulS:

Would it be something similar to:

No. Just adding up a bunch of 0s and 1s is not going to produce a useful value. Look at the bitWrite() function I mentioned.

I see your point about faster read times which actually come handy. I'm doing this to archieve faster read times

 //read the sensors value into a variable
        int S0 = bitRead(PORTD,2);
        int S1 = bitRead(PORTD,3);
        int S2 = bitRead(PORTD,4);
        int S3 = bitRead(PORTD,5);
        int S4 = bitRead(PORTB,5);
        int S5 = bitRead(PORTB,4);
        int S6 = bitRead(PORTB,3);
        int S7 = bitRead(PORTB,0);
        int S8 = bitRead(PORTD,6);
        int S9 = bitRead(PORTD,7);

but that doesnt help my question. Basically instead of this

 if (S0==1 && S1==1 && S2==1 && S3==1 && S4==1 && S5==1 && S6==1 && S7==1 && S8==1 && S9==1)

I would wish to have this

if PortD = (0b11111111)
{
do something
}

Or better yet, how do i assign a decimal value to this combination, since I have a few bits in different ports and I want to create a single variable

but that doesnt help my question

Maybe because you used bitRead instead of bitWrite.

 if ((S0==1 && S1==1 && S2==1 && S3==1 && S4==1 && S5==1 && S6==1 && S7==1 && S8==1 && S9==1) || (S0==0 && S1==0 && S2==0 && S3==0 && S4==0 && S5==0 && S6==0 && S7==0 && S8==0 && S9==0))

If all of those are going to be zero or non-zero then you should be aware that 0==FALSE and non-0==TRUE.
Also that NOT is spelled ! so that the above could be written:

 if (( S0 && S1 && S2 && S3 && S4 && S5 && S6 && S7 && S8 && S9 ) || ( !S0 && !S1 && !S2 && !S3 && !S4 && !S5 && !S6 && !S7 && !S8 && !S9 ))

If all of those are going to be either 0 or 1 then each uses 1 binary bit. A 16 bit unsigned int can hold them all and it takes almost no time or code to check them.

You can read, write, set or clear bits in many different ways. Arduino includes user-friendly functions just to do that.
The Reference, look under Bits and Bytes halfway down the right side: Arduino - Home
bitWrite() -- http://arduino.cc/en/Reference/BitWrite

If you make an unsigned int and set the low 9 bits (set means 1's, clear means 0's), it will be 511. All 0's makes 0. Your long line of checks becomes

 if (( myVar == 511 ) || ( myVar == 0 ))

or

 if (( myVar == 511 ) || ( !myVar ))

To make what is now S5 equal 0 you would
bitWrite( myVar, 5, 0 ); // to make it a 1, change the 0 to 1

casemod:
Just a line of code to exemplify how I would do that.

There has been a good bit of water through the bridge since my last post here and my approach is a bit (forgive the pun) different so as to be easier to understand. It won't function any better.

Suppose that S1 has a value of 0 or 1 depending on whether its bit is 0 or 1
Suppose that S2 0 or 2 0 or 1
Suppose that S3 0 or 4 0 or 1

Now if you add all three together when all the bits are 1 you get 7
If you add them all when the bit for S2 is 0 you get 5
And the number will always be unique to the combination of bits because the binary versions of the numbers 1, 2, 4, 8 etc each have a bit in a unique position.

Now you can create test variables such as allOn = 7, or oneAndThreeOn = 5 and your code can be

sumSwitchVals = S1 + S2 + S3;
if (sumSwitchVals == allOn) {

}
if (sumSwitchVals == onAndThreeOn) {

}

Of course you would have more meaningful names for the test variables.

This concept is very close to the code snippet you showed except that I have separate values (in powers of 2) for each of the Sx variables.

...R

That's cool too. It works!

Working with bits lets you deal with numbers as bit patterns in the fastest way (in this case, add is just as fast) because the CPU works that way. That's why languages that even begin to get "close to the metal" all have bit manipulation commands. Thinking bits makes using them far easier than thinking numbers, hence an approach to an approach, sort of, a way to orient ourselves to the machine.

Guess which works "better" or at least no slower in a loop?

1 = bit( 0 ) = 1 << 0
2 = bit( 1 ) = 1 << 1 = 1 x 2
4 = bit( 2 ) = 1 << 2 = 1 x 2 x 2
etc.

If the x 2 method is as fast, that's because the compiler optimized it to left shifts ( << ).

GoForSmoke:
That's cool too. It works!

I'm not sure if you are referring to my post.

I would prefer to use numbers rather than bits within a byte just because its easier to follow where ultimate speed is not required. Remembering which bit is which gets a bit harder if you need more than 8 and have to use an int.

...R