Need to refresh 4-digit 7-segment display?

My kids and I are working with a multifunction shield like this one and trying to display numbers on the four-digit 7-segment LED display. It looks like the display is managed through a pair of 74HC595 shift registers. When I want to put a value in a particular digit, I call this function:

void WriteNumberToSegment(byte Segment, byte Value)
{
  digitalWrite(LATCH_DIO,LOW); 
  shiftOut(DATA_DIO, CLK_DIO, MSBFIRST, SEGMENT_MAP[Value]);
  shiftOut(DATA_DIO, CLK_DIO, MSBFIRST, SEGMENT_SELECT[Segment] );
  digitalWrite(LATCH_DIO,HIGH);    
}

where SEGMENT_MAP and SEGMENT_SELECT are arrays of bitmaps specified earlier in the code.

I was surprised to find that after displaying four digits, if our code used the delay function to wait a bit before changing the display, all but one of the digits would go out. We apparently need to send the values for each digit frequently... you can't just set the display to what you want, go off and do something else, and expect the display to stay the way you left it.

However, in an earlier experiment, we connected eight LEDs to a shift register, and they didn't appear to require constant refresh to stay on. We could just use delay to wait between changes to the LED pattern.

Can anyone help us understand why the frequent refresh is needed in this case? If we wanted avoid needing to do this, what alternatives would we have? I'm guessing something like a MAX7219 might be appropriate here?

Thanks in advance for any links or advise you can offer!

Hi,

Its called multiplexing. Doing more with less, so to speak.

With your 8 leds and shift register, there was a shift register output for every led.

With your 7 seg display, you have 32 leds but only 16 shift register outputs (and actually only 12 of the 16 are used).

To make 12 outputs drive 32 leds, its neccessary to light only one group of the leds at any instant, but switch groups frequenly so they all get lit regularly. Do this fast enough and the eye thinks all the leds are lit, because of a property of the human eye called "persistence of vision".

To avoid having the Arduino perform the multiplexing, either increase the number of outputs to match the number of leds (4 shift registers, 32 outputs) or buy a chip that does the multiplexing for you (like your example of max7219).

Paul

Paul - I thought it'd be something like that, but thanks to your explanation things are much clearer for us now. I'm still going to need to read up some more about how multiplexing works in general, but at least I know we're not doing something wrong... it's just a limitation of this particular board, and different hardware could take care of things if we didn't want to deal with it in software.

Thanks again very much for your helpful response!

Now the MAX7219 is specifically designed to perform this function for you, and also includes more heavy-duty drivers to provide sufficient current for a bright display.

If you wish to "do it yourself", then you need to fully understand the concept of the "loop()" in coding, it must be continuously looping with no interruptions.

"delay()" is virtually never used in "real world" applications, nor is "busy waiting" using "while()" loops.

What you do in your loop() is to firstly display the next digit, so you need a stepping index to the current digit. Whilst you could structure it as such, you generally do not use a for() loop for this as you would then have to make that the entire loop content and place the rest of your program inside.

In any case, the remainder of the loop follows so that when all other steps have been considered, it returns to the top of the loop and again - displays the next digit. Every other step in the loop follows the same rule - a decision is made whether something needs to be done, if so it is done and immediately completed, if not the code passes on to the next task. If anything cannot be done immediately, a "flag" is set so that on future passes, a further test is made as to whether it can be completed at that time.

If something must be performed at a regular time (such as in fact, going on to the next multiplexed digit, so that all digits receive equal exposure), then this is determined by reading the system clock ("millis()") and comparing it to a previously determined "event" time at which point the awaited step will be performed.

The processor never waits.