I need to control a Barmeter 28 led bargraph via an arduino (Mega). I believe I have found the details of the component here:


enter image description here


I have previously used a SparkFun LED Driver Breakout (TLC5940) to drive animations on smaller bargraphs with each segment having its own anode/cathode pins via the Mega. (This board is still available if required)

But the diagram for this has got me flummoxed. I have rudementary knowledge of electronics, but my strength is in software, and I have no idea how this should be hooked up.

EDIT: I am using the Y80, and need animations that will require all segemnts to appear lit at once.

  • 1
    \$\begingroup\$ Your link doesn't work. Please add the schematic using the image upload button. That way the question is still understandable even when the link dies - as it already has. \$\endgroup\$
    – Transistor
    Commented Oct 20, 2019 at 18:23
  • \$\begingroup\$ Can't use a https URL for a site only availble via HTTP. \$\endgroup\$ Commented Oct 20, 2019 at 18:24
  • \$\begingroup\$ Do you want to be taught to fish? Or do you just want a fish tossed to you? One takes more time than the other. But are you looking to educate yourself so you can do other things on your own? Or is all you care about a quick solution and you aren't at all interested in learning this stuff? (This kind of project is a good segue to learning. But that doesn't mean you have to use it as such.) \$\endgroup\$
    – jonk
    Commented Oct 20, 2019 at 21:49

4 Answers 4


This is a 7 shared cathodes, 4 shared anodes display. Pretty standard way to drive complex LED displays:

There's groups of LEDs that share one cathode connection (in this case, those are 7 groups of 4 LEDs each), but all have different anode connections (of these, there are 4 groups of 7 LEDs each). There's no two LEDs that light up at the same time if you just connect one anode and one cathode connection!

Therefore, you need 11 connections to connect this display, 4 of which need to be able to source the LED forward current (i.e. be pulled high), 7 able to sink that amount of current.

So, to light up a segment, you pull down the corresponding cathode connection and the up the anode connection.

You do that for every segment, one after the other, quickly enough: the human eye is way slower than a microcontroller, and thus, although you're not lighting up all segments at once, it looks like you do.

  • \$\begingroup\$ Presumably I should add an appropriate resistor to each of the 7 cathodes? \$\endgroup\$
    – AndFisher
    Commented Oct 20, 2019 at 19:16
  • \$\begingroup\$ if you drive the anodes high one at a time and drive as many cathodes as needed (for the apropriate anode) low, then yes those 7, resistors are needed for best results. \$\endgroup\$ Commented Oct 20, 2019 at 19:39

The easiest way to drive this multiplexed display is like this (although the designation is K, what you have is driven the same as a 4-digit common Anode numerical LED display):


simulate this circuit – Schematic created using CircuitLab

With this circuit you are driving the entire display current through the MCU ground pin so you are limited to an absolute maximum of 200mA, and you should stay well away from that, so let's assume 100mA total current (meaning an average LED current per LED of only 3.6mA and a peak LED current of 14.3mA)

You would pick RSi to yield about 1/20 of the 100mA total LED current through the transistor base, so about 5mA. So RSi of 820 ohms would be okay.

You pick RXi to yield the peak current of 14.3mA, so about (4.8V-Vf)/0.0143. If your LED has a Vf of 2.0V (green or yellow) that's about 200 ohms.

If that does not yield sufficient brightness you could add a ULN2003A or 7 MOSFETs to the 7 resistors, however you would have to recalculate the resistor values to yield the higher current and take into account the relatively high drop of the Darlington transistors into the ULN2003A. Also invert the state to high=ON, of course.

Firmware wise, the algorithm is to start with all 4 drives to Q1-Q4 high (off), set the GPIOs corresponding to C1..C7 LOW for each LED out of 7 you want to have "on", bring the drive for Q1 LOW, hold for perhaps 250-1000usec, then bring all Q1-Q4 high again, set up for Q2 and repeat. By bringing the Q1-Q4 high while the C1..C7 are changing you avoid "ghosting" (dimly lit unwanted segments).

