Displaying a letter in 8x5 LED Matrix

I made a 8 column 5 row LED matrix of which I want to use 4 column and 5 row to display a letter ‘A’ I could somehow display the letter but things are not perfect because

  1. The letter display (or LEDs for letter A) flickers a lot and
  2. It would display (by flickering ) for few seconds and would remain OFF for the equal amount of time time. I failed to figure out why ?

I am using a IC 74HC595 to multiplex the row and scanning the column as evident from my sketch below.

int latchPin = 8;
int clockPin = 12;
int dataPin = 11;
int data[5]={15,20,20,15}; //For Letter A only
void setup()
{
  pinMode(latchPin,OUTPUT);
  pinMode(clockPin,OUTPUT);
  pinMode(dataPin,OUTPUT);
  pinMode(4,OUTPUT);
  pinMode(5,OUTPUT);
  pinMode(6,OUTPUT);
  pinMode(7,OUTPUT);

}

void loop()
{
  for(int j=0;j<4;j++)
  {
    //Scanning Column
    
    if(j==0)
    {
      digitalWrite(4,LOW);
      digitalWrite(5,HIGH);
      digitalWrite(6,HIGH);
      digitalWrite(7,HIGH);
    }
    else if(j==1)
    {
      digitalWrite(4,HIGH);
      digitalWrite(5,LOW);
      digitalWrite(6,HIGH);
      digitalWrite(7,HIGH);
    }
    else if(j==2)
    {
      digitalWrite(4,HIGH);
      digitalWrite(5,HIGH);
      digitalWrite(6,LOW);
      digitalWrite(7,HIGH);
    }
    else if(j==3)
    {
      digitalWrite(4,HIGH);
      digitalWrite(5,HIGH);
      digitalWrite(6,HIGH);
      digitalWrite(7,LOW);
    }
    //Providing O/P to Row
    
    digitalWrite(latchPin,LOW);
    shiftOut(dataPin,clockPin,LSBFIRST,data[j]);    
    digitalWrite(latchPin,HIGH);    
    delay(40);     
  }
  
}

delay(40) is the best delay I could get to display my letter by still its imperfect.

PS: I searched this forum for similar queries but could not find any

You have lots of things that making it slow.

  1. You are using shiftOut( ) to load the 74HC595.
    Use SPI.transfer( ) instead.
    D13 connects to SRCLK
    D11 connects to Ser In
    D10 connects to RCLK (call it ssPin)
    then:
void loop(){
j=j+1;
if (j==4){j=0;}
switch (j){
case 0:
digitalWrite (ssPin, LOW);
SPI.transfer(data[j]);
digitalWrite (ssPin, HIGH);

      digitalWrite(4,LOW);
      digitalWrite(5,HIGH);
      digitalWrite(6,HIGH);
      digitalWrite(7,HIGH);

break;
case 1:
// repeat for next column
:
: 
break;
} // end switch
delay(8);
} // end loop

Can also use blink without delay vs delay(8).
Can also use direct port manipulation vs all the digitalWrites.

You have current limit resistors on the '595 outputs?
Each arduino input should be kept well under 40mA, 20mA ideally. so the current for each segment should be under 1/7 or 1/8 of that.

I tried as you mentioned but none of the LED are glowing. All of them are plain OFF.

Blow is the code

#include <SPI.h>
int ssPin = 10;
int data[5]={15,20,20,15}; //For Letter A only
int j=0;
void setup()
{
  pinMode(ssPin,OUTPUT);
  pinMode(4,OUTPUT);
  pinMode(5,OUTPUT);
  pinMode(6,OUTPUT);
  pinMode(7,OUTPUT);

}

void loop()
{
  j=j+1;
  if(j==0){j=0;}
  switch(j)
  {
    case 0:
    digitalWrite(ssPin,LOW);
    SPI.transfer(data[j]);
    digitalWrite(ssPin,HIGH);
      digitalWrite(4,LOW);
      digitalWrite(5,HIGH);
      digitalWrite(6,HIGH);
      digitalWrite(7,HIGH);
     break;
     
    case 1:
    digitalWrite(ssPin,LOW);
    SPI.transfer(data[j]);
    digitalWrite(ssPin,HIGH);
      digitalWrite(4,HIGH);
      digitalWrite(5,LOW);
      digitalWrite(6,HIGH);
      digitalWrite(7,HIGH);
    break;
    
    
    case 2:
    digitalWrite(ssPin,LOW);
    SPI.transfer(data[j]);
    digitalWrite(ssPin,HIGH);
      digitalWrite(4,HIGH);
      digitalWrite(5,HIGH);
      digitalWrite(6,LOW);
      digitalWrite(7,HIGH);
    break;
    
    
    case 3:
    digitalWrite(ssPin,LOW);
    SPI.transfer(data[j]);
    digitalWrite(ssPin,HIGH);
      digitalWrite(4,HIGH);
      digitalWrite(5,HIGH);
      digitalWrite(6,HIGH);
      digitalWrite(7,LOW);
    break;
      
  }
  delay(8);
}

