177 lines
2.8 KiB
C++
177 lines
2.8 KiB
C++
#include <stdint.h>
|
|
#include <avr/sleep.h>
|
|
#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;
|
|
} |