/*
Arduino code for Individual control over each pin
Support for 40+ 74HC595 8 bit shift registers
http://bildr.org/2011/02/74hc595/
*/
// chatGPT character set for animation
const byte charSet[] = {
// Alternating / Blinking Patterns
0b01010101, // 55 - Alternating bits
0b10101010, // AA - Inverted alternating
0b11001100, // Double pairs
0b00110011, // Double pairs inverted
0b10011001, // Symmetric mirror
0b01100110, // Symmetric mirror inverted
// Sweeps / Crawlers (Left → Right)
0b00000001,
0b00000010,
0b00000100,
0b00001000,
0b00010000,
0b00100000,
0b01000000,
0b10000000,
// Sweeps / Crawlers (Edges & pairs)
0b10000001,
0b11000011,
0b11100111,
0b11111111, // All on
// 💡 Flash / Pulse / Fade
0b00011000, // Center pulse
0b00111100, // Medium pulse
0b01111110, // Wide pulse
0b00000000, // All off
// Borders & Centered Shapes
0b10000001,
0b11000011,
0b11100111,
0b01111110,
0b00111100,
0b00011000,
// Symmetric / Shape Patterns
0b10011001,
0b01100110,
0b11100000,
0b00000111,
0b00111111,
0b11111100,
0b00110011,
0b11001100,
0b10100101,
0b01011010,
0b11110000,
0b00001111,
// Random / Chaotic-Looking Patterns
0b10101001,
0b10010110,
0b01101010,
0b11010101,
0b00101001,
0b10001110,
0b11101000,
0b00010111,
// Duplicates for animation rhythm (optional reuse)
0b11111111, // Flash all on
0b00000000, // Flash all off
0b10000001, // Outer borders
0b11100000, // Edge-heavy left
0b00000111, // Edge-heavy right
0b11000011 // Edge blocks
};
const byte nChars = sizeof charSet / sizeof *charSet;
// Define ranges for each section of animation (start, length)
const byte animSections[][2] = {
{ 0, 6 }, // Alternating
{ 6, 8 }, // Left-to-Right Sweep
{14, 4 }, // Edges & pairs
{18, 4 }, // Flash / Pulse
{22, 6 }, // Borders & Shapes
{28,12 }, // Symmetric Patterns
{40, 8 }, // Chaotic
{48, 6 } // Rhythmic repeats
};
const byte numSections = sizeof(animSections) / sizeof(animSections[0]);
// Timing
unsigned long lastUpdate = 0;
const unsigned int frameInterval = 777; // Time between frames (ms)
const unsigned long sectionDuration = 9000; // Time per section (ms)
unsigned long sectionStartTime = 0;
// Animation state
byte currentChar = 0;
byte currentSection = 0;
#define DATA_PIN 8 // Pin connected to DS of 74HC595
#define LATCH_PIN 9 // Pin connected to STCP of 74HC595
#define CLOCK_PIN 10 // Pin connected to SHCP of 74HC595
// How many of the shift registers
#define NUM_SHIFT_REGS 1
const uint8_t numOfRegisterPins = NUM_SHIFT_REGS * 8;
bool registers[numOfRegisterPins];
unsigned char countBits(int n)
{
unsigned char count = 0;
while (n) {
// printf(" %d\n", n);
n &= (n - 1);
count++;
}
return count;
}
unsigned char lsfr8X(unsigned char xx) {
// tune for polynomial: this is 0xa6
if (xx == 1) return 0;
if (xx == 0) return 2;
char parity = countBits(xx & 0xa6) & 0x1;
xx <<= 1;
xx |= parity;
return xx;
}
unsigned char seq = 0x5a; // zero for zero zero, or retune
void setup() {
Serial.begin(115200);
Serial.println("\nchatGPT ANimation!\n");
pinMode(DATA_PIN, OUTPUT);
pinMode(CLOCK_PIN, OUTPUT);
pinMode(LATCH_PIN, OUTPUT);
clearRegisters();
writeRegisters();
sectionStartTime = millis();
}
void loop() {
unsigned long now = millis();
// Check if it's time to move to the next frame
if (now - lastUpdate >= frameInterval) {
lastUpdate = now;
// Display current character
byte start = animSections[currentSection][0];
byte len = animSections[currentSection][1];
byte pattern = charSet[start + (currentChar % len)];
displayPattern(pattern);
currentChar++;
}
// Move to next section if section duration elapsed
if (now - sectionStartTime >= sectionDuration) {
currentSection = (currentSection + 1) % numSections;
currentChar = 0;
sectionStartTime = now;
Serial.print("Switching to section: ");
Serial.println(currentSection);
}
}
void displayPattern(byte pattern) {
digitalWrite(LATCH_PIN, LOW);
shiftOut(DATA_PIN, CLOCK_PIN, MSBFIRST, pattern);
digitalWrite(LATCH_PIN, HIGH);
}
bool toggle = false;
void loop0() {
for (unsigned char ii = 0; ii < nChars; ii++) {
for (unsigned char jj = 0; jj < 8; jj++) {
setRegisterPin(7 - jj, charSet[ii] & (1 << jj));
}
writeRegisters();
delay(777);
}
return;
for (unsigned char ii = 0; ii < 8; ii++) {
setRegisterPin(7 - ii, seq & (1 << ii));
writeRegisters();
}
seq = lsfr8X(seq);
delay(477);
}
void clearRegisters() {
// Reset all register pins
for (int i = numOfRegisterPins - 1; i >= 0; i--) {
registers[i] = LOW;
}
}
void setRegisterPin(int index, int value) {
// Set an individual pin HIGH or LOW
registers[index] = value;
}
void writeRegisters() {
// Set and display registers
digitalWrite(LATCH_PIN, LOW);
for (int i = numOfRegisterPins - 1; i >= 0; i--) {
digitalWrite(CLOCK_PIN, LOW);
digitalWrite(DATA_PIN, registers[i]);
digitalWrite(CLOCK_PIN, HIGH);
}
digitalWrite(LATCH_PIN, HIGH);
}