Fastest way to cycle through 3 bit Digital out

Hello Arduino community!

I have a 4051 8 channel multiplexer connected to the Arduino.
The channel of the multiplexer is controlled by 3 digital out pins (5-7).

I now need to cycle through all 8 channels.

From the playground 4051 tutorial I started with

for (count=0; count<=7; count++) 
{
    // select the bit  
    r0 = bitRead(count,0);    // use this with arduino 0013 (and newer versions)     
    r1 = bitRead(count,1);    // use this with arduino 0013 (and newer versions)     
    r2 = bitRead(count,2);    // use this with arduino 0013 (and newer versions)     

    digitalWrite(5, r0);
    digitalWrite(6, r1);
    digitalWrite(7, r2);

    // do something
}

This proved to be really slow.

So the next idea was to use direct port manipulation to speed things up.

PORTD = B00000000
// do something
PORTD = B00100000
// do something
PORTD = B01000000
// do something
...

Is there a way to use a loop for this?

Preferably I would like not to change the value of the lower 5 bits but obviously I do want to assign the highest 3 bits.
Is there a way to do this in one assignment possibly using a bitwise operator?

I know about the fastDigitalWrite library but at this point I would prefer to do it directly without an external library.

Thank you very much for your kind help!!
Have a nice day!
Tom

Is there a way to use a loop for this?

Yes look at the code in this project:-
http://www.thebox.myzen.co.uk/Hardware/MIDI_Footsteps.html

for (byte i = 0 ; i < 8 ; i++)
{
  PORTD = (PORTD & 0x1F) | (i << 5) ; // only change top 3 bits of port D (pins 5,6,7)
  // do something
}

Awesome, thanks a lot, I appreciate the help very much! :slight_smile:

One more question, if I would like to cascade multiplexers and use pins 2, 3 and 4 to control the second "level", would this be the appropriate code?

for (byte i = 0 ; i < 8 ; i++)
{
    PORTD = (PORTD & 0x1F) | (i << 5) ; // only change top 3 bits of port D (pins 5,6,7)
    
    for(byte j = 0; j < 8; j++)
    {
      PORTD = (PORTD & B11100011) | (j << 2);
    }
}

Thats really just a 6 bit address, one loop is enough:

for (byte i = 0 ; i < 64 ; i++)
{
  PORTD = (PORTD & 0x03) | (i << 2) ; // only change top 6 bits of port D
  // do something
}