Multiplexing a 7 Seg LED display

After having experimented with all manner of displaying digits on a 7 Seg display and eventually realising that none of them were actually multiplexed, I have cobbled together a few codes written by other people. I had seen some demonstrations where people had started the multiplexing with a noticeable delay between individual segment displays and then progressively reducing the delay until it was inperceivable and thus displaying a steady digit. I have altered the delay function so now it decreases to a certain point but then goes back to the initial delay period. I can see why it does this but I cannot work out how to get the delay period short enough to allow for the steady digit display I am aiming for. Can anyone please offer me a gentle nudge in the required direction :smiley:
Thanks Pedro

  //  7-Segment LED counter, multiplexing using 74HC595 8-bit shift register.
  // Code mangled together from these sources - thanks fellas
  const int latchPin = 5;  //Pin connected to Pin 12 of 74HC595 (Latch)
  const int dataPin  = 6;  //Pin connected to Pin 14 of 74HC595 (Data)
  const int clockPin = 7;  //Pin connected to Pin 11 of 74HC595 (Clock)
  int timer = 500;
  const byte number = B11111110;  // Describe each digit in terms of display segments
  void setup()
    pinMode(latchPin, OUTPUT);  //set pins to output
    pinMode(clockPin, OUTPUT);
    pinMode(dataPin, OUTPUT);
  void loop()
  void show( byte number)
    /* Loop over each segment in the "number" we're about to display,
     * and illuminate only one segment at a time.
    for(int j=0; j<=7; j++)
      byte toWrite = number & (0b10000000 >> j); 
      if(!toWrite)  // If all bits are 0 then no point writing it to the shift register,so break out and move on to next segment.
      shiftIt(toWrite); // Otherwise shift it into the register
  void shiftIt (byte data)
    digitalWrite(latchPin, LOW); // Set latchPin LOW while and clock these 8 bits in to the register to illuminate a single segment.
    for (int k=0; k<=7; k++)
      digitalWrite(clockPin, LOW);  // clockPin LOW prior to sending bit
      /* Do another bitwise AND against a mask to check the state of
       * each bit as we clock it in.
       * Note that in our case, we need to set pinState to 1 (HIGH) for
       * "On" as the 74HC595 is sourcing current when using a common cathode display 
      if ( data & (1 << k) )
        digitalWrite(dataPin, HIGH); // turn "On"
        digitalWrite(dataPin, LOW); // turn "Off"
      digitalWrite(clockPin, HIGH);  // and clock the bit in
    digitalWrite(clockPin, LOW);  //stop shifting out data 
    digitalWrite(latchPin, HIGH); //set latchPin to high to lock and send data
    // put delay here if you want to see the multiplexing in action!
    delay (timer = (timer - 10));
    if(timer <=1)
      timer = 500 ;

How is the hardware for this connected up?

Here is the circuit CR. I realise that I could use common anode display with TPIC6B595 but I am interested in using this hardware setup purely to try and gain a fuller understanding of the coding required to multiplex via this hardware. I have tried other methods such as DPM and directly from the Arduino pins as explained in one of my previous questions here

Edit - attached correct circuit diagram 21 Sep 2013

  1. VCC is not connected to 5V. Fix that, with the 0.1uF cap from the Vcc pin to Gnd.
  2. MR is not connected to 5V. Fix that. It does not need a cap.
  3. OE/ is connected to Gnd, that's ok. Could connect to a PWM output pin for brightness control.

  4. This appears to be a common cathode display, with a single current limit resistor. Your plan is to drive 1 segment high at a time so that the illumination level stays consistent? (5V - 2.2V)/220 = 12mA assuming typical Red display. Each segment on 1/7 of the time, so that will appear dimmer.

Whole point of this exercise is to save 6 resistors?

I would go at it like this with this setup and assumed operation of #4.

void loop(){
currentMicros = micros();
elapsedMicros = currentMicros - previousMicros;
if (elapsedMicros >= onTime){  // onTime of 500 to 1000
previousMicros = previousMicros + on Time;
nextSegment = nextSegment +1;  // loop thru the segments, 0-7
if (nextSegment == 8){ nextSegment = 0;}
} // end time check

/* then do whatever else you, 
 including updating displayArray[] every so often with new data to display
based on serial data received, switches thrown, counting something, etc */
// example, new digit once a second
elapsedTime1 = currentMicros - previousMicros1;
if (elapsedTime1 >= onTime1){  // onTime = 1000000UL, 1 second
digitToDisplay = digitToDisplay +1;
if (digitToDisplay == 10){digitToDisplay = 0;}
case 0:
displayArray[] = {0,1,1,1,1,1,1,1,}; // asssumes DP,G,F,E,D,C,B,A
//      A
//  F       B
//      G
// E        C
//      D        DP
case 1:
displayArray[] = {0,0,0,0,0,1,1,0,};
: // defining the other  digits is left as an exercise for the reader
case 9:
displayArray[] = {0,1,1,0,1,1,1,1,};
} // end switch
} // end 1 second check
} // end loop

Thanks CR. I don't know what I was thinking when I drew this circuit diagram in my lunch break at work today :grin: I can assure you that I do not actually have it connected up as such. I keep putting caps on the MR pin because I was under the misapprehension that both VCC and MR should have them, so I will remove the cap on MR. I am not wealthy but I can afford a few 220 ? resistors, I am only doing it this way to try and improve my rudimentary coding knowledge. I will have a look at your suggestions and see how I go. Thanks a lot for your help ... again.

Ok, let me know. That code was not compiled, shouldn't be too far off tho.

Will do. Thanks heaps :smiley: