(Sorry this is a tad long, but I've marked the questions in bold!)

So I found these 14-segment alphanumeric LEDs online and wanted to control 16 of them using a TI microcontroller. Each alphanumeric LED has 15 pins, 1 for each segment and then one for the dot at the bottom right. If I wanted to power each one directly, I'd need 240 GPIO pins. Not ideal (and not possible).

My next idea was to control each individual LED square using two 8-bit SIPO shift registers. The thing is, I'd need 2 of these for every single LED square, meaning I'd have to use 32 in total. Again, not ideal.

My final idea was to use only two 8-bit SIPO shift registers, but "redirect" the collective 16-bit output to an individual square using some sort of circuit. I know decoders are one-to-many, but they only send one bit out. I need a circuit that sends 16-bit data. I'm thinking this involves combining a ton of decoders, like this chip which has two 1-to-4 decoders in it. This seems really inefficient though. What sort of circuit would I need for this type of redirect?

Also, my problem is that each square will only be lit 1/16 of the time, so they'll be 1/16 as bright. I could pass 16 times the current, but that just sounds like a bad idea... How do I make sure the LEDs are operating at their brightest?

Also, is there a way to have the LED's "persist" using some sort of memory? If the values of the square don't change, then I don't see why I need to keep cycling through them. Would a gated D-latch do the trick?

Please let me know if I'm going about this all wrong. This is my first time trying something this complex, and I'm a bit lost at the moment.

  • 2
    \$\begingroup\$ Multiplexing ... \$\endgroup\$
    – brhans
    Feb 14, 2017 at 22:51
  • \$\begingroup\$ @brhans how complex and/or expensive is that to implement? \$\endgroup\$
    – rcplusplus
    Feb 14, 2017 at 23:48
  • \$\begingroup\$ Cheap, not too complex hardware wise. A bit heavy on the code, but plenty of libraries out there for this. \$\endgroup\$
    – Passerby
    Feb 15, 2017 at 0:35
  • \$\begingroup\$ @Passerby I kinda want to do everything by hand, is that feasible? I'm only an engineering student so I dont know a lot of complex theory yet (we only just learned convolution). Also how does its speed compare to dannyf's answer? \$\endgroup\$
    – rcplusplus
    Feb 15, 2017 at 19:20
  • \$\begingroup\$ Take a look at this example which goes from a single display to a pair of multiplexed displays. Once you've understood two it should be obvious how you extend it to more than two. But the real question is... how many pins do you have available? You can do this with anything from a single output pin to 240 of them depending how much external circuitry you're prepared to add! \$\endgroup\$
    – Finbarr
    Feb 17, 2017 at 17:54

1 Answer 1


A few possibilities, depending how many pins you want to spend on driving them.

  1. 2 SR registers on the segment and 16 individual pins for individual display.

  2. 2 SR registers on the segment plus two SR registers for the 16 display, driven independently. This allows very fast display update from digit to digit.

  3. 4 SR registerss together. The least amount of pins used and the slowest.

For more static solutions, look into dedicated drivers like max7219 or its modern equivalent.


i put this together based on an old project of mine to demonstrate the approach mentioned in #2 above: it drives up to 8 digit 14-segment leds with four pins.

//display a digit in lRAM[SRDIG_CNT]
//blanking optional - currently disabled
void ledx14_display(void) {
    static uint8_t cnt = 0x00;              //lsb first
    static uint16_t tmp=0;                  //pick up the current char

    //blanking the segments
    //ledx14seg_write(0);                       //active high segments

    //shift to the next digit
    IO_SET(SRDIG_PORT, SRDIG_SCLK);         //sclk on positive edge

    //send the segment data
    ledx14seg_write(tmp >> 8);              //send the msb first
    ledx14seg_write(tmp);                   //send the lsb

    //strike out the digit data
    IO_SET(SRSEG_PORT, SRSEG_SLAT);         //strike out data on positive edge

    //advance to the next digit
    cnt = (cnt == SRDIG_CNT - 1)?0x00:(cnt+1);  //advance to the next digit
    if (cnt==0) IO_CLR(SRSEG_PORT, SRSEG_SDI);  //digit active low (common cathod)
    tmp = lRAM[cnt];

here is the display being driven by a 12f675. the three SR registers share SDI/SLAT pins but with their own SCLK pins.

the data being displayed (correctly i may add) is 0x0101, 0x0202, 0x0303, 0x0404, from the left to the right. Each digit takes 0.3ms to refresh. or 2.4ms for all 8 digits. 100 bytes of flash and 24 bytes of ram.

enter image description here

as is, the code can drive up to 8 digits. with the addition of one shift register, and no increase in pins, the code can drive 16 digits.

porting it to an arduino should be fairly easy.

hope it helps.

  • \$\begingroup\$ I'm sorry, I'm a bit confused. All solutions involve shift registers but how do I redirect the output to individual LED segments? Also are they PISO or SIPO? \$\endgroup\$
    – rcplusplus
    Feb 15, 2017 at 19:24

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.