Home Controlling LEDs

Controlling LEDs

<this is a work in progress text for my thesis>

In order to build a display, a good understanding of how LEDs work is needed. This chapter covers the steps that were taken to figure out how multiple LEDs are controlled with an Arduino.
(+ why LEDs? has a low energy consumption, is small in size and has a long lifetime.)

Control 1 LED
A LED or Light Emitting Diode is a semiconductor that has a positive side (anode) and a negative side (cathode). Because of the polarity, it will only light up when the current flows from the anode to the cathode. The positive side is typically characterized by a longer leg while the negative side has a flat spot on the bulb and has a bigger part on the inside. This means that the long leg must be connected to a power source and the short leg to ground. Depending on the voltage of the power source, a resistor needs to be inserted between power and ground. Two laws for electric circuits explain why this is and also point to the correct resistor value.

Kirchhoff’s voltage law states that “the directed sum of the electrical potential differences (voltage) around any closed circuit is zero”. This means that if the supply voltage of an Arduino is 5V and the LED has a forward voltage drop of 3.2V(can be found in the datasheet), the resistor needs to waste the remaining 1.8V (5V – 3.2V = 1.8V). Otherwise, there would be no balance in the circuit.

Ohm’s law states that “the current through a conductor between two points is directly proportional to the potential difference across the two points”. The mathematical equation that describes this relationship is:

V = I * R

In this equation, V stands for the voltage across a resistor (volts), I stands for the current through the resistor (amperes) and R is the Resistance of the resistor (Ohms). The value needed for the resistor can be found if the formula is rewritten to:

R = V / I

The LED desires 20mA in this example and because the current is constant in the circuit, this is also the desired amperage in the resistor:

R = 1.8V / 20mA
R = 90 Ohm

The nearest higher rated resistor is 100 Ohm. Using a different resistor influences the brightness of the LED. A lower rated resistor will produce a higher current and this will increase the brightness. But if the current through the LED is too high, it will burn out. Using a higher rated resistor only causes the light to be dimmer.

The colour code for a 100 Ohm resistor is brown-black-brown-(gold). Those codes are read from left to right and to distinguish the sides, there is a small gap between the third and the fourth colour band. The table 1 reveals the value for each colour.
table 1
Schematic and code to test this on an Arduino, can be found in Appendix …


An RGB LED could also be considered as a single LED, but in fact three seperate LEDs (a red, a green and a blue) are put into a single 5mm LED package. On a common anode RGB LED, those single coloured LEDs have their own cathode leads but they share the same anode. Controlling an RGB LED is simply said the same as controlling 3 individual LEDs. This can be done by using 3 different output pins on the Arduino as explained in appendix … (blogpost about RGB LEDs)

Multiple LEDs

Lighting up multiple LEDs can be done the same way as described above by putting them in series or in parallel. But in comparison with a single LED, the resistor and/or the power source will need adjustment in order to comply with Kirchhoff’s and Ohm’s Law. If N LEDs are put in series, the amperage will stay the same but the power source will need to be at least N times the forward voltage drop of the LEDs. If N LEDs are put in parallel, the amperage of the power source must be capable to handle N times the desired current over a LED. The voltage of the power source must be higher than the voltage drop of one LED. graph and table … illustrate this.

This way, a lot of LEDs can be turned on or off by using an output pin on the Arduino as a power source. With 13 digital outputs readily available on an Arduino Uno, it is possible to create some combinations but sometimes this won’t be enough. Different technologies exist to expand this number without having to buy a more advanced microcontroller. Two techniques, charlieplexing and shift registers, were explored and are discussed below.

Charlieplexing is based on traditional multiplexing but gains efficiency by utilizing the tri-state logic capabilities (+V, GND, or “high impedance”) of microcontrollers. While a LED needs a resistor to limit the current going through it, it doesn’t matter if the resistor is placed before or after the diode. A resistor can even be split into 2 separate components as long as the sum of both equals the demand. To introduce Charlieplexing it makes sense to start with an example that has only two LEDs. In figure (4) , LED 1 is oriented backwards in respect to LED 2. A diode only lets current go through in one direction, so depending on the state of pin 1 and pin 2, one (or none) of the LEDs will shine. This example still uses 2 output pins so there is no real benefit. On the contrary, there is the disadvantage that the two LEDs can’t emit light at the same time, although it is possible to get the same effect by switching very fast between the two states.


Using the same technique, it is possible to use the output pins more efficiently. The minimum matrix that benefits from Charlieplexing requires 3 output pins and gives 6 controllable LEDs in return, as illustrated in figure (5) . Three pairs of LEDs are sandwiched between 2 resistors and are connected to 2 different pins. Disconnecting pin 3 would give the same situation as in figure(4); If pin 1 provides 5V and pin 2 acts as ground, the first LED will glow and LED 2 won’t emit light because it is placed backwards. To light up LED 3 or LED 4 the situation is similar if pin 1 is disconnected. The circumstances to illuminate LED 5 or LED 6 is slightly different and needs some more explanation. If pin 1 acts as ground, pin 2 is disconnected and pin 3 provides power, the current will flow through LED 5 and not through LED 6. But the current will also flow through LED 1 and LED 3 because those diodes are in the same circuit and placed in the correct direction. Normally, they won’t emit enough light to become visible because the voltage across them is only half of what goes through LED 5.


