Skip to content

topquark22/CharlieLED

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

25 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

CharlieLED

This library lets you control bi-colour (2-lead) LEDs using charlieplexing. That is a technique for minimizing the number of GPIO pins needed to activate a number of bidirectional devices.

Using N pins, you can control:

N * (N - 1) / 2

bi-colour LEDs.

  • Works with 2 to 5 Arduino GPIO pins
  • Supports RED / GREEN / YELLOW (time-multiplexed)
  • Non-blocking (update() loop, GPIOUtils-style)
  • Adjustable colour balance using gamma

Bi-colour LEDs

-bicolor LED schematic 1 -bicolor LED schematic 2


🧠 Key Principle

Each bi-colour LED is connected between a unique pair of pins; not to ground as is usual for LEDs.

  • Current flows one way → RED
  • Reverse direction → GREEN
  • Rapid alternation → YELLOW

For N pins, you get:

Pins Bi-colour LEDs
2 1
3 3
4 6
5 10

⚡ Wiring Rules (Important)

  • Each LED is placed between two pins
  • Each LED must have a series resistor (220Ω–470Ω)
  • Resistor can be on either side of the LED
  • Pins must be capable of INPUT (high-Z) mode

🔌 Wiring Tables

Assume Arduino pins:

2, 3, 4, 5, 6


✅ Case 2 Pins (1 LED)

LED Connect Between
0 2 ↔ 3

✅ Case 3 Pins (3 LEDs)

LED Connect Between
0 2 ↔ 3
1 2 ↔ 4
2 3 ↔ 4

✅ Case 4 Pins (6 LEDs)

LED Connect Between
0 2 ↔ 3
1 2 ↔ 4
2 2 ↔ 5
3 3 ↔ 4
4 3 ↔ 5
5 4 ↔ 5

✅ Case 5 Pins (10 LEDs)

LED Connect Between
0 2 ↔ 3
1 2 ↔ 4
2 2 ↔ 5
3 2 ↔ 6
4 3 ↔ 4
5 3 ↔ 5
6 3 ↔ 6
7 4 ↔ 5
8 4 ↔ 6
9 5 ↔ 6

🔁 LED Orientation

Bi-colour LEDs contain two internal diodes.

So:

  • One direction = RED
  • Opposite direction = GREEN

If colours appear swapped:

  • Flip the LED physically, or
  • Swap RED/GREEN in software

🧪 Electrical Behaviour

To light an LED:

Pin A Pin B Result
HIGH LOW One colour
LOW HIGH Other colour
INPUT INPUT Off

All unused pins must be set to INPUT (high impedance).


🎛️ Gamma (Colour Balance Control)

The colour YELLOW is created by rapidly alternating between red and green.

However, in practice:

  • Red LEDs are often brighter than green (or vice versa)
  • Equal timing does not produce a visually balanced yellow

To compensate, this library provides:

setGamma(uint8_t gamma);

Where:

Gamma Result
0 all green
128 equal time split
255 all red

Internally, this controls the duty cycle split between red and green phases.

Example

leds.setGamma(50);

If red is brighter than green, a lower gamma value reduces red’s duty cycle, producing a more balanced yellow.

You can even adjust this dynamically:

leds.setGamma(analogRead(A0) >> 2);

💡 Brightness and Multiplexing

Charlieplexing achieves efficiency by driving only one LED at a time, rapidly cycling through all active LEDs. Your eyes integrate this into a steady image — but there’s an important consequence:

Brightness is shared across time.

If multiple LEDs are active simultaneously, each one receives only a fraction of the total “on” time.

📊 Duty Cycle Effect

If N LEDs are active:

Active LEDs Duty cycle per LED Perceived brightness
1 100% full brightness
2 50% slightly dimmer
3 ~33% noticeably dimmer
6 ~17% dim
10 10% quite dim

So:

  • A single LED will appear brightest when turned on
  • A group of LEDs will appear dimmer if they are turned on at once
  • This is expected behavior, not a bug

🟡 Yellow is affected twice

For bi-colour LEDs, YELLOW is created by alternating:

  • RED phase
  • GREEN phase

So yellow LEDs are affected by:

  1. Multiplexing across LEDs
  2. Red/green duty splitting (gamma)

This can make yellow appear dimmer or slightly biased in colour.


🔧 Practical Tips

  • Call update() as frequently as possible (avoid delays)
  • Use lower resistor values carefully to increase brightness (within safe limits)
  • If possible, avoid turning on all LEDs at once

🧠 Trade-off

Charlieplexing trades:

Fewer GPIO pins ↔ Lower brightness

This is the fundamental design constraint of the technique.


🚀 Example Usage

#include "CharlieLED.h"

CharlieLED leds(2, 3, 4);

void setup() {
  leds.begin();

  leds.setLED(0, CharlieLED::RED);
  leds.setLED(1, CharlieLED::GREEN);
  leds.setLED(2, CharlieLED::YELLOW);

  leds.setGamma(50); // adjust yellow balance
}

void loop() {
  leds.update();
}

🧩 Summary

  • Efficient use of GPIO pins
  • Clean abstraction via the CharlieLED class
  • Scales from 1 to 10 LEDs
  • Fully non-blocking design
  • Adjustable colour balance via gamma

📚 References

  1. Charlieplexing (Maxim / Analog Devices Application Note)
  2. Wikipedia: Charlieplexing
  3. Adafruit Guide to Charlieplexing

🔧 Future Ideas

  • Per-LED brightness (PWM duty cycle)
  • Smarter time-sliced scheduler using micros()
  • Gamma calibration per LED
  • Animation patterns / effects layer

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors

Languages