PS: I am using current limiting resistors

Sorry, typo in my example.
Need a fix here:

if(j==0){j=0;}

to

if(j==4){j=0;} // count from 0,1,2,3,0,1,2,3 ...

Rest looks good.

The typo was in my code, not in your example. Sorry for that. But still, there is no O/P :expressionless:

I changed the line number of j=j+1 since I have declared j=0 above as global variable. Here is the code

#include <SPI.h>
int ssPin = 10;
int data[5]={15,20,20,15}; //For Letter A only
int j=0;
void setup()
{
  pinMode(ssPin,OUTPUT);
  pinMode(4,OUTPUT);
  pinMode(5,OUTPUT);
  pinMode(6,OUTPUT);
  pinMode(7,OUTPUT);

}

void loop()
{  
  if(j==4){j=0;}
  switch(j)
  {
    case 0:
    digitalWrite(ssPin,LOW);
    SPI.transfer(data[j]);
    digitalWrite(ssPin,HIGH);
      digitalWrite(4,LOW);
      digitalWrite(5,HIGH);
      digitalWrite(6,HIGH);
      digitalWrite(7,HIGH);
     break;
     
    case 1:
    digitalWrite(ssPin,LOW);
    SPI.transfer(data[j]);
    digitalWrite(ssPin,HIGH);
      digitalWrite(4,HIGH);
      digitalWrite(5,LOW);
      digitalWrite(6,HIGH);
      digitalWrite(7,HIGH);
    break;
    
    
    case 2:
    digitalWrite(ssPin,LOW);
    SPI.transfer(data[j]);
    digitalWrite(ssPin,HIGH);
      digitalWrite(4,HIGH);
      digitalWrite(5,HIGH);
      digitalWrite(6,LOW);
      digitalWrite(7,HIGH);
    break;
    
    
    case 3:
    digitalWrite(ssPin,LOW);
    SPI.transfer(data[j]);
    digitalWrite(ssPin,HIGH);
      digitalWrite(4,HIGH);
      digitalWrite(5,HIGH);
      digitalWrite(6,HIGH);
      digitalWrite(7,LOW);
    break;
     
  }
  j=j+1;
  delay(8);
}

Other basics:
OE/ is tied LOW and SRCLR is tied HIGH? Can be Gnd and +5.
These 2 pins floating high & low would also cause erratic operation.

