// pin connections constant won't change:
const int buttonPin = 2; // the pin that the pushbutton is attached to
const int ledPins[] = {8, 9, 10 }; //the pins that the ambient LED's are attached to
const int motorPin = 3; //the pin the motor is attached to
const int uvPin = 4; // the pin that the UV LED's are attached to
//const int speakerPin = 5; //TBA pin the attached connect to
// Button control Variables will change:
int buttonPushCounter = 0; // counter for the number of button presses
int buttonState = LOW; // current state of the button
// UV timeout settings
const unsigned long uvTimeOut = 4000; // TBA 900000 (15 min) for final code
unsigned long switchUVoffTimer = 0;
boolean checkUVTiming = false;
void setup() {
Serial.begin(9600); // initialize serial communication:
while (!Serial); // wait for serial to be ready
//knight rider setup start
for (int p = 0; p < 3; p++) {
pinMode(ledPins[p], OUTPUT);
} //knight rider setup end
// Initialize button pin
pinMode(buttonPin, INPUT_PULLUP); // initialize the button pin as a input:
// initialize the uvLED's,motor and speaker as an output:
pinMode(motorPin, OUTPUT);
pinMode(uvPin, OUTPUT);
//pinMode(speakerPin, OUTPUT);
Serial.println("Setup-Start press button");
}
void loop() {
buttonState = debouncedStateOfButton();
if (buttonState == HIGH) {
// if the current state is HIGH then the button went from off to on:
buttonPushCounter++;
Serial.print("Button Pushes ");
Serial.println(buttonPushCounter);
if (buttonPushCounter == 3) {
// check if UV-timing is RE-activated
// indicated through value 0
if (switchUVoffTimer == 0) {
// store actual timestamp
// this means switchUVoffTimer is UN-equal to zero
// => timestamp is stored only ONCE until RE-activating through storing value 0
switchUVoffTimer = millis();
digitalWrite(uvPin, HIGH);
checkUVTiming = true;
}
}
}
if (buttonPushCounter > 0) {
knightRider(); //one click turns on the ambient LED with effect
}
if (buttonPushCounter > 1) {
digitalWrite(motorPin, HIGH); //two cliks turns on the motor while ambient LED stays on
}
if (buttonPushCounter > 2) {
if (checkUVTiming == true) {
uvLightsOut();
}
}
if (buttonPushCounter > 3) {
//digitalWrite(speakerPin, HIGH); //four clicks turns on speaker
}
if (buttonPushCounter > 4) {
digitalWrite(motorPin, LOW);
digitalWrite(uvPin, LOW);
// digitalWrite(speakerPin, LOW); //Five clicks turns all LED's, motor and speaker off
}
if (buttonPushCounter == 5) {
buttonPushCounter = 0; //reset button counter to 0
for (int p = 0; p < 3; p++) {
digitalWrite(ledPins[p], LOW);
}
}
}
void knightRider() {
static int knightLight = 0; // using the attribute "static" makes variables persistant over function-calls
static int knightCounter = 1;
static unsigned long knightRiderTimer;
static unsigned long interval = 75;
if ( TimePeriodIsOver(knightRiderTimer, interval) ) {
delay(1);
// reset last knightlight
digitalWrite(ledPins[knightLight], LOW);
// calc new knight light
knightLight = knightLight + knightCounter;
if (knightLight > 3 ) {
knightLight = 3;
knightCounter = -1;
}
if (knightLight < 0) {
knightLight = 0;
knightCounter = 1;
}
// set new knight light
digitalWrite(ledPins[knightLight], HIGH);
}
}
// Timeout for UV light Function
void uvLightsOut() {
if (checkUVTiming == true) {
// check to see if it's time to turn off the uvLED; that is, if the difference
// between the current time and last time you turned on the LED is bigger than
// the timeOut at which you want to turn off the uvLED.
if ( TimePeriodIsOver(switchUVoffTimer, uvTimeOut) ) {
Serial.println("UV Ontime over switching off UV-Leds");
digitalWrite(uvPin, LOW);
checkUVTiming = false; // set back to false
switchUVoffTimer = 0; // store 0 to RE-activate storing of timestamp
}
}
}
// easy to use helper-function for non-blocking timing
boolean TimePeriodIsOver (unsigned long & startOfPeriod, unsigned long TimePeriod) {
unsigned long currentMillis = millis();
if ( currentMillis - startOfPeriod >= TimePeriod ) {
// more time than TimePeriod has elapsed since last time if-condition was true
startOfPeriod = currentMillis; // a new period starts right here so set new starttime
return true;
}
else return false; // actual TimePeriod is NOT yet over
}
byte debouncedStateOfButton() {
static byte actualButtonState = HIGH;
static byte lastButtonState = HIGH;
static unsigned long debounceTimer;
byte intervalDebounce = 50;
byte result = LOW;
if ( TimePeriodIsOver(debounceTimer, intervalDebounce) ) {
// read the pushbutton input pin:
actualButtonState = digitalRead(buttonPin);
// compare the buttonState to its previous state
if (actualButtonState != lastButtonState) {
lastButtonState = actualButtonState;
if (actualButtonState == HIGH) {
result = HIGH;
}
else {
result = LOW;
}
}
}
return result;
}