LEDs aplenty, and only a few pins

LEDs
Who doesn’t like seeing the LED blink when they upload their first Arduino sketch to the board? No one. It’s just magic! So, this time, I’ve decided to push the “illusion” a bit further with lots and lots of LEDs. I am currently working on an exciting project (more on that in a future post) for which I need to have individual control over multiple LEDs. Problem: I’ve got a restricted amount of pins I can use on the Arduino. Below is a list of a few techniques I’ve experimented with. I hope you’ll find this useful.

1. LED strips

What I was looking to achieve was a straight line of LEDs, lighting up one after the other; so naturally I thought: “Hey! LED strip!”. That would have been too simple. I probably got the wrong strip in the first place. If you want to work with an LED strip and Arduino, you probably want to get one that operates on 5V (and not 12V, like mine), and make sure it’s addressable (i.e that you can control each LED individually). Adafruit have got quite a good tutorial if you’re working with addressable strips. There’s even an Arduino library on Github.
It turned out that my project requires a really low voltage (less than 5V), so LED strips are out of the way for now. They still look amazing, though. Who knows? Maybe one day I’ll build a wearable TV, like this guy:

2. Charlieplexing

Next, my research led me to Charlieplexing. It definitely uses fewer pins than if you had to attribute a pin per LED. I thought I had a potential winner for a moment.

a) The concept behind Charlieplexing
Charlieplexing takes advantage of the fact that the pins of the microcontroller have multiple states (I/O HIGH or LOW). Therefore, you can have LEDs sharing pins. When the anode (long lead of the LED) of an LED is connected to a pin, the cathode (short lead of the LED) of another one is also connected to it. Then, for each LED you want to turn on, identify its pins, set the pin connected to the anode as OUTPUT, HIGH; and the cathode as OUTPUT, LOW. Set pins as inputs (also called high-impedance) to turn the lights off.

b) Charlieplexing in action
Here’s the circuit I used;

After that, using the principles outlined in the previous section, and the different code examples I could find, all I had to write in the loop() function was

 
  pinMode(LED_pin_11, OUTPUT);
  digitalWrite(LED_pin_11, LOW);
  pinMode(LED_pin_10, INPUT);
  digitalWrite(LED_pin_10, LOW);
  pinMode(LED_pin_9, OUTPUT);
  digitalWrite(LED_pin_9, HIGH);
 
  delay(1000);

for the first LED, and so on on for each one. And here’s the result:

c) Pros & cons
Charlieplexing surely reaches the goal I had set to use fewer pins. If n is the number of pins you can use, then you can have n*(n-1) LEDs. 6 LEDs for 3 pins, 12 LEDs for 4 pins, 20 for 5 and so on. However, wiring can become a bit complex and intertwined, and doesn’t make debugging easy. At some point, 2 of my LEDs were lighting up at the same time, and one of the remaining ones wouldn’t turn on. It took me a while to figure out whether it was coming from the code or the circuit itself.

It definitely meets the objective of having individually addressable LEDs. Although you can have multiple LEDs on at the same time, you can’t have all of them on (you would have to play with persistence of vision if that’s what you wanted), for obvious reasons. A pin can’t be set to both HIGH and LOW states at the same time. For the purpose of my current project, I need to leave the previous LED on when you move on the next. Unfortunately, that can’t be achieved with Charlieplexing.

3. Shift Registers

74HC595 Shift RegisterThen I came across shift registers. Now, I don’t want to sound too biased (and I honestly think the solutions above are great, just not for my current project), but so far I’m loving it! If you’ve got an Arduino starter kit, there is a shift register that comes with it (see picture on the right).

a) 8-bit shift register
One of these allows you to individually control up to 8 LEDs, using only 3 pins on the Arduino. And you can even use 2 shift registers to double the amount of LEDs without using any more pins.

A shift register has 16 pins, 8 of which are outputs (or inputs), and 3 of them that get plugged into a microcontroller: the clock, the latch and the data pins. The clock will determine when to take a data reading, the data receives bits that will command which pins (1 to 8) of the shift register to activate (in our case, which LEDs to turn on), and the latch that tells the shift register when to process the new data.

This video from the guys at Sparkfun proved really helpful when it came to understanding how shift registers work:

b) Demo
There is a method in Arduino called shiftOut() that takes in 4 arguments : the data pin, the clock pin, the bit order (most significant bit first or least significant bit first, defined as constants MSBFIRST and LSBFIRST), and the value (in bytes) of the data to shift out.

Now, if you recall, what I wanted to achieve was lighting up LEDs one after the other, but keeping the previous ones lit up. Here’s the result with a shift register:

The code for the example above is quite simple:

int latchPin = 8;
int clockPin = 12;
int dataPin = 11;

//An array of bytes corresponding to the desired states for the LEDS
int sequence[] = {1,3,7,15,31,63,127,255};

void setup() {
  pinMode(latchPin, OUTPUT);
  pinMode(clockPin, OUTPUT);
  pinMode(dataPin, OUTPUT);
}

void loop() {
   for(int i = 0; i < sizeof(sequence); i++){
     registerWrite(sequence[i]);
   }
}

void registerWrite(int byteNumber) {
      digitalWrite(latchPin, LOW);
      shiftOut(dataPin, clockPin, MSBFIRST, byteNumber); 
      digitalWrite(latchPin, HIGH);
      delay(500);
} 

And here’s how it looks like with 16 LEDs; the wiring is becoming a bit crazy, but again, it uses only 3 pins from the Arduino, which is a huge advantage.
16_led_example

4. Conclusions
LEDs are great, and you’ll probably need them in 90% of your electronics projects, but they can take a lot of space on your microcontrollers. As detailed above, there are different options available to eradicate that problem. Each one of them depends on your project’s specifications. I chose shift registers, but had a lot of fun investigating!

Related articles:
Wearable TV with LED strips
Wikipedia – Charlieplexing
Arduino – ShiftOut

Advertisements

One thought on “LEDs aplenty, and only a few pins

  1. Pingback: Countdown to Christmas | 300 LEDs before Xmas

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s