#include <OneWire.h>
const int buttonPin = 2;
const int relayPin = 0;
const int redPin = 3;
const int grnPin = 4;
const int bluPin = 1;
const int pollInterval = 100;
const unsigned int minuteMillis = 60000;
const int startReminders = 15; // minutes until we start flashing reminders
unsigned int elapsedMinutes = 0; // minutes since start of timing
unsigned int elapsedMillis = 0; // milliseconds of current second
int reminderElapsed = -1; // milliseconds since this reminder started
// Serial iButton
OneWire ds(buttonPin); // on pin 10
byte addr[8];
byte infiniteLives = 0;
// # of items in the reminderDuration array
byte reminderCount = 10;
// When reminders start, we will switch light off for given number of milliseconds
int reminderDuration[] = { 2000, 2000, 2000, 2000, 2000, 3000, 3000, 3000, 3000, 3000 };
void setup() {
pinMode(relayPin, OUTPUT);
pinMode(redPin, OUTPUT);
pinMode(grnPin, OUTPUT);
pinMode(bluPin, OUTPUT);
pinMode(buttonPin, INPUT);
// Switch light ON when powered up
digitalWrite(relayPin, HIGH);
}
void loop() {
delay(pollInterval);
elapsedMillis = elapsedMillis + pollInterval;
if(infiniteLives == 1) {
// iButton key previously verified, slow blink
rgbTransition(0, 0, 0, 0, 0, 99, 500); // fade blue on
rgbTransition(0, 0, 99, 0, 0, 0, 500); // fade blue off
delay(5000);
return;
}
// check if iButton is present
if ( !ds.search(addr)) {
ds.reset_search();
} else if ( OneWire::crc8( addr, 7) != addr[7]) {
rgbTransition(0, 0, 0, 99, 0, 99, 50); // fade purple on
rgbTransition(99, 0, 99, 0, 0, 0, 50); // fade purple off
rgbTransition(0, 0, 0, 99, 0, 99, 50); // fade purple on
rgbTransition(99, 0, 99, 0, 0, 0, 50); // fade purple off
} else {
// Acknowledge valid iButton
rgbTransition(0, 0, 0, 0, 99, 0, 50); // fade green on
rgbTransition(0, 99, 0, 0, 0, 0, 50); // fade green off
rgbTransition(0, 0, 0, 0, 99, 0, 50); // fade green on
rgbTransition(0, 99, 0, 0, 0, 0, 50); // fade green off
// Turn on lights (in case they were off)
digitalWrite(relayPin, HIGH);
infiniteLives = 1;
ds.reset();
return;
}
if(reminderElapsed >= 0)
reminderElapsed = reminderElapsed + pollInterval;
elapsedMillis = elapsedMillis % minuteMillis;
// Another minute has passed
if(elapsedMillis == 0) {
elapsedMinutes++;
if(elapsedMinutes >= startReminders) {
if(elapsedMinutes >= startReminders+reminderCount) {
// Leave light off
digitalWrite(relayPin, LOW);
// "Evil" blink (red)
rgbTransition(0, 0, 0, 75, 0, 0, 500);
rgbTransition(75, 0, 0, 0, 0, 0, 500);
} else {
if(reminderDuration[elapsedMinutes - startReminders] > 0) {
// start the reminder timer
reminderElapsed = 0;
digitalWrite(relayPin, LOW);
}
// "Danger" blink
rgbTransition(0, 0, 0, 75, 75, 0, 500); // fade red+green on
rgbTransition(75, 75, 0, 0, 0, 0, 500); // fade red+green off
}
} else {
// "All's Well" blink
rgbTransition(0, 0, 0, 0, 75, 0, 250); // fade green on
rgbTransition(0, 75, 0, 0, 75, 75, 250); // fade blue on
rgbTransition(0, 75, 75, 0, 0, 75, 250); // fade green off
rgbTransition(0, 0, 75, 0, 0, 0, 250); // fade blue off
}
}
if(reminderElapsed >= 0) {
if(reminderElapsed == reminderDuration[elapsedMinutes - startReminders])
{
// disable the reminder timer
reminderElapsed = -1;
digitalWrite(relayPin, HIGH);
}
}
}
// PWM transition from rgb1 -> rgb2 in 'duration' milliseconds
// rgb values must be 0-99
void rgbTransition(char r1, char g1, char b1, char r2, char g2, char b2, int duration)
{
for(int step = 0;step < duration;step++) {
// Each millisecond is a step in the transition
char rOn = r1+(r2-r1)*float(step)/float(duration);
char gOn = g1+(g2-g1)*float(step)/float(duration);
char bOn = b1+(b2-b1)*float(step)/float(duration);
for(byte i=0;i<3;i++) {
if(rOn>0)
digitalWrite(redPin, HIGH);
if(gOn>0)
digitalWrite(grnPin, HIGH);
if(bOn>0)
digitalWrite(bluPin, HIGH);
byte j = 0;
while(j<100) {
if(rOn == j)
digitalWrite(redPin, LOW);
if(gOn == j)
digitalWrite(grnPin, LOW);
if(bOn == j)
digitalWrite(bluPin, LOW);
j = j + 1;
}
}
}
digitalWrite(redPin, LOW);
digitalWrite(grnPin, LOW);
digitalWrite(bluPin, LOW);
}