diff --git a/src/main.cpp b/src/main.cpp index 73571c1..77c09b2 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -6,7 +6,6 @@ void sleepUntilInterrupt(); Adafruit_TLC59711 controller(1); -#define SegmentCount 8 #define PinTiltSwitch 3 #define PinTiltSwitchMask PB3 @@ -14,7 +13,8 @@ Adafruit_TLC59711 controller(1); #define Timeout 2000 /* For PCB layout purposes the LED segments are connected to different pins. */ -uint8_t channels[SegmentCount] = { +#define SegmentCount 8 +const uint8_t channels[SegmentCount] = { 0, 1, 2, @@ -25,15 +25,15 @@ uint8_t channels[SegmentCount] = { 9 }; -uint16_t pwmValues[SegmentCount] = { - 65535, - 16384, - 8192, - 4096, - 2048, + +#define AnimationSteps 6 +const uint16_t pwmValues[AnimationSteps] = { 1024, - 0, - 0 + 2048, + 4096, + 8192, + 16384, + 65535 }; @@ -52,8 +52,12 @@ void debugBlink(uint8_t count) volatile bool tiltChanged = false; + uint8_t currentSegment = 0; -uint32_t animationStart = 0; +uint32_t animationStartTime = 0; +bool animationStopping = false; + +uint8_t animationValues[SegmentCount]; void setup() @@ -61,10 +65,19 @@ void setup() pinMode(PinTiltSwitch, INPUT_PULLUP); //pinMode(PinDebugLED, OUTPUT); - controller.begin(); - for (uint8_t segment = 0; segment < SegmentCount; segment++) - controller.setPWM(channels[segment], 0); + 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); @@ -85,67 +98,75 @@ void loop() { if (tiltChanged) { - animationStart = millis(); + animationStartTime = millis(); + animationStopping = false; tiltChanged = false; } - else if (animationStart == 0) + + + // Decrease all current values + bool allStopped = true; + for (uint8_t segment = 0; segment < SegmentCount; segment++) { - sleepUntilInterrupt(); - return; + if (animationValues[segment] > 0) + { + animationValues[segment]--; + allStopped = false; + } + } + + if (!animationStopping) + { + allStopped = false; + animationValues[currentSegment] = AnimationSteps; + + // Check for timeout + if (millis() - animationStartTime >= Timeout) + animationStopping = true; } - if (millis() - animationStart >= Timeout) + // Output the current values + for (uint8_t segment = 0; segment < SegmentCount; segment++) { - for (uint8_t segment = 0; segment < SegmentCount; segment++) - controller.setPWM(channels[segment], 0); + uint8_t animationValue = animationValues[segment]; - controller.write(); - animationStart = 0; - return; - } - - - uint8_t segment = currentSegment; - for (uint8_t channel = 0; channel < SegmentCount; channel++) - { - controller.setPWM(channels[segment], pwmValues[channel]); - - if (segment == 0) - segment = SegmentCount - 1; + if (animationValue > 0) + controller.setPWM(channels[segment], pwmValues[animationValue - 1]); else - segment--; + controller.setPWM(channels[segment], 0); } controller.write(); - delay(75); + currentSegment++; if (currentSegment == SegmentCount) currentSegment = 0; + + + + // If the animation has ended, sleep + if (allStopped) + { + sleepUntilInterrupt(); + return; + } + else + delay(75); } void sleepUntilInterrupt() { - // Turn ADC off - ADCSRA &= ~_BV(ADEN); set_sleep_mode(SLEEP_MODE_PWR_DOWN); - // Set sleep bit and halt the CPU sleep_enable(); - sei(); - sleep_cpu(); - - // ...goooood morning! - cli(); - - + sleep_mode(); sleep_disable(); - ADCSRA |= _BV(ADEN); - sei(); + tiltChanged = true; }