Electrical – Controlling a lot of 14-segment LEDs

circuit-designgpioledmicrocontroller

(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.

Best Answer

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.

edit:

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
    //ledx14seg_write(0);

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

    //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
    IO_CLR(SRSEG_PORT, SRSEG_SLAT);

    //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)
    else IO_SET(SRSEG_PORT, SRSEG_SDI);
    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.