/*
Based on countdown timer:
https://home.et.utwente.nl/slootenvanf/2020/06/08/countdown-timers-tasks-in-parallel/
Avoid use of delays by using tasks that are executed on a certain time.
Author: F. van Slooten
*/
#include <Bounce2.h>
#define RED A3 // Red light connected to analog pin A3
#define YELLOW A4 // Yellow light connected to analog pin A5
#define GREEN A5 // Green light connected to analog pin A4
#define BUZZER 9
// leds for difficuly level:
#define LED_EASY_PIN 4
#define LED_MEDIUM_PIN 3
#define LED_HARD_PIN 2
byte button_pins[] = { 5, 6, 7 }; // button pins for difficulty
#define NUMBUTTONS sizeof(button_pins)
Bounce * buttons = new Bounce[NUMBUTTONS];
unsigned long previousMillis = 0, previousMillis2 = 0; // will store last time timer was updated
unsigned long interval = 1000; // 1 second
int difficulty = 2; // 1 = easy, 2 = medium, 3 = hard
int state = 0; // blinking the leds
bool blink = true;
void setup() {
Serial.begin(9600);
// Initialize the pins as outputs
pinMode(GREEN, OUTPUT);
pinMode(RED, OUTPUT);
pinMode(YELLOW, OUTPUT);
pinMode(LED_EASY_PIN, OUTPUT);
pinMode(LED_MEDIUM_PIN, OUTPUT);
pinMode(LED_HARD_PIN, OUTPUT);
pinMode(BUZZER, OUTPUT);
// Make input & enable pull-up resistors on switch pins
for (int i = 0; i < NUMBUTTONS; i++) {
buttons[i].attach( button_pins[i] , INPUT_PULLUP ); //setup the bounce instance for the current button
buttons[i].interval(25); // interval in ms
}
// initialize random generator
randomSeed(analogRead(0));
// show difficulty (starts as medium):
digitalWrite(LED_EASY_PIN, LOW);
digitalWrite(LED_MEDIUM_PIN, HIGH);
digitalWrite(LED_HARD_PIN, LOW);
}
void loop() {
unsigned long currentMillis = millis();
interval = random(3000, 7000); // Generate random delays for each light change
// task 1 - update blinking
if (currentMillis - previousMillis > interval) { // interval passed?
previousMillis = currentMillis; // save the last time
if (state==0) {
red_light();
} else if (state==1) {
yellow_light();
} else if (state==2) {
green_light();
} else if (state==3) {
buzzer_sound();
yellow_light();
} else if (state==4) {
buzzer_sound_off();
state = -1;
}
state++;
}
// task 2 - check for pressed buttons
for (int i = 0; i < NUMBUTTONS; i++) {
// Update the Bounce instance :
buttons[i].update();
if ( buttons[i].fell() ) { // a button was pressed
difficulty++; // 1 = easy, 2 = medium, 3 = hard
if (difficulty>3) difficulty = 1;
// show difficulty:
if (difficulty==1) {
digitalWrite(LED_EASY_PIN, HIGH);
digitalWrite(LED_MEDIUM_PIN, LOW);
digitalWrite(LED_HARD_PIN, LOW);
}
else if (difficulty==2) {
digitalWrite(LED_EASY_PIN, LOW);
digitalWrite(LED_MEDIUM_PIN, HIGH);
digitalWrite(LED_HARD_PIN, LOW);
}
else if (difficulty==3) {
digitalWrite(LED_EASY_PIN, LOW);
digitalWrite(LED_MEDIUM_PIN, LOW);
digitalWrite(LED_HARD_PIN, HIGH);
}
Serial.print("difficulty "); Serial.println(difficulty);
} // end if - fell
} // end for
}
// Function to turn on the green light
void green_light() {
digitalWrite(GREEN, HIGH);
digitalWrite(RED, LOW);
digitalWrite(YELLOW, LOW);
}
// Function to turn on the red light
void red_light() {
digitalWrite(GREEN, LOW);
digitalWrite(RED, HIGH);
digitalWrite(YELLOW, LOW);
}
// Function to turn on the yellow light
void yellow_light() {
digitalWrite(GREEN, LOW);
digitalWrite(RED, LOW);
digitalWrite(YELLOW, HIGH);
}
void buzzer_sound() {
tone(BUZZER, 1000); // Generate a 1000 Hz tone
Serial.println("Buzz");
}
void buzzer_sound_off() {
noTone(BUZZER);
Serial.println("Buzzer off");
}