Flicker while making images - 8x8 LED matrix using two 74HC595 shift registers

Hi all!

I am new to arduino and its language, and I am trying to use it to make a school project. My end goal is a pong or tetris type game, using either one or two pre-made single colour 8x8 LED matrices. I am using an arduino uno (from the sparkfun inventor's kit), and I currently have the matrix connected by daisy chaining two 74HC595 shift registers from 3 of the pins on my arduino. I have been able to get all the LED's to light up, and am now trying to make an image on the LED's. I have looked into multiplexing, and I THINK I get the idea. Here is the code I've written for making the image:

byte image[8] = {B00000000, //1 means LED is on, 0 means LED is off
                 B00000000,
                 B00000000,
                 B00010000,
                 B00111000,
                 B00010000,
                 B00000000,
                 B00000000};

void displayImage(byte image[]) {
      int i = B10000000;
    for (int col = 0; col < 8; col++) {
      shiftWrite(col, LOW);         //turns the current column off
      for (int r = 8; r < 16; r++) { //turns off each row in the column
        shiftWrite(r, HIGH);
      }
      for (int row = 8; row < 16; row++) {
        if ((image[row - 8] & i) != 0) { //checks the (8-row)th digit of each binary number in image[]
          shiftWrite(row, LOW);           //turns the corresponding row on if that digit is a 1
        }
      }
      shiftWrite(col, HIGH);  //turns the column on
      delayMicroseconds(200);
      shiftWrite(col, LOW);
      i = i >> 1;
    }
}

void loop() {  
  displayImage(image);
}

Here is the shiftWrite code I wrote for sending the data via the daisy-chained shift registers:

byte dataOne = 0;
byte dataTwo = 0;

void shiftWrite(int desiredPin, boolean desiredState) {
  if (desiredPin < 8) {
    bitWrite(dataOne, desiredPin, desiredState);
  } else {
    bitWrite(dataTwo, desiredPin - 8, desiredState);
  }
  
  shiftOut(dataPin, clockPin, MSBFIRST, dataTwo);
  shiftOut(dataPin, clockPin, MSBFIRST, dataOne);
  
  digitalWrite(latchPin, HIGH);
  digitalWrite(latchPin, LOW);
}

Now, for my problem. Uploading this code onto my arduino, I get very noticeable flicker in all the LED's that are supposed to be on. Also, the LED's are quite dim when running this code. I originally had 330 ohm resistors connected to each column pin on the matrix... I took them off, and the LED's got a bit brighter, but they still flicker a lot, and I am not sure if it is smart to use the matrix without any resistors. I've tried decreasing/increasing the delay between turning each column on and off, but it doesn't help a whole lot. So, to all you bright people out there... what gives? Am I using an inefficient method for making images? Do I need some different hardware? Any help would be greatly appreciated.

why do you keep your column pins off so long?
what's wrong with shifting in the data, moving to the next column and then latching? now you're putting all this effort in clearing everything all the time (both rows and columns) rather than just syncing up the latching & the moving to the next column. If just naively moving to the next row and then latching would give some ghosting, you can turn off the previous column before doing the latching and then turning on the next one.

I've recently been playing around with multiplexing a bit, and seen high level my code usually is:
loop
{
for number of rows
{
shift in new row
move to next column
latch the new row
delay(2) (if you delay 2 milliseconds per row, you still update about 60 times per second, more than fast enough for the human eye, and makes possible ghosting due to not turning off the previous column before latching non existent)
}
}

and it gives great results :slight_smile:

Thanks so much for the help! I'm actually quite new to microprocessors/circuitry as a whole, so I'm not 100% sure what you mean by shifting the data and then latching. However, I think I get the idea.... I rewrote my code so that I broke my shiftWrite function into two parts:

void shiftBit(int desiredPin, boolean desiredState) {
  if (desiredPin < 8) {
    bitWrite(dataOne, desiredPin, desiredState);
  } else {
    bitWrite(dataTwo, desiredPin - 8, desiredState);
  }
}


void shiftWrite(){  
  //shifts to the second shift register first
  shiftOut(dataPin, clockPin, MSBFIRST, dataTwo);
  shiftOut(dataPin, clockPin, MSBFIRST, dataOne);
  
  digitalWrite(latchPin, HIGH);
  digitalWrite(latchPin, LOW);
}

I now only have to shift dataOne and dataTwo out once per loop, and look at that... No flicker!!

Thanks so much! XD

Cailans:
Thanks so much for the help! I'm actually quite new to microprocessors/circuitry as a whole, so I'm not 100% sure what you mean by shifting the data and then latching.

you have a shift register, so shifting in the data is with serial signals filling it up :
shiftOut(dataPin, clockPin, MSBFIRST, dataTwo);
and your shift register is latched, meaning that it won't immediatly put the data it's got to its output pins, it waits for you to give the signal when to put that data onto the output pins:
digitalWrite(latchPin, HIGH);
digitalWrite(latchPin, LOW);

now you know why the method is called shiftOut, and why the latchpin is called the latchpin :).