My multiplexing with port manipulation

Hello,
I was having brightness issues with using the relatively slow digitalWrite command; even digitalWriteFast was not fast enough...so I took to direct port manipulation. The result was so much current I had to switch out my MOS drivers!

Just wanted to share my initial success with multiplexing in the hope that it will help any other relative newcomers like myself. I promise this is some of the fastest multiplexing coding out there (just four lines). It could possibly be faster if your column and row pins have their own ports, but since I needed 7 for rows/columns they are spread out across B C D and F. Of course you will have to re-purpose the port addresses for your own chip if you are not using a Micro.

Since this is for an art project, I wanted code that would allow me to number my segments 1, 2, 3... and enter which ones to illuminate into an array, and the code would do the rest. It takes the numbers, separates them into a row/column matrix of 0's and 1's, and in turn converts them into arrays of bytes to manipulate the ports directly. The main loop code simply sets the ports for each column in turn. Since most of the programming occurs in setup, the main loop is extremely efficient.

The next thing I am going to tackle is dimming individual segments in and out; any ideas?

/*
 Multiplexing with direct port manipulation for Arduino Micro
 */

const int columnPins[] = {3, A0, A1, A2, A3, A4, A5};
const int rowPins[] = {13, 5, 6, 9, 10, 11, 12};
const int SegmentSize = (sizeof(Segments)/sizeof(int));

const int Segments[] = {1, 2, 3}; //enter which segments you want to illuminate here


  int pixel = 0;
  int columnLevel = 0;
  int rowLevel = 0;
  int segmentArray[7][7];
  byte rowSegB[7];
  byte rowSegC[7];
  byte rowSegD[7];
  byte colSegD[7];
  byte colSegF[7];
  
  
void setup() {
  for (int i = 0; i < 7; i++) { //initialize row and column pin mapping
    rowSegB[i] = B00000000; 
    rowSegC[i] = B00000000;
    rowSegD[i] = B00000000; 
    colSegD[i] = B00000000;
    colSegF[i] = B00000000;
  }
  
  for (int i = 0; i < 7; i++) //set pins as outputs
  { 
    pinMode(rowPins[i], OUTPUT);
    pinMode(columnPins[i], OUTPUT);
  }
  
    for (int pixel = 0; pixel < SegmentSize; pixel++) //convert Segments into segment array
  {
    rowLevel = Segments[pixel] / 7;
    columnLevel = (Segments[pixel] % 7);
    segmentArray[rowLevel][columnLevel] = 1;
  }
  
  //convert Segment Array into direct port pin map
  for (int colCount = 0; colCount < 7; colCount++)
  {
    for (int rowCount = 0; rowCount < 7; rowCount++)
    {
      if (segmentArray[rowCount][colCount] == 1)
      {
        if (rowCount == 0)
        rowSegC[colCount] |= 10000000;
        if (rowCount == 1)
        rowSegC[colCount] |= 01000000;
        if (rowCount == 2)
        rowSegD[colCount] |= 10000000;
        if (rowCount == 3)
        rowSegB[colCount] |= 00100000;
        if (rowCount == 4)
        rowSegB[colCount] |= 01000000;
        if (rowCount == 5)
        rowSegB[colCount] |= 10000000;
        if (rowCount == 6)
        rowSegC[colCount] |= 01000000;
      }
    }
  }
  //set column port mapping
  colSegD[0] = B00000001;
  colSegF[1] = B10000000;
  colSegF[2] = B01000000;
  colSegF[3] = B00100000;
  colSegF[4] = B00010000;
  colSegF[5] = B00000010;
  colSegF[6] = B00000001;
  
  
}

void loop() {
 for (int colCount = 0; colCount < 7; colCount++) { //for each column,
  PORTF = colSegF[colCount];
  PORTD = rowSegD[colCount] | colSegD[colCount];
  PORTB = rowSegB[colCount];
  PORTC = rowSegC[colCount];
  delay(50);
 }
}

Maybe you can glean some ideas from, and expand upon, my "research".

http://forum.arduino.cc/index.php?topic=171567.0

Runaway Pancake,
I'm pickin' up what you're puttin' down. No PWM, simple, clean, easy. But I can't help but wonder what one PWM pin and some multiplexing would do. Give them a common ground and use one pin per element. Then scan through them one at a time with different PWM values, subtracting x from PWM value each time. This is why all my grounded columns are run to PWM pins.

        rowSegC[colCount] |= 01000000;

You do realise those are octal constants (leading 0) not binary.
Perhaps you meant:

        rowSegC[colCount] |= 0b01000000;