Connect with us

Creating a 12x3 digit 7-segment display with Arduino

Discussion in 'Microcontrollers, Programming and IoT' started by Panici, Dec 5, 2011.

Scroll to continue with content
  1. Panici


    Dec 5, 2011
    Bear with me, this my first project.
    Please include details that are assumed knowledge to an experienced person.

    I'm planning to build an external display for PC racing simulators (ie. rFactor)
    Mock up:
    The plan is to build on breadboard then transfer to perfboard at a later date.

    I'm going to use 9x red 4-digit modules (0.56") from here [12 pin version]:
    Should I get Common Cathode, or Common Anode?

    My main concerns right now are:
    1. Power - How to physically wire power to all of the displays. (using a 5v bench supply most likely)
    2. Data Transfer - How to get the data from the arduino onto the displays. (multiplexing? hardware/pin wiring?)
    3. Fast display refresh rate/speed - I've seen displays lag with only four 7-segment displays, so i'd rather use extra pins on the Arduino then daisy chain.
    4. Special characters. - In addition to (0-9,A,B,C,E,F) Ideally I want to be able to use the segments to form whatever other letters I can. (n, r, o, d, b, etc)

    Oh and also, while talking about speed, I plan on also driving two (possibly 3) of these using the (TM1638) library.

    Let's leave the TM1638 based modules out of the equation for now, unless we need to somehow wire them together with these displays, in order to not have display lag???

    I obviously cannot drive (9x12) pins right off of the arduino, so what is my best option?
  2. (*steve*)

    (*steve*) ¡sǝpodᴉʇuɐ ǝɥʇ ɹɐǝɥd Moderator

    Jan 21, 2010
    The displays themselves must already be set up for multiplexing.

    The fastest way to drive them is to have them multiplexed in parallel. So you display all the first digits, then all the second, then all the third, then the foutth, then back to the first.

    To do this with a reasonable number of pins you use something like a 74C595 to clock out the various signals, then latch them. This can be done with three pins.

    Google for "74HC595 arduino" for more information.

    As to whether you use common cathode or common anode, that depends on how you decide to wire stuff up.I'd think common cathode may make things conceptually easier.
  3. Panici


    Dec 5, 2011
    I bolded some stuff in your response, I appreciate any and all info you can share, as i'm a total beginner at this stuff. :)
  4. (*steve*)

    (*steve*) ¡sǝpodᴉʇuɐ ǝɥʇ ɹɐǝɥd Moderator

    Jan 21, 2010
    If there's 12 pins for 4 x 7 segment displays then you have 8 segments (remember the decimal point) plus one connection for each (common) anode or cathode.

    You have a single 74HC595 for each 8 lines you need. The minimum number of connections would be 8 + (9x4) = 44 -- that's 6 of them. But I'd recommend that you don't multiplex them that way because it may be too slow, so the way I suggest you require 9 x (8 + 4) = 108 -- that's 14 of them.

    Any way you do this, it's going to require some fairly fancy programming.
  5. Panici


    Dec 5, 2011
    Yeah, i'm not sure what to do at this point?
  6. TedA


    Sep 26, 2011

    I'm not sure that something like the 74HC595 is a good solution. The outputs are stout enough to drive a single, un-multiplexed segment, but will require a current limiting resistor to interface to the display. Without multiplexing, you will need 36 of these ICs, and nearly 300 resistors…

    There are better ways.

    I'll try to answer your questions, in order:

    > Should I get Common Cathode, or Common Anode?

    Common Anode works with the more common driver ICs.

    > My main concerns right now are:
    > 1. Power - How to physically wire power to all of the displays. (using a 5v bench supply most likely)

    The Kingbright displays appear to all be rated at 10mA per segment, and require fairly low voltage, perhaps under 2.5V. So you should be fine powering the display from a 5VDC source. If you light up all the segments at once, you will need about 2.9A, at the 10mA/segment level.

    You must provide for limiting the segment current to the desired value. The Kingbrite displays have no internal current limiters. The easiest way to do this is to use LED driver ICs that limit the current.

    > 2. Data Transfer - How to get the data from the arduino onto the displays. (multiplexing? hardware/pin wiring?)

    You definitely want to use a small number of wires from the controller to transfer the data to the display system. Available LED driver ICs typically have I2C or other serial-type inputs.

    Multiplexing the display is a good idea. It will reduce the amount of wiring, and the number of driver IC pins required. Some of the Kingbrite parts have segments bussed-together internally; using one of these will reduce the amount of wiring to be done. The 12-pin versions of the Kingbrite display require four-way multiplexing.

    > 3. Fast display refresh rate/speed - I've seen displays lag with only four 7-segment displays, so i'd rather use
    > extra pins on the Arduino then daisy chain.

    Unless the controller is incredibly slow, any reasonable display system configuration should be able to update the display quickly enough to appear to be instantaneous.

    > 4. Special characters. - In addition to (0-9,A,B,C,E,F) Ideally I want to be able to use the segments to form
    > whatever other letters I can. (n, r, o, d, b, etc)
    > Several of the available driver ICs contain no character decoder, so you can set any segment as you wish. This
    > does mean that the character set must be encoded by the controller software.

    My thoughts in general:

    This sort of project, where you are doing the connections by hand, benefits from a design that minimizes the connections to be made. With 36 digits, of 8 segments ( including the decimal point ) per digit, you have the potential for a wiring nightmare. You want to minimize the wiring per segment, as a first priority. For instance, you do not want to be wiring a current limiting resistor for each segment, or even for each group of two to four segments. ( Grouped, if the display is multiplexed. ) By combining a specialized LED driver IC with multiplexing, you can reduce the wiring required considerably.

    A brief search turned up a couple of LED driver ICs that seem to be reasonable choices. These parts drive the cathodes of the display with constant currents that you can set to the desired value. They have serial inputs, so require few wires going to the controller. P&D seem reasonable. ( I only looked at Mouser, in the US.)

    If I were doing this, I think I'd use a set of 5, MAX6969 or MAX6971 driver ICs, plus 4ea. P-channel power FETs for anode drivers. The FETs can be driven directly by four "left-over" pins on the last MAX chip. A common Anode display would be required, and would multiplex 4 digits together per multiplex set.

    This scheme would work with one of the Kingbrite displays having all four digits internally connected: 4 pins for the anodes, 8 pins for the segments. See P/N CA56-21GWA, for instance.

    The software will have some work to do to drive this. Interpreted Basic may be too slow. The logic interface is that of a simple 1-bit in shift register. This driver is listed as in-stock, at Mouser, and comes in a 24 pin DIP package.

    A data sheet for the Maxim driver is at

    Another driver you might look at is the NXP SAA1064. this one drives four digits, and does the multiplexing for you. However, it will require 18 transistors for anode drivers, and many more wires to the display, since it multiplexes the digits in pairs. ( Will not work with the 12-pin display.) Another 24 pin part.

    The NXP data sheet:

    I hope this is of some help to you.

  7. Panici


    Dec 5, 2011
    Thanks for the help Ted, i've responded in bold, inside the quote.
  8. (*steve*)

    (*steve*) ¡sǝpodᴉʇuɐ ǝɥʇ ɹɐǝɥd Moderator

    Jan 21, 2010
    Unless you get a driver chip with integral resistors or current limiting, you'll need the same number of resistors. Because these displays are multiplexes, you'll need between 8 and 72 resistors. Also, because you'll be running the segments at higher peak currents due to multiplexing, and due to the current limited nature of standard CMOS outputs (we're not talking line drivers here) you may be able to get away with no resistors at all (not that I'd recommend it).

    The important thing is to decide on how you're going to drive them *first*, THEN get the appropriate displays.

    They're a multiplexed unit, so you would be driving them at an average current of 10mA (i.e. 40mA per segment since they're multiplexed) to achieve that.

    The MAX6969 is pretty much exactly the same solution as the 74HC595, except that it has internal current limiting (and does 16 channels rather than 8). It costs around $8 in unit quantities.

    The 74HC595 costs $0.63 but you'd need 2 ($1.26) plus some resistors (16x) to perform the near equivalent function.

    In some respects it comes down to whether you're on a budget for money or your own time (since it would take a little more time to wire up the resistors)

    If an Arduino is used, then it's going to be compiled C, right? The important thing will be to have the code used to display the digits called regularly so that the display has an even brightness. There are specific libraries for handling the SPI output, and it can be done at MHz rates, so speed is not a real issue once the data has been put together. Probably best having one piece of code maintain a buffer holding the values to be displayed, and another reading the buffer (interrupt code based on a timer) to multiplex it out.

    Internally you can use one byte per digit (each bit corresponds to a segment) and internally convert numbers and letters to their unique combination of segments (presumably via a lookup table). Actually it may be best to simply encode them as constants for "text" messages and use a lookup table only for numbers.

    Another thing you might consider is coupling the column drivers to the mosfets via an RC network so that they cannot remain turned ON for more than a small time. This will work fine when they're multiplexed, but saves you from a problem where you burn out segments if your multiplexer stops working. This can be really handy during development considering that the multiplexing is under software control.
  9. Panici


    Dec 5, 2011
    Maybe this will simplify things a little.

    The Arduino MEGA that i'm going to be using has 54 Digital I/O pins.
    I could use ~45 for this display and have enough left over for the rest of my design.
  10. (*steve*)

    (*steve*) ¡sǝpodᴉʇuɐ ǝɥʇ ɹɐǝɥd Moderator

    Jan 21, 2010
    An Arduino can drive 25mA from each pin. So you can drive the segments from the outputs directly (Using resistors is better though).

    You could use 12 pins for each set of 4 digits (remembering that 4 of these pins will need to drive a mosfet for the common anode or cathode). That would naively require (8 x 9) + (4 x 9) pins (108) and deliver an average current of up to about 7 mA per segment. In practice you can parallel the columns and do it with (8 x 9) + 4, or 76 pins

    If you multiplex them further in 4 sets of 8 digits and one set of 4 you would need (5 x 8) + 8 (or 48) pins. You would get an average current of around 3 mA per segment. you could easily expand this to another set of 4 digits without any significant changes.

    If you have three sets of 12 digits, then you could get away with (3 * 8) + 12, or 36 pins, but the average current would be only 2mA per segment.

    As you increase the number of digits multiplexed together, the peak current has to increase to maintain the same average current. In addition, your timing has to be much better since you need to scan the entire display at least 20 times per second.

    If I was driving them directly, I'd probably go for 5 sets of 8 digits (you don't have to wire up the last set completely).

    Basically you connect the like segments of pairs of displays together and connect them to outputs (that's 5 sets of 8). You then have 8 common connections for each display. Considering the low current, you can probably drive all 5 (1 for each like digit) from a single mosfet and connect the 8 mosfet gates to 8 further pins of the arduino.

    In operation you set the 5 digits in positions 1, 9, 17, 25, and 33, then set the column drivers to 10000000. You wait a while, then set the 5 digits in positions 2, 10, 18, and 34, and set the column drivers to 01000000 and then you wait again. You keep going until you have displayed all the 8 digits in each group, then start again. This code must keep running all the time and the rest of what happens must happen during the periods called "wait a while". In practice you call the multiplexing code from an interrupt generated by a timer.

    edit: hmm 45, 48 is too many... Well you could use 2 pins to drive something like a 4017 which will generate a bit that moves from output to output. That would bring you down to 42 pins
    Last edited: Dec 6, 2011
  11. Panici


    Dec 5, 2011
    I could use 48 pins, i'll just have to be careful with my other devices.

    I'm having trouble visualizing how this all will be wired up :confused:
  12. (*steve*)

    (*steve*) ¡sǝpodᴉʇuɐ ǝɥʇ ɹɐǝɥd Moderator

    Jan 21, 2010
    OK, each individual display is something like this:


    There are 4 individual displays with each of the segments connected together and each of the common (anodes or cathodes) coming out individually.

    So you need to connect 2 of these together. connect the A through G segments and DP to their corresponding pin on another display to extend the matrix to 8 digits.

    Now you have 8 connections for the segments that go to 8 outputs of the arduino (you can kind of think of these as rows).

    You also have 8 connections, one for each common display connection (think of these as columns) Note that you'll have to connect them via a mosfet (or transistor as shown here).

    So that's 16 pins for the first 8 digits.

    Repeat this for the next 8 digits, connecting the rows to their own arduino outputs, but the columns to the same set of columns used for the first display.

    Rinse and repeat.

    As I've said earlier the 8 column outputs only ever have a single one turned on, so you can get away with fewer pins if you're tricky. However if you have the pins to spare, use them.

    Does that help?
  13. TedA


    Sep 26, 2011

    I'll try to respond to your comments:

    Yes, it would be nice to not have giant arrays of resistors.

    Even a giant array would have to be wired-up. Perhaps you enjoy wiring, but I think there will still be enough work, even if the design is optimized to minimize the number of connections.

    I plan to use the 5V rail from a computer PSU, so I should have enough power. What's the alternative to an internal current limiter?

    The 2.9A figure would apply only while all segments are on. Say during a "lamp test".

    The current limiting has to be provided for each segment of each display. If the display is not multiplexed, that means hundreds of limiters. If it is multiplexed, each current limiter is shared over the multiplexed segments. Either resistors, or the specialized driver IC can provide this current limiting. The advantage of using the driver IC is that no extra wiring is required; each output pin on the IC has a current limiter built in.

    So the 12 pin versions are the right way to go then?

    The 12-pin versions of the 4-digit display will minimize the wiring required. My feeling is that avoiding extra wiring is a good objective, but other concerns may be more important in your particular case. Anyway, Steve is absolutely correct in suggesting that you figure out what you are going to do about driving the displays before making a firm decision.

    The system will be running off of a 16Mhz arduino controller. Will that have enough grunt?

    I am not an arduino expert; with some luck we may hear from one on this forum. It might not hurt to put the question to an Arduino specific forum. I think it's safe to say that an 8 bit microcontroller running at 16Mhz should be fast enough. However software can always be devised that will make any hardware too slow. Witness Microsoft Windows.

    How much extra load does software encoding put on the microcontroller?

    Software encoding of the characters won't load-down the controller very much. The character needs to be encoded only when the display changes. What will load the controller is having to repeatedly send the same data out to the display, in sequence, to support any multiplex scheme.

    Implementing a multiplex scheme with software will for sure put some extra load on the programmer!

    Thinking about this consideration, it might be advisable to actually start blocking-out code to do the multiplexing, in order to get a feel for just how hard it will be to code, and to allow an estimate of the load on the processor. I have no idea what else the controller needs to be doing. It may become very busy, indeed.

    Sounds like the best way i've heard so far.

    Note that this is a software-intensive approach. And you would be spending a bit more for the driver ICs, in order to save wiring and component count.

    What does P&D stand for?

    Price and Delivery. I just checked one US distributor: Mouser currently lists the MAX6971ANG at $5.06 each, quantity 1-24, with 4,656 pcs in stock. I realize that in different markets, your results may vary.

    I was looking at the CC56-21 or CA56-21 which is 12 pin as well.

    I didn't examine all of the different Kingbrite parts listed. A suggestion is to pay a tiny bit more for the one with the higher brightness rating in the color you want, if there is a choice.

    Does the arduino use Interpreted Basic?

    Steve says compiled C. I would expect that this would run much faster than interpreted Basic. I'm sure there is some way to use assembler / machine code, if the compiler doesn't quite cut the mustard. I can say that Microsoft Basic on a 2Mhz 6502 would be too slow. I trust that almost anything on the Arduino would be faster.

    Seems wise to avoid the displays with larger 36pin inputs. 329 pins just to the displays

    I didn't look; does Kingbrite offer a 4-digit module with the displays wired for multiplexing in pairs? That would be only 18 pins. Someone must make such a version. ( Or two digit modules could be used.) This would match-up with the NXP driver.

    Steve makes a good point about the low cost of the 74HC595 being an advantage. And there may be some markets where it is easier to find. I don't know where you are located. And it may just possibly limit the current to about the desired value when you overload its outputs by a factor or 5 or 6. But this route will mean a lot more stuff to do the job ( The parts count is 18:1, including resistors ), and will be operating the parts outside their ratings. ( Assuming multiplexed operation, and average segment currents around 10 mA.)

    I think that Steve has demonstrated that using the Arduino output pins directly would be very marginal: not enough pins, not enough current, at least within the ratings. Your display has a lot of digits!

    You can adjust a shift register ( either the driver or HC part ) design to use more or fewer Arduino pins. The shift register ICs can be daisy-chained; I think just two pins could do the whole job, if they work pretty fast. Alternately, it sounds as if you have pins enough to provide an individual pin to drive each shift register IC directly, plus a pin to control each anode driver transistor. Each approach would present its own interesting software challenges.

    A final thought, is that many applications of this nature use a single large graphic display that's more like a computer screen. Think LCD, CRT, OLED. But going that way would ruin our fun here!

    Well, I gotta go. Interesting project.

    Take care.

  14. noufel


    Jul 2, 2018
    Hi Panici,
    please i have the same project as yours,have you find the solution for your project?
    i need a help
Ask a Question
Want to reply to this thread or ask your own question?
You'll need to choose a username for the site, which only take a couple of moments (here). After that, you can post your question and our members will help you out.
Electronics Point Logo
Continue to site
Quote of the day