// === 32-LED Charlieplex Auto-Cycle (Arduino Nano) ===
// P0..P6 = D2..D8 (through 220Ω each)
#include <Arduino.h>
const uint8_t NODES[7] = {2,3,4,5,6,7,8};
const uint8_t NUM_LEDS = 32;
struct Pair { uint8_t hi, lo; };
// LED map (weeks layout)
const Pair LEDMAP[NUM_LEDS] = {
// Week 1
{1,0},{2,0},{3,0},{4,0},{5,0},{6,0},{0,1},
// Week 2
{2,1},{3,1},{4,1},{5,1},{0,2},{1,2},{3,2},
// Week 3
{4,2},{5,2},{6,2},{0,3},{1,3},{2,3},{4,3},
// Week 4
{5,3},{6,3},{0,4},{1,4},{2,4},{3,4},{5,4},
// Week 5
{6,4},{0,5},{1,5},{2,5}
};
// -------------------- Charlieplex core --------------------
void allHiZ() {
for (uint8_t i=0; i<7; i++) pinMode(NODES[i], INPUT);
}
void pulseOne(uint8_t idx, unsigned int us) {
allHiZ();
auto p = LEDMAP[idx];
pinMode(NODES[p.hi], OUTPUT); digitalWrite(NODES[p.hi], HIGH);
pinMode(NODES[p.lo], OUTPUT); digitalWrite(NODES[p.lo], LOW);
delayMicroseconds(us);
}
// -------------------- Animations --------------------
void playAnimations() {
Serial.println(F(">> Animation Mode <<"));
// 1. Chase forward
for (uint8_t r=0; r<2; r++) {
for (uint8_t i=0; i<NUM_LEDS; i++) pulseOne(i, 800);
}
// 2. Bounce
for (uint8_t r=0; r<2; r++) {
for (int i=0; i<NUM_LEDS; i++) pulseOne(i, 600);
for (int i=NUM_LEDS-1; i>=0; i--) pulseOne(i, 600);
}
// 3. Blink all
for (uint8_t r=0; r<4; r++) {
for (uint8_t i=0; i<NUM_LEDS; i++) pulseOne(i, 700);
delay(150);
}
// 4. Wave (week by week)
for (uint8_t w=0; w<5; w++) {
for (uint8_t d=0; d<7 && w*7+d<NUM_LEDS; d++) {
pulseOne(w*7+d, 1200);
}
}
Serial.println(F(">> Animation Done <<"));
}
// -------------------- New Comet Animation --------------------
void cometAnimation(uint8_t cycles=2, uint8_t trail=5, uint16_t hold=80) {
Serial.println(F(">> Comet Animation <<"));
for (uint8_t c=0; c<cycles; c++) {
for (uint8_t i=0; i<NUM_LEDS; i++) {
// head
pulseOne(i, 1500);
// fading trail behind comet
for (uint8_t t=1; t<=trail; t++) {
if (i >= t) pulseOne(i-t, 600/(t+1));
}
delay(hold);
}
}
Serial.println(F(">> Comet Done <<"));
}
// -------------------- Snake Animation --------------------
void snakeAnimation(uint8_t cycles=3, uint8_t length=6, uint16_t hold=100) {
Serial.println(F(">> Snake Animation <<"));
for (uint8_t c=0; c<cycles; c++) {
// forward slither
for (uint8_t i=0; i<NUM_LEDS+length; i++) {
for (uint8_t seg=0; seg<length; seg++) {
int pos = i - seg;
if (pos >= 0 && pos < NUM_LEDS) {
// pulse stronger at the "head", weaker at the "tail"
uint16_t power = 1200 / (seg+1);
pulseOne(pos, power);
}
}
delay(hold);
}
// backward slither
for (int i=NUM_LEDS+length-1; i>=0; i--) {
for (uint8_t seg=0; seg<length; seg++) {
int pos = i - seg;
if (pos >= 0 && pos < NUM_LEDS) {
uint16_t power = 1200 / (seg+1);
pulseOne(pos, power);
}
}
delay(hold);
}
}
Serial.println(F(">> Snake Done <<"));
}
// -------------------- Shape Animations --------------------
// Helper: light a pattern (indexes from array)
void drawShape(const uint8_t *pattern, uint8_t count, uint16_t hold=300) {
for (uint8_t r=0; r<3; r++) { // blink 3 times
for (uint8_t i=0; i<count; i++) {
pulseOne(pattern[i], 1500);
}
delay(hold);
}
}
// ⭐ Star (rough star in the grid)
void starAnimation() {
Serial.println(F(">> Star Animation <<"));
const uint8_t star[] = {3, 9, 11, 14, 17, 19, 25, 28};
drawShape(star, sizeof(star), 400);
Serial.println(F(">> Star Done <<"));
}
// ❤ Heart
void heartAnimation() {
Serial.println(F(">> Heart Animation <<"));
const uint8_t heart[] = {
1,2,4,5, // top bumps
8,9,11,12, // upper mid
15,16,17,18,19, // middle row
22,23,24,25, // lower taper
30 // tip
};
drawShape(heart, sizeof(heart), 400);
Serial.println(F(">> Heart Done <<"));
}
// 🏠 House
void houseAnimation() {
Serial.println(F(">> House Animation <<"));
const uint8_t house[] = {
3, // roof peak
9,10,11, // roof slope
15,16,17,18,19, // roof base
22,23,24,25,26, // walls
29,30,31 // door base
};
drawShape(house, sizeof(house), 400);
Serial.println(F(">> House Done <<"));
}
// -------------------- Setup & Loop --------------------
void setup() {
allHiZ();
Serial.begin(115200);
while (!Serial) {}
Serial.println(F("\n== Charlieplex Calendar Auto Boot =="));
}
void loop() {
// Cycle through all LEDs one by one
for (uint8_t i=0; i<NUM_LEDS; i++) {
pulseOne(i, 1500); // show one LED
delay(100); // hold for 0.1s
}
// After finishing all LEDs → play animations
starAnimation();
heartAnimation();
houseAnimation();
playAnimations();
snakeAnimation();
cometAnimation();
}
P0 (D2)
P1 (D3)
P2 (D4)
P3 (D5)
P4 (D6)
P5 (D7)
P6 (D8)