#include #include #include "./Adafruit_TLC59711.h" void sleepUntilInterrupt(); Adafruit_TLC59711 controller(1); #define PinTiltSwitch 3 #define PinTiltSwitchMask PB3 //#define PinDebugLED 4 #define Timeout 2000 /* For PCB layout purposes the LED segments are connected to different pins. */ #define SegmentCount 8 const uint8_t channels[SegmentCount] = { 0, 1, 2, 3, 6, 7, 8, 9 }; #define AnimationSteps 6 const uint16_t pwmValues[AnimationSteps] = { 1024, 2048, 4096, 8192, 16384, 65535 }; /* void debugBlink(uint8_t count) { for (uint8_t i = 0; i < count; i++) { digitalWrite(PinDebugLED, HIGH); delay(150); digitalWrite(PinDebugLED, LOW); delay(150); } } */ volatile bool tiltChanged = false; uint8_t currentSegment = 0; uint32_t animationStartTime = 0; bool animationStopping = false; uint8_t animationValues[SegmentCount]; void setup() { pinMode(PinTiltSwitch, INPUT_PULLUP); //pinMode(PinDebugLED, OUTPUT); memset(animationValues, 0, sizeof(animationValues)); controller.begin(); for (uint8_t channel = 0; channel < 12; channel++) controller.setPWM(channel, 0); controller.write(); // Turn ADC off ADCSRA &= ~_BV(ADEN); // Clear outstanding interrupts GIFR |= _BV(PCIF); // Enable pin change interrupts GIMSK |= _BV(PCIE); // Set up pin change mask PCMSK = _BV(PinTiltSwitchMask); sleepUntilInterrupt(); } void loop() { if (tiltChanged) { animationStartTime = millis(); animationStopping = false; tiltChanged = false; } // Decrease all current values bool allStopped = true; for (uint8_t segment = 0; segment < SegmentCount; segment++) { if (animationValues[segment] > 0) { animationValues[segment]--; allStopped = false; } } if (!animationStopping) { allStopped = false; animationValues[currentSegment] = AnimationSteps; // Check for timeout if (millis() - animationStartTime >= Timeout) animationStopping = true; } // Output the current values for (uint8_t segment = 0; segment < SegmentCount; segment++) { uint8_t animationValue = animationValues[segment]; if (animationValue > 0) controller.setPWM(channels[segment], pwmValues[animationValue - 1]); else controller.setPWM(channels[segment], 0); } controller.write(); currentSegment++; if (currentSegment == SegmentCount) currentSegment = 0; // If the animation has ended, sleep if (allStopped) { sleepUntilInterrupt(); return; } else delay(75); } void sleepUntilInterrupt() { set_sleep_mode(SLEEP_MODE_PWR_DOWN); sleep_enable(); sleep_mode(); sleep_disable(); tiltChanged = true; } // Interrupt for pin changes ISR(PCINT0_vect) { tiltChanged = true; }