With N output pins, it is possible to drive a maximum of N * (N-1) LEDs. In appendix … an experiment is described that uses 4 I/O pins to drive a 3×4 LED Matrix. The conclusions from this experiment were that a lot of wire is needed to make all the connections. The result is cluttered and this makes it difficult to detect errors or make adjustments. In order to give the impression that multiple lights are lit at the same time, the highest possible refresh rate was used but this caused the light intensity to drop a little bit. This is probably because the time that the current could flow through the LED became too short. (Perhaps the output ports on an Arduino are not perfectly in sync which could be one of the reasons.) Increasing the Refresh rate with 1ms helped to boost the light intensity back to the regular level. Moving ‘images’ were rendered perfectly but when displaying static patterns, a flickering effect was noticed.

Another solution to control multiple LEDs uses shift registers. It gives you control over each LED individually and unlike with Charlieplexing the LEDs aren’t turn on one at a time. An 8-bit shift register creates eight digital output pins while using only three output pins on a microcontroller. Because shift registers can be daisy chained, each additional shift register adds 8 new digital outputs. There is no limit on the number of extensions but more means slower in this case.

To describe the working of such a chip, the 74HC595 from NXP is taken as a base. This 8-bit shift register is configured as a serial-in parallel-out (SIPO) and contains a chain of 8 flip-flops in which data can be clocked at a rate of 1 bit at a time. This means that the 8 output pins in the shift register are either 1 (HIGH) or 0 (LOW). The Serial pin (DS) defines if the first output pin is HIGH or LOW. By pulling the Serial Clock pin (SHCP) high, every pin moves up one place and a new value gets shifted in by the Serial pin. Doing this eight times would assign a new value to every pin. Those values are stored temporarily and in order to update the output-pins with the new shift register values, the Register Clock pin (STCP) must be set HIGH. The LEDs are not affected when new data is shifted into the internal shift register. The image below (source) illustrates this process. The Serial pin defines “1 0 0 0 0 1 0 1″, and at the end of the cycle three output pins are HIGH (Qa, Qc and Qh).

The datasheet gives the pin configuration and pin description (figure_ and table 2, in appendix??) which are needed to build a working prototype.

Figure_ illustrates how a shift register can be hooked up to an Arduino. Three digital outputs on the microcontroller are connected with the DS, STCP and SHCP pin. Also power (between 2V and 6V) and ground are linked with the chip. Q0, Q1, … Q7 are the newly created outputs and 8 single LEDs are attached to them. Additional shift registers use the same digital outputs on the Arduino except for the serial data input. For ease of use, pin number 9 (Q7s) could be used as a serial data output so that the different shift registers work together. An almost endless amount of extra shift registers could be added this way.

In appendix_, an example is described that uses 5 shift registers and is able to control 37 LEDs individually. Some reflections about this technique are that it is more difficult to understand and write code than Charlieplexing but that -once it works- is a lot easier to to deploy and make adjustments. No flickering occurs when displaying static patterns thanks to the real digital outputs that control the LEDs. There are also some disadvantages when shift registers are used. Because they run at 1Mhz while the Arduino runs at 16Mhz, there will always be a slight delay. The text-display doesn’t need a fast refresh rate so this is not a big issue. Another disadvantage is that the output current of the shift register is limited to 25mA for an individual pin and 70mA in total. A LED consumes about 20mA each which means that using more than 3 LEDs would lower the luminosity of the LEDs, unless transistors are used. Another reason to choose for those semiconductors is that, in a worst case scenario, all LEDs are turned on and would require more current than an Arduino can handle (max 200mA). This would damage the microcontroller permanently.

A transistor can be used as an electronic switch to to turn current on or off in another circuit. The circuit that is being controlled that way, can carry a different current and voltage than the other. By connecting the LEDs to such a circuit with a power source that is big enough, the previously mentioned limitations are being avoided. To test this theory, a common NPN bipolar transistor used for general purpose low-power switching applications was chosen and set up as in figure__. The transistor has three connections that are labeled base, collector, and emitter. The base can control if the other circuit is switched on or of. The collector is connected with a power source and with the LEDs. The emitter is attached to ground. If a small current enters the base, current will be able to flow from the collector to the emitter and thus turning on the LEDs.

In the final display, 5 shift registers are used to expand the amount of digital outputs on an Arduino. All those outputs are connected with a transistor to drive the LEDs from a different power source.

+more explanation about the final display: #leds, calculating the value of the resistors, schematic?

1 comment

update | Stijn Coppens Labs Januari 10, 2012 at 8:55 am

[…] Writing a chapter for my thesis about ‘controlling LEDs‘ […]


Leave a Comment