Controlling LEDs with Arduino


Your browser needs to be JavaScript capable to view this video

Try reloading this page, or reviewing your browser settings

This segment introduces the concept of what charlieplexing LEDs is and how it works with instructions on how to build a circuit and write code.


  • charlieplexing
  • leds
  • arduino
  • multiplexing
  • circuit design

About this video

Liz Clark
First online
09 April 2019
Online ISBN
Copyright information
© Liz Clark 2019

Video Transcript

In this section, we’re going to go over the concept of charlieplexing, which is a way to control LEDs that’s unique to microcontrollers.

To follow along, you’ll need the Arduino, breadboard, jumper wires, 220 ohm resistors, and basic LEDs from before. Let’s get started.

We’ve gone over quite a few ways on how to control LEDs with Arduino so far. For our final segment, we’re going to go over the concept of charlieplexing. Charlieplexing is a way to control multiple LEDs with just a few pins. It can be a bit complicated to understand, so we’ll go through it step by step.

Let’s begin with a simple example. We’re going to start with two LEDs and two digital pins on the Arduino. First, insert an LED into the breadboard as shown, making note of which leg is the cathode and which is the anode. Then insert the second LED so that the cathode of LED 1 is connected to the anode of LED 2, and the anode of LED 1 is connected to the cathode of LED 2.

Next, connect digital pin 2 and digital pin 3 to the breadboard with some jumper wire. Attach a 220 ohm resistor to each connection from the Arduino.

Finally, connect the signal from digital pin 2 the cathode of LED 1 and anode of LED 2, and the signal from digital pin 3 to the anode of LED 1 and the cathode of LED 2.

Now that we have our circuit, let’s move to the Arduino IDE to look at some code. This example code was written for this video series, but it will be easier to understand if we look at it as a complete program, rather than write it together as we have in previous examples.

First, as usual, we’re setting up constant integers for the digital pins, calling them pin 2 and pin 3. There is no setup portion for this code. Instead, we’ll go straight to the loop.

Inside the loop, though, it looks a little sparse. Instead of our usual multiple lines of code, we’re simply calling functions and delays.

As you can see, we’ve written functions for each LED below the loop using void. This allows you to write subroutines to call throughout the loop or in other portions of the code.

Similar to arrays that we went over in our last two segments, functions clean up our code, and allow us to save some time by not having to write certain lines of code repeatedly.

Let’s look at the function LED1. In it, we see that pin 2 is set up as an output and written as low, and pin 3 is also set up as an output, but written as high.

Let’s look back at our circuit. The first LED in our breadboard has its cathode connected to pin 2 and its anode connected to pin 3. This means that when we run this function in our code, it will send a positive signal to the anode and ground signal to the cathode, which, as we know by now, turns on an LED.

Returning to our code to look at function LED2, we see the opposite sequence of events has taken place. Pin 2 is written as high, and pin 3 is written is low.

Since we connected the LEDs’ cathode to anodes and anodes to cathodes, we know that the second LED on our breadboard has the opposite configuration of LED 1, and that this function is effectively turning LED 2 on. This is how charlieplexing works. It uses different combinations of pins sending high and low signals to turn LEDs on and off.

Let’s upload our code and see it in action. You can see the LED 1 and LED 2 are alternately blinking with a delay of 1 second between each.

Of course, using two pins to control two LEDs isn’t that impressive. We could do this with a simple blink program that we’ve already gone over.

What’s impressive with charlieplexing is when the number of pins is outnumbered by the LEDs.

First, a bit of math. There is a formula to determine the number of LEDs that can be controlled by a number of pins. N multiply by parentheses N minus 1, equals C, where N is the number of GPIO pins, and C is the number of LEDs.

For example, if we have 3 GPIO pins, the equation becomes 3 times parentheses 3 minus 1. Remembering our order of operations, 3 minus 1 equals 2, and then 3 times 2 equals 6. So we can control six LEDs with 3 GPIO pins. Let’s build that circuit.

First, place two LEDs on the breadboard, just like we did in our first example, where the anode of the first LED is connected to the cathode of the second LED, and conversely the cathode of the first LED is connected to the anode of the second LED. Repeat this setup for two more pairs of LED. You should end up with six LEDs as shown.

Next, connect digital pins 2, 3, and 4 from the Arduino to the breadboard. Then as we did in the first example, connect 220 ohm resistors to each of these connections.

Now we’re going to connect the digital pins to the LEDs. It’ll be helpful to think of the LEDs as having numbers for this step and going forward, as shown here.

Connect digital pin 2 the anode of LED 2 and the cathode of LED 6. Of course, by forming these connections, you are in turn connecting to the cathode of LED 1 and the anode of LED 5, since they are sharing a connection on the breadboard.

Next, connect digital pin 3 to the cathode of LED 2 and the anode of LED 4.

And finally, connect digital pin 4 to the cathode of LED 4 and the anode of LED 6. Each set of LEDs should be connected to two digital pins.

Now we can move to the code, where the real charlieplexing fun will begin. Again, just like with our first example, we’re going to look at the code in its finished state.

Again, we’re beginning with three digital pins defined as constant integers. There is no setup, but in the loop, we see six functions separated by delays of 1 second. Each function is named for each LED, and is holding the combinations of digital pin data that allows for the specific LED to be turned on.

These combinations can be figured out with a table like this. It lists every possible combination for the three digital pins; high, low, and input. This is known as tri-state logic.

Tri-state logic is the ability for a pin on a microcontroller to have three states– high, on; low, off; and input– which as we’ve gone over previously means that you’re inputting a signal to the pin for the microcontroller to interpret.

The input state is important here because it basically takes the pin out of the circuit. In the input state, the pin is not sending any signal, and is effectively disconnected. This is how you can do charlieplexing with three or more digital pins on the Arduino. The digital pins that are not in use to turn on the target LED are changed to inputs so that they are not outputting any current to the other LEDs.

We can see this in the individual LED functions in our code. For example, to turn on LED 1, digital pin 2 is set to be written to low. Digital pin 3 is said to be written to high. And pin 4 is disabled as an input.

Looking at the circuit, LED 1’s cathode is connected to digital pin 2, which is low in the function, and its anode is connected to digital pin 3, which in the function is high.

The rest of the functions for each LED match this pattern. If you were to dissect the code and circuit together, you’d see that each time a digital pin is written high, it is connected to that LED’s anode.

Going back to the loop, the functions are being called so that the LEDs will light up one by one in order. Let’s upload the code to see it in action.

By writing the loop with the LED functions it makes it easier to rearrange our LEDs’ light-up order. For example, let’s say we wanted all of the odd-numbered LEDs to light up, followed by the even-numbered LEDs. We’d simply change the loop so that LED1, LED3, and LED5 functions were called first, followed by the LED2, LED4, and LED6 functions.

After you do this, upload your code and see how the LEDs light up in lines now. If we weren’t utilizing functions for the LEDs, it would be a lot more cumbersome to change our LEDs’ effects.

This matters more when you’re working on larger animations or want to achieve a specific timing with your LEDs. Charlieplexing offers a lot of possibilities for using LEDs with Arduino and other microcontrollers. These examples are really just scratching the surface of what can be accomplished using this technique.