TiltAlarm/src/main.cpp

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;
}