// Define Pins
const uint8_t eyeLedLeft = PB3; // sets Pin D10 to Eye LED, will become Pin 3 for ATTiny85
const uint8_t eyeLedRight = PB4; // sets Pin D11 to Eye LED, will become Pin 4 for ATTiny85
const uint8_t lightningLedWhite = PB0; // sets D8 to lightning Led, for lightning Effect, will become Pin 2 for ATTiny85
const uint8_t lightningLedUV = PB1; // Sets D9 to lightning Led, for UV lightning Fade, will become Pin 1 for ATTiny85
const uint8_t lowPins = PB2;
// Blinking and Winking Constants
const uint8_t MIN_EYE_BLINK = 65; //sets minimum blinking frequency
const uint8_t MAX_EYE_BLINK = 90; //sets max eye blink frequency. Longer means less often
const uint16_t MIN_EYE_WINK = 1800; //sets minimum winking frequency
const uint16_t MAX_EYE_WINK = 3600; //sets max winking frequency. Longer means less often
const uint8_t MAX_CURRENT_BLINK = 5; //sets eye blink lingth. Longer means... err, longer
const uint8_t MAX_CURRENT_WINK = 10; //sets eye blink lingth. Longer means... err, longer
const uint8_t lightningFadeDuration = 30; //sets duration of lightning fade
const float lightningFadeAmount = 0.95; //sets how much light fades per sectin, curretntly 5%
// Lightning Constants
const uint8_t MAX_BRIGHTNESS_LIGHTNING_LED = 255; //sets max brightness to 255, max value
const uint8_t MIN_NEXT_LIGHTNING_STRIKE = 50; //represents minimum frequency (in seconds) that lightning will strike
const uint16_t MAX_NEXT_LIGHTNING_STRIKE = 360; //represents maximum frequency (in seconds) that lightning will strike
uint8_t multipleStrikeChance = 4; //represents maximum frequency (in seconds) that lightning will strike
const uint8_t delayLength = 100; //sets delay heartbeat
// Function Declarations
void initializePins();
void startEyes();
void performBlink();
void performWink();
void handleLightning();
void handleBlink();
// Variable Declarations
uint8_t eyeBlink;
uint16_t eyeWink;
uint8_t currentBlink;
uint8_t currentWink;
uint8_t brightnessLightningLed;
uint8_t nextLightningStrike;
uint8_t currentTickBlink;
uint8_t currentTickWink;
uint8_t currentTickLightning;
//starts a boolian for clockspeed, and start out in regular (fast) mode
bool clockFast = true;
void setup() {
initializePins();
startEyes();
randomSeed(analogRead(0));
nextLightningStrike = random(MIN_NEXT_LIGHTNING_STRIKE, MAX_NEXT_LIGHTNING_STRIKE);
eyeBlink = random(MIN_EYE_BLINK, MAX_EYE_BLINK);
eyeWink = random(MIN_EYE_WINK, MAX_EYE_WINK);
}
void loop() {
fastClock(); //sets fastClock while running logic loop
currentTickWink++;
currentTickLightning++;
currentTickBlink++;
handleBlink(); //que Blink Logic
handleLightning(); //que Lightning Logic
slowClock();//sets slowClock while waiting
delay(delayLength/8); //delay for a heartbeat.
}
void fastClock(){ //fastCLock logic, sets speed to full (8mhz)
noInterrupts();
CLKPR = 0x80; // enable clock prescale change
CLKPR = 0; // no prescale
interrupts();
}
void slowClock(){ //slowCLock logic, sets speed to slow (1mhz)
noInterrupts();
CLKPR = 0x80; // enable clock prescale change
CLKPR = 3; // divide by 8 prescale
interrupts();
}
void initializePins() {
pinMode(eyeLedLeft, OUTPUT);
pinMode(eyeLedRight, OUTPUT);
pinMode(lightningLedUV, OUTPUT);
pinMode(lightningLedWhite, OUTPUT);
pinMode(lowPin, OUTPUT)
}
void startEyes() { //sets eyes to High when it turns on
digitalWrite(eyeLedLeft, HIGH);
digitalWrite(eyeLedRight, HIGH);
digitalWrite(lowPin, LOW);
}
void handleLightning() {
analogWrite(lightningLedUV, brightnessLightningLed);
if (nextLightningStrike == currentTickLightning) {
digitalWrite(lightningLedWhite, HIGH);
brightnessLightningLed = MAX_BRIGHTNESS_LIGHTNING_LED;
nextLightningStrike = random(MIN_NEXT_LIGHTNING_STRIKE, MAX_NEXT_LIGHTNING_STRIKE);
currentTickLightning = 0;
if (random(1, 11) == 1) {// Add a 10% chance for a second lightning strike
nextLightningStrike = 5;
} else {
nextLightningStrike = random(MIN_NEXT_LIGHTNING_STRIKE, MAX_NEXT_LIGHTNING_STRIKE);
}
} else if (currentTickLightning <= lightningFadeDuration) {
brightnessLightningLed *= lightningFadeAmount;
digitalWrite(lightningLedWhite, LOW);
} else {
brightnessLightningLed = 0;
}
}
void handleBlink() {// Blinking and Winking Logic
if (eyeWink == currentTickWink) {
performWink(); // Prioritize winking over blinking
} else if (eyeBlink == currentTickBlink && eyeWink != MAX_CURRENT_WINK) {
performBlink(); //blinks, if not currently winking
} else {
//If blinking and winking doesnt need to start...
if (currentBlink < MAX_CURRENT_BLINK) {
currentBlink++;
} else if (currentWink < MAX_CURRENT_WINK) {
currentWink++;
} else {
// Set eyes to high only when both blink and wink are finished
digitalWrite(eyeLedLeft, HIGH);
digitalWrite(eyeLedRight, HIGH);
}
}
}
void performBlink() { //Blink
digitalWrite(eyeLedLeft, LOW);
digitalWrite(eyeLedRight, LOW);
eyeBlink = random(MIN_EYE_BLINK, MAX_EYE_BLINK);
currentTickBlink = 0;
currentBlink = 0;
}
void performWink() {
currentWink = 0;
currentTickWink = 0;
eyeWink = random(MIN_EYE_WINK, MAX_EYE_WINK);
digitalWrite(eyeLedLeft, LOW);
digitalWrite(eyeLedRight, HIGH);
}