// Define the 3 pins used for Charlieplexing
const int pins[] = {2, 3, 4};
const int NUM_PINS = 3;
const int NUM_LEDS = NUM_PINS * (NUM_PINS - 1); // 6
// Array to hold the state of each LED (0 = off, 1 = on)
int led_state[NUM_LEDS] = {1, 0, 1, 0, 1, 0}; // Example: LEDs 1, 3, and 5 are ON
// Structure to define the wiring connections
// Source Pin (HIGH), Sink Pin (LOW)
const int led_connections[NUM_LEDS][2] = {
{0, 1}, // LED 1: Pin 2 (HIGH) -> Pin 3 (LOW)
{1, 0}, // LED 2: Pin 3 (HIGH) -> Pin 2 (LOW)
{0, 2}, // LED 3: Pin 2 (HIGH) -> Pin 4 (LOW)
{2, 0}, // LED 4: Pin 4 (HIGH) -> Pin 2 (LOW)
{1, 2}, // LED 5: Pin 3 (HIGH) -> Pin 4 (LOW)
{2, 1} // LED 6: Pin 4 (HIGH) -> Pin 3 (LOW)
};
// Function to light up a single LED
void setLED(int ledIndex) {
// 1. Get the source and sink pin indexes from the table
int sourcePinIndex = led_connections[ledIndex][0];
int sinkPinIndex = led_connections[ledIndex][1];
// The third pin is the "inactive" pin
int inactivePinIndex = 3 - sourcePinIndex - sinkPinIndex;
// 2. Set all pins back to INPUT mode (safest neutral state)
for (int i = 0; i < NUM_PINS; i++) {
pinMode(pins[i], INPUT);
}
// 3. Configure the active path
// Source Pin: Set to HIGH Output
pinMode(pins[sourcePinIndex], OUTPUT);
digitalWrite(pins[sourcePinIndex], HIGH);
// Sink Pin: Set to LOW Output (Ground)
pinMode(pins[sinkPinIndex], OUTPUT);
digitalWrite(pins[sinkPinIndex], LOW);
// The inactive pin remains in INPUT mode (High Impedance)
}
void setup() {
// All pins are initialized as INPUT by default in the setLED function
}
void loop() {
// Multiplexing loop: Quickly cycle through all LEDs
for (int i = 0; i < NUM_LEDS; i++) {
if (led_state[i] == 1) {
setLED(i);
// Brief delay for the LED to be visible.
// The total cycle time (6 * delay) should be less than ~20ms.
delayMicroseconds(2000); // 2 milliseconds (2ms * 6 LEDs = 12ms cycle time)
}
}
}
// Example function to make the LEDs "chase"
void chase() {
for (int i = 0; i < NUM_LEDS; i++) {
// Turn off all LEDs
for(int j=0; j<NUM_LEDS; j++) led_state[j] = 0;
// Turn on the current LED
led_state[i] = 1;
// Run the display loop for a short time
for (int k = 0; k < 50; k++) { // 50 cycles of the display loop
for (int l = 0; l < NUM_LEDS; l++) {
if (led_state[l] == 1) {
setLED(l);
delayMicroseconds(2000);
}
}
}
}
}
// To use the chase effect, replace the loop() content with:
/* void loop() {
chase();
}
*/