# Bit Shift Tutorial - Question.

I am working through Heather Dewey-Hagborg’s tutorial on software serial and can mostly follow along except for the bit highlighted below.
I am struggling to understand how the for loop will iterate through 8 bits by the use of the mask and bit shift statement.
As far as I can tell mask will always be greater than 0 so this loop will never end.
I have run this code and it works so what am I not understanding about this for loop?
Any one here care to shed some light to help my brain with this?

Cheers

Peter B.

void SWprint(int data)
{
//startbit
digitalWrite(tx,LOW);
delayMicroseconds(bit9600Delay);
if (data & mask){ // choose bit
digitalWrite(tx,HIGH); // send 1
}
else{
digitalWrite(tx,LOW); // send 0
}
delayMicroseconds(bit9600Delay);
}[/quote]

mask is a byte, so as soon as the 1 is shifted off the end, it will be zero.

The value in mask is initially 0b00000001. After 1 shift, it is 0b00000010. After several more shifts, it is 0b10000000. What happens when another shift occurs? The 1 gets shifted out, and mask becomes 0b00000000.

Groove and PaulS; Thanks for your response, I had missed the point about the 8th left shift operation will mean that mask will then be equal to 0. Seems obvious now.

Cheers

Peter B.

An alternate implementation, that I find easier to read, is -

``````void SWprint(int data)
{
// transmit start-bit
digitalWrite(tx, LOW);
delayMicroseconds(bit9600Delay);

do
{
digitalWrite(tx, ((data & bit_mask) ? HIGH : LOW));
delayMicroseconds(bit9600Delay);
} while ( bit_mask <<= 1 );
...
``````

lloyddean;

Thanks for the follow up, however I am not sure what the line
digitalWrite(tx, ((data & bit_mask) ? HIGH : LOW)); is attempting to do.
I guess this is where you are anding the mask with the data, but what is the ? HIGH : LOW doing?

Cheers

Peter B.

(data & bit_mask) ? HIGH : LOW

is a short-notation for an if statement

if (data & bit_mask) HIGH else LOW

``````digitalWrite(tx, ((data & bit_mask) ? HIGH : LOW));
``````

can also be (cryptically) written

``````digitalWrite(tx, !!(data & bit_mask));
``````

(!)

robtillart;

OK thanks, every time I write a new piece of code or interpret someone else's efforts I learn a new way of doing things. Thank you for the shortcut statement.

Cheers

Peter B.

AWOL;

Thanks also to you. But why would you do it that way? to save a few keystrokes or what! Does it save memory if you use shorter notation to get the result?

Peter B.

In fact, to save most, simply this:

``````digitalWrite(tx, data & bit_mask);
``````

will work.

(this is only because the kind author of "digitalWrite" put the double-NOT (!!) inside "digitalWrite". If they changed the implementation of digitalWrite so that it only accepted HIGH or LOW, the code above would cease to work.)