156 lines
2.3 KiB
C++
156 lines
2.3 KiB
C++
#include <stdint.h>
|
|
#include <avr/sleep.h>
|
|
#include "./Adafruit_TLC59711.h"
|
|
|
|
|
|
void sleepUntilInterrupt();
|
|
|
|
Adafruit_TLC59711 controller(1);
|
|
#define SegmentCount 8
|
|
|
|
#define PinTiltSwitch 3
|
|
#define PinTiltSwitchMask PB3
|
|
//#define PinDebugLED 4
|
|
#define Timeout 2000
|
|
|
|
/* For PCB layout purposes the LED segments are connected to different pins. */
|
|
uint8_t channels[SegmentCount] = {
|
|
0,
|
|
1,
|
|
2,
|
|
3,
|
|
6,
|
|
7,
|
|
8,
|
|
9
|
|
};
|
|
|
|
uint16_t pwmValues[SegmentCount] = {
|
|
65535,
|
|
16384,
|
|
8192,
|
|
4096,
|
|
2048,
|
|
1024,
|
|
0,
|
|
0
|
|
};
|
|
|
|
|
|
/*
|
|
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 animationStart = 0;
|
|
|
|
|
|
void setup()
|
|
{
|
|
pinMode(PinTiltSwitch, INPUT_PULLUP);
|
|
//pinMode(PinDebugLED, OUTPUT);
|
|
|
|
controller.begin();
|
|
for (uint8_t segment = 0; segment < SegmentCount; segment++)
|
|
controller.setPWM(channels[segment], 0);
|
|
|
|
|
|
// 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)
|
|
{
|
|
animationStart = millis();
|
|
tiltChanged = false;
|
|
}
|
|
else if (animationStart == 0)
|
|
{
|
|
sleepUntilInterrupt();
|
|
return;
|
|
}
|
|
|
|
|
|
if (millis() - animationStart >= Timeout)
|
|
{
|
|
for (uint8_t segment = 0; segment < SegmentCount; segment++)
|
|
controller.setPWM(channels[segment], 0);
|
|
|
|
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;
|
|
else
|
|
segment--;
|
|
}
|
|
|
|
controller.write();
|
|
delay(75);
|
|
|
|
currentSegment++;
|
|
if (currentSegment == SegmentCount)
|
|
currentSegment = 0;
|
|
}
|
|
|
|
|
|
|
|
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_disable();
|
|
ADCSRA |= _BV(ADEN);
|
|
|
|
sei();
|
|
}
|
|
|
|
|
|
// Interrupt for pin changes
|
|
ISR(PCINT0_vect)
|
|
{
|
|
tiltChanged = true;
|
|
} |