Difference between = and |= and &= ???

I was looking over a library and noticed some code that I don't quite understand.

PORTC |= B00100000
PORTC &= B11011111

I do understand that - for example, with an Arduino NANO, pin number A5 is being set high on the first line then low on the second line, but what is happening here with the |= and the &= vs just using =? does it have anything to do with ONLY changing the value of pin A5 and leaving the other pins unchanged? If not, what do those modifiers actually do?

Thank you,

Mike Sims

does it have anything to do with ONLY changing the value of pin A5 and leaving the other pins unchanged?

It has everything to do with that

PORTC |= B00100000  //put the result of bitwise OR of PORTC and 0b00100000 into PORTC
PORTC &= B11011111 //put the result of bitwise AND of PORTC and 0b11011111 into PORTC

After I created this post, I looked more closely at the modifiers and I realized that the || modifier is also used in if ... else statements as an OR test for boolean variables and the && operator as an AND test between boolean variables.

So, using that line of thinking, when I look at the PORT modifier lines, when I look at the first one, and lets say we take the LSB which is 0 ... if we OR that bit with whatever is in the register, then that register bit will not be changed. Same for the second line ... if I logically AND the bits that are set to 1 with any value that might already be in that register, its value will not change.

So I think the answer to the question is in fact that we are only actually affecting change on pin A5 ... or more precisely, in the first line, we are guaranteeing that pin A5 gets set high regardless of its current state, and in the second line, we are making sure that pin A5 gets set low, regardless of its current state, while simultaneously casing no change at all on the remaining 7 pins.

Am I correct?

UKHeliBob:
It has everything to do with that

OK, perfect. I had no idea we could do direct changes to pins like that without using the digitalWrite command. I was always under the impression that when you used PORT, you had to affect change on all 8 pins at the same time which could cause problems if you didn't need to affect change on all 8 pins.

One wonders why you would use digitalWrite at all given the enormous speed advantage of using direct PORT change.

EasyGoing1:
One wonders why you would use digitalWrite at all given the enormous speed advantage of using direct PORT change.

Portability between different boards.

Am I correct?

Yes, but don't whatever you do confuse the bitwise operators such as & and | with the boolean operators such as && and ||

See Arduino reference for details of more bitwise and compound operators

TheMemberFormerlyKnownAsAWOL:
Portability between different boards.

AH HA! Of course!

UKHeliBob:
Yes, but don’t whatever you do confuse the bitwise operators such as & and | with the boolean operators such as && and ||

See Arduino reference for details of more bitwise and compound operators

Perish the thought … && and || are for evaluation whereas |= and &= commit actual change.

EasyGoing1:
Perish the thought ... && and || are for evaluation whereas |= and &= commit actual change.

FAR more importantly, and FAR more correctly - && and || are BOOLEAN operators. The operands are evaluated as boolean values (each being either true or false), then LOGICALLY combined to create a final boolean result which is either true or false. & and | are BITWISE operators, which perform BITWISE boolean operations on two multiple bit operands, and create a multiple bit result. In other words, &&/|| and &/| perform completely different functions on completely different operands, and produce completely different results.

Regards,
Ray L.

RayLivingston:
FAR more importantly, and FAR more correctly - && and || are BOOLEAN operators. The operands are evaluated as boolean values (each being either true or false), then LOGICALLY combined to create a final boolean result which is either true or false. & and | are BITWISE operators, which perform BITWISE boolean operations on two multiple bit operands, and create a multiple bit result. In other words, &&/|| and &/| perform completely different functions on completely different operands, and produce completely different results.

Regards,
Ray L.

Yes, I understand. However, from the context of thinking through the process of what is actually happening - from an understanding point of view - && and || take two boolean values, then either AND them together or, OR them together, returning the result of the ANDing or ORing to you, the programmer, after which code flow can be directed based on those results. The boolean values that you are comparing are not altered.

HOWEVER, with |= and &=, you are instructing the program to take two different bit values (in this case, the current value of the pin and the value to which you wish to boolean operate against the current pin value), then change the value of that pin to the result of the chosen boolean operation.

When I said that I considered the | and & symbols in the context of || and && I was merely using logical deduction, applying the rules that are specific to each symbol (| being OR, and & being AND) then deducing that preceding the equal sign with either symbol will produce the effect of setting the bits to the value that comes out of the OR or AND operation.

I wasn't confusing - by any stretch of the imagination - || vs |= ... on the contrary, I was able to answer my own question by using simple logical deduction under the assumption that the language would treat the symbols in like manner but obviously in vastly different contexts.

Continuing with that logic, I would assume (although I have never done nor seen done before) I could change a boolean variable using the exact same method.

If, for example, if mybool = false and yourBool = true, I could do this:

myBool &= yourBool;

would be the same thing as

myBool = myBool & yourBool;

Which would leave myBool unchanged because false AND true = false

whereas

myBool |= yourBool;

would be the same thing as

myBool = myBool | yourBool;

Which would change myBool to true because false OR true = true