It is best to do this in a timer interrupt routine, though it's fine to test it with simple-minded delays- but that will use up 100% of the MCU cycles. Set up a 4 byte area of memory that contains a bitmap of the desired LED states and use that to communicate with the ISR (your program writes to it and the ISR only reads it).

  • \$\begingroup\$ Just a note. The datasheet specifies (as I read it) a nominal \$20\:\text{mA}\$ average for each segment. With \$\times 4\$ muxing, this suggests \$80\:\text{mA}\$ (which also appears on the datasheet as a typical value under "peak forward current.") So I take it from that, the manufacturer expects this. I don't think the I/O pins (nor 7 I/O pins on a single port combined) would meet the absolute specs for the ATmega. Obviously, one doesn't have to drive things according to the suggestions on the datasheet. But it may help the OP to know the cathodes may also need external compliance support. \$\endgroup\$
    – jonk
    Commented Oct 20, 2019 at 20:53
  • \$\begingroup\$ @jonk Right.. 80mA x 7 = 560mA so well beyond the capability of the MCU to switch directly. They're 80-200mcd at 20mA so at 3.6mA average they'll be maybe 15mcd apparent brightness for the 80mcd ones - maybe good enough with a filter. Personally, I would try it without the sink drivers first and see how it looks. \$\endgroup\$ Commented Oct 20, 2019 at 20:58
  • \$\begingroup\$ Also note that the datasheet for the ATmega devices suggests an ABSOLUTE MAX of \$200\:\text{mA}\$ for all \$V_\text{CC}\$ and GND pins. This means "everything" on the device (and I assume that the bar graph isn't the only load.) And one shouldn't even get close to that absolute maximum. Each I/O has an ABSOLUTE MAX of \$40\:\text{mA}\$, as well. It's all pretty limiting. I agree about trying to significantly lower the average drive as one approach. But I think the OP would benefit from a "real design process," too. \$\endgroup\$
    – jonk
    Commented Oct 20, 2019 at 21:01
  • \$\begingroup\$ @jonk Yes, the 200mA is the limiting one since we're sinking all the current through the ground. The source drivers never had a chance of direct drive, which is why I added the 4 BJTs. If OP tried direct drive with those at 20mA that would yield only 700uA each average, which is almost surely insufficient. \$\endgroup\$ Commented Oct 20, 2019 at 21:05
  • 1
    \$\begingroup\$ I'll consider it. I also have work ahead. But I may get a moment, later. Of course, the OP may chip in, too, and say they don't care (in the meantime.) So we'll see. \$\endgroup\$
    – jonk
    Commented Oct 20, 2019 at 21:11

These are driven like any std common Cathode Low side switch to 3 digit displays with high side current limiting resistors (Vcc-Vf)/If = R and total power 0.2W =V*I high side direct to Output ports. 3.3V is possible or 5V with different R values.

  • then TDM MUX all groups at 1kHz or so for peripheral flicker free or go slow. 3 byte writes and dimmable with Delay off.

Sometimes ghosting needs a delay off between digits if there are Discharge timing issues, but easy fixes.

you can goog image the config.

the low side switch can be NPN or Nch FET. they may even have SMT quad switches


STEP 1 -- Review the Bargraph Display

I've never used one of these types of bargraph displays before. But I can see that it is designed as \$4\times 7\$ (or \$7\times 4\$, depending on your perspective.) So the first step for me is to examine it sufficiently well to decide how the manufacturer probably sees its operation.

From this, found below the Absolute Maximum Rating section, I see that the peak forward current is given as typically \$I_\text{F}=80\:\text{mA}\$:

enter image description here

From this, found below the Electro-Optical Characteristics section, I see the test condition of \$I_\text{F}=20\:\text{mA}\$ being used for all three statements:

enter image description here

This is the continuous operation value of \$I_\text{F}\$ is \$4\times\$ smaller than the so-called typical maximum value of \$I_\text{F}\$. And that isn't just a coincidence. It tells me that the manufacturer expects this device to be operated as a multiplexed device using four distinct phases. Your software will need to dice up things in such a way that you sequence through \$\frac14\text{th}\$ of the total of 28 LEDs in each of four successive steps. This is often simply called "\$4\times\$ multiplexing." And it means that you dedicate 25% of the time (called a "25% duty cycle) for phase 1, 25% of the time for phase 2, etc., with the implication also that in order to achieve an average of \$I_\text{F}=20\:\text{mA}\$ you will need to operate each LED in a given phase at \$I_\text{F}=80\:\text{mA}\$. (As your eyes will average out things so that the effect of operating \$I_\text{F}=80\:\text{mA}\$ at a 25% duty cycle will seem like \$I_\text{F}=20\:\text{mA}\$ running at 100% duty cycle.)

(If you are interested in more details about operating LEDs and some laws about human perception, I've written about some about it as an answer under the topic of pwm frequency for led dimming.)

The upshot all this is to gain some confidence in how to read a datasheet like this and also to gain some idea about how to test your own impressions, when reading, to cross-confirm your reading and make sure that you extract the details, correctly. This datasheet isn't the best I've seen. A lot is left to the imagination. So you do have to read between some lines.

To operate this in a way that follows the manufacturer's intended operation, your Arduino will need to set up controlling I/O pins that are assigned to enable/disable lines \$C_1\$ through \$C_7\$ (using your own code and internal calculations to figure out which to enable in each phase or step) and then you will enable \$L_1\$. You will hold \$L_1\$ enabled for 25% of the total cycle time (something else that you must choose, but should be fast enough that someone observing the display won't notice any flicker), then you will disable \$L_1\$, set up different controlling values for lines \$C_1\$ through \$C_7\$, and enable \$L_2\$ for the next 25%. Etc., finally returning back to \$L_1\$ after completing the 25% duty cycle for \$L_3\$. This repeats over and over and over again, without end.

STEP 2 -- Review the ATmega

You are using an Arduino that includes an ATmega device. You don't say which, but in general it is likely that the specifications will look something like this from the Absolute Maximum Ratings section of the Electrical Characteristics chapter of the ATmega2560 datasheet on page 355:

enter image description here

Before I go any further with this, I want to point out that these are the absolute maximum specifications. You do NOT exceed them. Ever. In fact, you should probably stay well under them. Note that they write:

Stresses beyond those listed under “Absolute Maximum Ratings” may cause permanent damage to the device. This is a stress rating only and functional operation of the device at these or other conditions beyond those indicated in the operational sections of this specification is not implied. Exposure to absolute maximum rating conditions for extended periods may affect device reliability.

Take that to heart. They mean it.

So when you read someone telling you, "Oh, heck. An I/O pin can handle up to \$40\:\text{mA}\$," you need to take everything else they say with a huge grain of salt. And you do NOT design at the dangerous edge of life! You design with some room for comfort. How much "comfort" is enough? Well, on the same page they write:

enter image description here

Notice the conditions? When operating at \$V_\text{CC}=5\:\text{V}\$ they appear to show \$I_\text{OH}=I_\text{OL}=20\:\text{mA}\$. This is a strong suggestion about how much (at most) you should expect a single I/O pin to be operated at (in terms of its current compliance.) And that still doesn't mean you can run ALL of the I/O pins that way at the same time!!! Again, you have an absolute maximum of \$200\:\text{mA}\$ that you should probably stay well below, from the above section on Absolute Maximum Ratings.

So you don't have carte blanche to go running around with high I/O pin currents. You have to think and stay within all of the specifications at the same time. And you must also take into account anything else your Arduino is doing for you. You don't get to just say, "Well, my display at least is within spec." You have to observe the entire schematic of your Arduino and work out what else is ALSO going on and subtract all of that from the datasheet specifications to see what's left over for your display operation. The point of all this is to make you think and not just assume stuff or to read what others say can be done and just assume you can get away with the same things everywhere, all the time, whenever you feel like it. You must think for yourself. You must READ everything and put into context in your mind.

You know you will need to activate up to 7 I/O pins for \$C_1\$ through \$C_7\$. That will require sinking some current in each of up to all 7 I/O lines at once. In addition, you will have to source current from yet another I/O pin that is operating one of from \$L_1\$ to \$L_4\$. Each of the 7 I/O pins assigned to \$C_1\$ through \$C_7\$ may need to sink \$80\:\text{mA}\$ (which you already know they cannot do without help.) Each of the 4 I/O pins assigned to \$L_1\$ through \$L_4\$ may need to source \$7\cdot 80\:\text{mA}=560\:\text{mA}\$ (which you also already know there is NO POSSIBLE WAY to handle without external circuitry to help, as well.)

So the conclusion here is that you will need external circuit help for EVERY I/O pin. This can take the form of either BJT or MOSFET transistors used as switches. Which you choose to use, will depend on cost and availability factors as well as familiarity, speed, dissipation, and other considerations you may want to think about. But there is no question at all that in order to operate your bargraph according to the way intended by the manufacturer, you will need additional external active devices and not just a few resistors tossed around.

STEP 3 -- Considering Brightness Trade-offs

By now, I hope you've come to realize that you cannot just paste LEDs like this onto I/O pins with a few resistors and walk away happy. Now that you realize that the external circuitry isn't trivial anymore, you may want to ask yourself a different question. Something that Spehro considered in a comment. You could attempt to see if your bargraph device can be operated at currents far less than the manufacturer intended, while still satisfying your own requirements. You can certainly attempt to operate things at lower currents. The results will be dimmer than intended. But that may be fine for your application.

Let's assume for the moment that you can afford as much as \$20\:\text{mA}\$ on any one of the I/O pins assigned to \$L_1\$ through \$L_4\$. With up to 7 of the I/O pins assigned to \$C_1\$ through \$C_7\$ active, this means each LED would (in a perfect world) use \$\frac17\text{th}\$ as much, or about \$2.8\:\text{mA}\$. With a 25% duty cycle, this means they would appear as bright as if they had \$700\:\mu\text{A}\$ running through them, continuously. That's not much. But if you are using this in a darkened environment, perhaps you can get away with it.

Reality (the world isn't perfect) will be that even with current-limiting resistors included at each of the \$C_1\$ through \$C_7\$ circuits, they won't all have the same current and, likely, won't appear with the same brightness. How close will the currents be? Well, you can review what I wrote as an answer to How can Ohms law be used to calculate the resistor value for an LED when multiple voltage/current pairings give the same resistance? in order to see some quantification. I won't belabor the details here, but assuming \$250\:\text{mV}\$ drop for each of the high side and low side switch circuits (leaving about \$4.5\:\text{V}\$), and reading the values of \$V_\text{F}\$ from your bargraph datasheet, I find that you will get something like 10-15% variation in current. And that's probably acceptable here.

But the main point is, "Can you accept an apparent average LED current of \$700\:\mu\text{A}\$? I can't answer that. Only you can. If you can, you can greatly simplify the external circutry (just the bargraph and some resistors.) But if you cannot, then you are facing active external circuitry.

There's more, of course. If you assume that the high side will be sourcing up to \$20\:\text{mA}\$ in order to support up to 7 LEDs at once (for a 25% duty cycle period), then the worst case voltage drop at the I/O pin is \$900\:\text{mV}\$. This means the output pin voltage for \$L_1\$ (say) would be as low as \$4.1\:\text{V}\$. It's likely that each of the sinking I/O pins, which only have to sink less than \$1\:\text{mA}\$, will be close to ground. But the emerald LEDs need a "typical" of \$3.2\:\text{V}\$. (The range isn't specified, but you know it must exist and is probably somewhere between \$3.0\:\text{V}\$ and \$3.4\:\text{V}\$ for any given LED in the bargraph.) This probably means you can only count on about \$700\:\text{mV}\$ of remaining overhead for the resistor to help you control current for the emerald LED case. This would suggest a resistor of \$1.2\:\text{k}\Omega\$ and regulation from anywhere between \$580\:\mu\text{A}\$ and \$920\:\mu\text{A}\$ or about 20% regulation between LEDs. Given human perception, this is probably okay. The red LED case would be better, so the above is a worst case regulation analysis.

Again, you need to decide if you are willing to trade off a LOT of brightness in order to gain a simple circuit. That choice is up to you. But let's proceed on the basis of operating the bargraph as the manufacturer expects. (Which means an external, active circuit.

STEP 4 -- Considering Alternative Avtive vs Passive Approaches

Assuming for now that you need active high side and active low side circuitry, you have to return to the question of BJT vs MOSFET (or some hybrid of both.) Each have their place. BJTs are cheaper and offer lower base to emitter voltage differential drive requirements. But they require a lot of base current. MOSFETs are more expensive and don't require base current, but they do require a more substantial gate to source voltage. There are other trade-offs.

But before we get to that, there's something else. While resistors are "fine" current limit devices (cheap, easy to use, less space, etc.), they have more trouble performing their purpose when there isn't much excess voltage overhead to work with. Also, if you want to support a variety of these bargraph LED types (red to emerald), with the same circuit then you may need something other than "just a resistor."

To get an idea of what I'm talking about, look at my answer to 'Leftover' voltage when using constant current. Here, you can apply a circuit that will provide uniform and well-controlled current drive for each of the 7 "segment" low-side drives. Doing so has its advantages and disadvantages. And you can also see the use of both BJT as well as BJT/MOSFET hybrid circuits there.

Again, whether or not you want to go that far will depend on your own goals. Also, note that those examples are low-side arranged. Similar can be done for high-side drivers. But in your bargraph case, you'd use the low-side arrangement (if you use it, at all.)

Of course, going back to a simple resistor is fine here. I just want to point out that there are circuits which can do better, if you want it. In your \$V_\text{CC}=5\:\text{V}\$ case, it's a tight design (not a lot of "room" to work with.) But it's doable.

STEP 5 -- Considering Single High-Side and Low-Side BJTs as Switches

Let's assume BJT-only for the design and see where that takes us.

The high side switch must support up to \$560\:\text{mA}\$ (see above discussion.) If we want to stay within the \$20\:\text{mA}\$ I/O pin limitation for the \$L_1\$ through \$L_4\$ pins, this would mean we'd need \$\beta=\frac{560\:\text{mA}}{20\:\text{mA}}=28\$. A lot of BJTs will saturate well at that \$\beta\$. So you might get away with it, just fine. If so, then you can use just a single BJT for the high-side drive. If not, you'd need to add another BJT to the circuit to lower the I/O pin drive current or else you'd need to accept a higher source current from the I/O pin.

Either is workable. For example, we know that the absolute maximum is \$40\:\text{mA}\$ per I/O pin. So we'd imagine we could push a little above \$20\:\text{mA}\$, if needed. After all, it's only for a 25% duty cycle and not a continuous current. So that might work okay. But there'd be the risk of even more voltage drop at this I/O pin, too. So that's another consideration. Of course, adding another BJT means that there is no risk to the I/O pin or the ATmega device. But it means more circuitry.

So let's assume it will work okay with just a single high-side BJT for now and go with that idea.

On the low-side, we can either go with a 2-BJT current limiting design (per the answer to 'Leftover' voltage when using constant current), or else just use a resistor current limiter.

We'll need to think about it before deciding.

The low-side BJT switch can provide \$\le 200\:\text{mV}\$ voltage drop and collector currents of about \$20\:\text{mA}\$. Let's look at the datasheet for the very commonly available PN2222A. If you look at "Figure 4. Collector Saturation Region" on page 4, and example the \$I_\text{C}=10\:\text{mA}\$ curve:

enter image description here

You can easily see that \$V_\text{CE}\lt 200\:\text{mV}\$ for all base currents \$I_\text{B} gt 60\:\mu\text{A}\$. Even using the \$I_\text{C}=150\:\text{mA}\$ curve, you can see that sourcing \$I_\text{B} gt 2\:\text{mA}\$ gets you there. So this means that you can easily use this BJT for the low-side switch device.

The high side is a little trickier, as PNPs often aren't quite so good for low \$V_\text{CE}\$. But let's look at a pretty nice example datasheet for this case: the NSS20500UW3. Let's look at "Figure 2. Collector Emitter Saturation Voltage vs. Collector Current" (where \$\beta=100\$ -- nice for our purposes):

enter image description here

Here you can see that at \$I_\text{C}=560\:\text{mA}\$ (worst case here), that \$V_\text{CE}\le 200\:\text{mV}\$ -- even when \$\beta=100\$! This means we could drive this by sinking perhaps \$5.6:\text{mA}$ from an I/O pin. Which again, is doable. (These devices are inexpensive and available and in-stock at Mouser, for example.)

STEP 6 -- The BJT-only circuit using resistors as current limiters.

At this point there is enough information to suggest an approach for the external circuitry. I'll keep it simple:


simulate this circuit – Schematic created using CircuitLab

I've kept the current-limit resistors, \$R_{12}\$ to \$R_{18}\$, to \$100\:\Omega\$. This might allow a bit too much current; or not. You can adjust these values upward to lower the current. I probably wouldn't lower their values much, though. (Their range should probably stay between \$68\:\Omega\$ and \$150\:\Omega\$ and that depends on the display device you actually choose -- color of LED, I mean.)

The base drive resistors on the PNP side (high side) are \$1.5\:\text{k}\Omega\$ and the base drive resistors on the NPN side (low side) are \$1.8\:\text{k}\Omega\$.

Assuming that the LEDs are red, I assumed the average voltage drop of \$2.0\:\text{V}\$ and that there would be about \$5.0\:\text{V}-250\:\text{mV}-250\:\text{mV}=4.5\:\text{V}\$ available. Removing the red LED voltage from that leaves \$2.5\:\text{V}\$ to drop. At \$20\:\text{mA}\$, this is about \$125\:\Omega\$ for the current-limit resistor. I chose to drop that a little because I'm not sure which of the LED types you plan. With the emerald LEDs, you'd probably want closer to \$68\:\Omega\$. So I chose \$100\:\Omega\$ as a vague compromise for current limiting. (I'm working with what little I know about your application.)

The low-side BJTs will need about \$900\:\text{mV}\$ for the base-emitter junction and I have to assume some voltage drop from the I/O pin sourcing the base current for them. With \$\beta\approx 10\$ in these cases, it works out to close to \$2\:\text{k}\Omega\$. I picked a slightly lower value, \$1.8\:\text{k}\Omega\$ for them.

The high-side BJTs I picked can deliver good saturation at \$\beta=100\$. Leaving plenty of room for their base-emitter junction voltage and assuming a \$\beta\$ less than that by a small bit, I decided on using base resistors of \$1.5\:\text{k}\Omega\$ in that case. I've not used these particular BJTs before, though. So I'd be sure to test one of them first before finalizing any such circuit. I might be surprised by the results and need to re-think the above arrangement. But from the datasheet alone, I'd say it may work okay.


You could also consider MOSFETs. These also come in NFET and PFET varieties and have the advantage of not requiring (except momentarily) any current compliance from the I/O pins. You'd need to find and select devices that are appropriate for the currents they have to support and you'd need to look over devices with lower threshold voltages, in keeping with the \$5\:\text{V}\$ rail you have. But they are fairly common these days and you probably could remove the base (gate) resistors shown in the above circuit, if you used them. (The intrinsic resistance of each I/O pin should be sufficient to avoid oscillation at their gates.)

From the above, I think you can see that while LEDs are "simple" in concept, driving them well can be annoyingly complex. This is one of the reasons why there are so many different LED driver ICs around. They package up all these details and save a lot of trouble and space. They even often include more sophisticated current limiting features, as well, which are "universal" enough to handle different colors of LEDs without any circuit changes, at all.

There are other means of driving multiplexed LEDs that are even more complicated. You could, for instance, arrange the low side to use active current limiting for each of the 7 available segments (at a time) and set this for all 7 to be the same exact current limit. However, since each LED might exhibit a slightly different apparent intensity at that same current, you could calibrate each of the 28 LEDs by adjusting the duty cycle to anywhere from the full 25% to something smaller for each segment, so that you guarantee nearly "perfect" apparent brightness across the entire display. (This assumes that the manufacturer hasn't themselves "binned" all the LEDs in the display, already.) In this case, you'd keep these special calibration numbers inside your Arduino and would still drive the high side with 25% per I/O. But would instead drive the low-side switches with varying sub-duty cycles that go from 100% of the 25% duty cycle to something less than 100%, depending on the LED segment itself. I don't say this as a random "wild guess", but from actual experience in calibrating large scale LED display systems where slight variations in display brightness between segments was unacceptable (aircraft instrumentation seen in a dark cabin, for example.)

I also haven't discussed contrast enhancement issues. These include various types of plastic and optical glass filters, methods to reduce the luminous sterance of the background, filter combination techniques, louvered filters, or anti-reflection filters. Those optical considerations are an entirely separate topic and require a great deal more.

That's about it. I think you can see what you may need to achieve on the software side, as well, now.


Your Answer

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

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