LED anodes connect to '595 and cathode/series resistor to Gnd?
(or '595 to resistor to anode, cathode to Gnd)
(you have display, so I would think the LED wiring is okay).

0.1uF cap from '595 pin 16 to Gnd? Power supply decoupling is important at higher switching speeds.

  1. OE or Pin 13 oof 595: Nothing is connected to it. I tried it by connecting it to 5V (and GND) but nothing happened.

  2. Anodes of LED to rows i.e. to 595. Cathodes to pin 4,5,6,7 of Arduino.

  3. Just connected a 0.1uf between Pin 16 and GND.

  4. Connection are as follows: Pin 13 of Arduino to Pin 11 (SHCP) of 595
    Pin 11 of Arduino to Pin 14 (DS) of 595
    Pin 10 of Arduino to Pin 12 (STCP) of 595

'595: connect 13 to Gnd,
connect 10 to +5. Leave them there.

The other 3 are good.

Yes. I did all. I tested all the connections and power etc. All seems fine, but unfortunately no O/P :frowning:

Got me stumped then. I would expect that to work.
If you slow things way down, like delay (5000), do you see the individual IO pins (4-5-6-7) bits changing as expected using a multimeter? Same for the '595 outputs?

Yes, tested the outputs via multimeter, all looks fine.

To test it further, I uploaded my previous sketch by using the same Pins of Arduino as this (new sketch). The LED glows as this

which is almost the result I wanted. Perhaps the flickering effect is gone due to the decoupling capacitor you suggested me to use.

But, its strange that the code which you gave using SPI transfer did not work, I could not figure out why, but for sure that the error is not in hardware part.

Here is the code for the image above

int latchPin = 10;
int clockPin = 13;
int dataPin = 11;
int data[5]={15,20,20,15}; //For Letter A only
void setup()
{
  pinMode(latchPin,OUTPUT);
  pinMode(clockPin,OUTPUT);
  pinMode(dataPin,OUTPUT);
  pinMode(4,OUTPUT);
  pinMode(5,OUTPUT);
  pinMode(6,OUTPUT);
  pinMode(7,OUTPUT);

}

void loop()
{
  for(int j=0;j<4;j++)
  {
    //Scanning Column
    
    if(j==0)
    {
      digitalWrite(4,LOW);
      digitalWrite(5,HIGH);
      digitalWrite(6,HIGH);
      digitalWrite(7,HIGH);
    }
    else if(j==1)
    {
      digitalWrite(4,HIGH);
      digitalWrite(5,LOW);
      digitalWrite(6,HIGH);
      digitalWrite(7,HIGH);
    }
    else if(j==2)
    {
      digitalWrite(4,HIGH);
      digitalWrite(5,HIGH);
      digitalWrite(6,LOW);
      digitalWrite(7,HIGH);
    }
    else if(j==3)
    {
      digitalWrite(4,HIGH);
      digitalWrite(5,HIGH);
      digitalWrite(6,HIGH);
      digitalWrite(7,LOW);
    }
    //Providing O/P to Row
    
    digitalWrite(latchPin,LOW);
    shiftOut(dataPin,clockPin,LSBFIRST,data[j]);    
    digitalWrite(latchPin,HIGH);    
    delay(5);     
  }
  
}

Just found out that this code works better. No other LED glows even a little except the desired ones

int latchPin = 10;
int clockPin = 13;
int dataPin = 11;
int data[5]={15,18,18,15}; //For Letter A only
int j=0;
void setup()
{
  pinMode(latchPin,OUTPUT);
  pinMode(clockPin,OUTPUT);
  pinMode(dataPin,OUTPUT);
  pinMode(4,OUTPUT);
  pinMode(5,OUTPUT);
  pinMode(6,OUTPUT);
  pinMode(7,OUTPUT);
}

void loop()
{  
  if(j==4){j=0;}
  switch(j)
  {
    case 0:
    digitalWrite(latchPin,LOW);
    shiftOut(dataPin,clockPin,LSBFIRST,data[j]); 
    digitalWrite(latchPin,HIGH);
      digitalWrite(4,LOW);
      digitalWrite(5,HIGH);
      digitalWrite(6,HIGH);
      digitalWrite(7,HIGH);
     break;
     
    case 1:
    digitalWrite(latchPin,LOW);
    shiftOut(dataPin,clockPin,LSBFIRST,data[j]); 
    digitalWrite(latchPin,HIGH);
      digitalWrite(4,HIGH);
      digitalWrite(5,LOW);
      digitalWrite(6,HIGH);
      digitalWrite(7,HIGH);
    break;
    
    
    case 2:
    digitalWrite(latchPin,LOW);
    shiftOut(dataPin,clockPin,LSBFIRST,data[j]); 
    digitalWrite(latchPin,HIGH);
      digitalWrite(4,HIGH);
      digitalWrite(5,HIGH);
      digitalWrite(6,LOW);
      digitalWrite(7,HIGH);
    break;
    
    
    case 3:
    digitalWrite(latchPin,LOW);
    shiftOut(dataPin,clockPin,LSBFIRST,data[j]); 
    digitalWrite(latchPin,HIGH);
      digitalWrite(4,HIGH);
      digitalWrite(5,HIGH);
      digitalWrite(6,HIGH);
      digitalWrite(7,LOW);
    break;     
  }
  j=j+1;
  delay(5);
}

Now after all these tests I think something is wrong in the SPI thing

I am stumped. I have used SPI to blast out 45 bytes at a time to 45 shift registers at 8 MHz speeds, updating them at a 20 KHz rate (a new blast of data everto 50uS), the fastest an Arduino will go, and not had any issues.

Back again :slight_smile:
Instead of starting a new post I thought it will be good to continue here.

What I want now is the have a scrolling message at the LED matrix. I have changed my connection, i.e. now I am feeding data to columns and scanning the rows. I can easily scroll a letter by left shifting the column values by 1 but how do I feed new data to the column once the old data has shifted by significant times ?

Since my LED matrix is 5 rows 8 columns, so I decided to display 2 letter at a time, one of which will take 4 columns and the other letter would take rest of the 4 columns

e.g. For my letter 'A', the 5th row's column data would be 11110110 (Column are connected to cathode). Ones this data is shifted left by 1 times, I want the letter 'B's data to take the LSB position, in short I want to keep feeding data so that new text are displayed in the LED after the old ones are shifted significantly, how do I do that ?

What I have done in the past, and the programmers probably laugh at this, is to fill an array with the message, and then move thru the array pulling out data as I go.
So the initial display could be elements 0-7, then 1-8, 2-9, 3-10, etc.
I even got so fancy as to put the message in the internal EEPROM and had several hundred characters scrolling across an 8x32 display that way. Here's a youtube clip of a shorter message:

okay,
Now I have an entirely new problem.

In my 5 row 8 column hardware, all cathode are connected column wise. So that way if Is send 11111110 as column bit, the LED corresponding to bit 0 glows up and rest are OFF. Now if I left shift it by 1 ((11111110)<<1) I get 11111100 and this result in two LED lighting up but I want 11111101 when it left shifts by 1 (Kind of circular shift so that new bit 0 is replaced by bit 7) of the same byte ?

Is this possible ?? I could not figure out a way

That kind of messiness is why have the bytes from memory represent the "vertical" data:

each column is 1 byte of memory, with the upper 3 bits not used, so "A b" might look like this:

00000000
00000000
00000000
11111000
10011000
11111111
10011001
10011111

Well,

I did not get it.

Can you elaborate if you don't mind.