Another 7 Segment Display driven by Shiftregister

Hi Folks,

right before anyone posts the "use the search"-Thread... I did for about 1 hour.
Sadly didn't find a solution for my problem.

I tried to drive a 4 digit 7 Segment Display with 2 HC595N in series.

The first one is connected to all 8 Segments while the second powers the 4 digit lines. (one by one ofc)

I've been coding whole evening, got some results but one very weird problem.
I can only drive 2 of the 4 digits at once otherwise it get's messy... Simply can't figure out why...

Anyone got a solution or a reasonable explanation what is going wrong?

SR.h (2.33 KB)

// Here's where the trouble occurs during testing
      digitalWrite(latchPin, LOW);
      digitalWrite(latchPin, HIGH);
      digitalWrite(latchPin, LOW);
      digitalWrite(latchPin, HIGH);
      /*digitalWrite(latchPin, LOW);
      digitalWrite(latchPin, HIGH);
      digitalWrite(latchPin, LOW);
      digitalWrite(latchPin, HIGH);*/

Well, besides having 2 digits commented out, you're not leaving any digit on for very long. You need to leave each digit on a for a few milliseconds each.

I commented them out because it ended up in a mess with all 4 blocks active.
Strange thing is it was working nomatter which of the 4 blocks was active or not whilst it were only 2 active at the time.

But this morning I came up with a working solution.
Instead of generating the bytes to send in refresh I stored them in a array and just read them out while refreshing.

Another thing bugging me is pow(2,x) ... For some reason it didn't work. In the end I had to replace it with a static array of {1,2,4,8} to make the code work.
Not the smartest solution but it did the trick.

SR.h (1.75 KB)

Surely you would look at existing solutions. The general principles apply:

  1. write segment bits and enable one digit select bit.
  2. run this for about 5ms.
  3. repeat for next digit.

This is known as multiplexing. Persistence of Vision will make it look as if all 4 digits are lit at the same time.

You can either use direct port pins or set the bits via your shift registers.
You can use a 5ms Timer interrupt or use a delay(5)

It is wise to use a 4-byte display buffer to hold the segment data for each digit. i.e. you only look up the segments when you change a value.

Think about the pow() function. It uses floating point arithmetic. Far easier to use integer shift e.g. (1 << digit)

Remember that 4 digits mean the peak segment current is 4x average. e.g. 12mA for 3mA average
And the digit select means one pin is sinking up to 8 segment peak current. e.g. 96mA for "8."

It is unlikely that you are displaying "" but it is wise to design for the possibility. i.e. high current shift register or extra transistors for digit select.


At the moment I'm happy with the functionality of my code.
I need just a basic number display (no text or something alike) for displaying a temperature and some blinking (with delays) to indicate the setting of a new target temperature.
I don't think I want to implement another library... maybe for future projects.

Looks like I searched in the wrong category. Sorry for that.

I just looked up the datasheet of my 595 registers they support up to 35mA.
Since I don't want the display to be very bright I'm using a 1k resistor for each digit.
If my calculations are correct I end up having a max. current of something less than 5mA.

Not only it doesn't flash my eyes it should also extend the lifetime of both register and display.

But thank you very much for your advise.
I'll definitly consider some of them in the future.
Like I'm also interested in building a LED cubus with wireframe, maybe a high current shift register is a good idea for that future project.