#include #include //Start button pins and state const int BUTTON_START_PIN = 2; //Digital pin 2 on the Uno const int LED_START_BUTTON_PIN = 3; //Digital pin 3 on the Uno int startButtonState = 0; //0 = OFF, 1 = ON //Stop button pins and state const int BUTTON_STOP_PIN = 4; //Digital pin 4 on the Uno const int LED_STOP_BUTTON_PIN = 5; //Digital pin 5 on the Uno int stopButtonState = 0; //0 = OFF, 1 = ON //Lamp pins const int RELAY_LAMP_PIN = 6; //Digital pin 6 on the Uno //Shift register pins const int SHIFT_DATA = 11; //Digital pin 11 on Uno, pin 14 on 74HC595 const int SHIFT_CLK = 12; //Digital pin 12 on Uno, pin 11 on 74HC595 const int SHIFT_LATCH = 8; //Digital pin 8 on Uno, pin 12 on 74HC595 //Byte array of digits from 0 to 9. byte digits[10] = { // .GFEDCBA 0xC0, //0, b11000000 0xF9, //1, b11111001 0xA4, //2, b10100100 0xB0, //3, b10110000 0x99, //4, b10011001 0x92, //5, b10010010 0x82, //6, b10000010 0xF8, //7, b11111000 0x80, //8, b10000000 0x90 //9, b10010000 }; //State machine configuration const int STATE_STANDBY = 0; //State when awaiting for user input const int STATE_COUNTDOWN = 1; //State when counting down to RUNNING const int STATE_RUNNING = 2; //State when the lamp is on int state = STATE_STANDBY; //Default to STANDBY //Program cycle configuration const int RUNTIME_COUNTDOWN = 8; //8 seconds const int RUNTIME_RUNNING = 20; //20 seconds CountUpDownTimer timer(DOWN); //Countdown timer void initButtons() { //Set the buttons to INPUT pinMode(BUTTON_START_PIN, INPUT); pinMode(BUTTON_STOP_PIN, INPUT); //Set the button LEDs to OUTPUT pinMode(LED_START_BUTTON_PIN, OUTPUT); pinMode(LED_STOP_BUTTON_PIN, OUTPUT); //Set the button LEDs digitalWrite(LED_START_BUTTON_PIN, HIGH); digitalWrite(LED_STOP_BUTTON_PIN, LOW); } void initDisplay() { //Set the shift register pin modes to OUTPUT pinMode(SHIFT_LATCH, OUTPUT); pinMode(SHIFT_CLK, OUTPUT); pinMode(SHIFT_DATA, OUTPUT); } void initRelays() { //Set the lamp relay pin to OUTPUT and set it to LOW pinMode(RELAY_LAMP_PIN, OUTPUT); digitalWrite(RELAY_LAMP_PIN, LOW); } void updateDisplay(int value) { /* Split the number into two integers. Add thirdDigit etc. when adding * more digits */ int firstDigit = value / 10; int secondDigit = value % 10; //Set latch LOW so segments do not change while sending digitalWrite(SHIFT_LATCH, LOW); //Shift out the bits going in reverse, starting with the second shiftOut(SHIFT_DATA, SHIFT_CLK, MSBFIRST, digits[secondDigit]); shiftOut(SHIFT_DATA, SHIFT_CLK, MSBFIRST, digits[firstDigit]); //Set latch HIGH so the correct segments light up digitalWrite(SHIFT_LATCH, HIGH); } void setup() { /* Setup the relays first to ensure they have the correct state before * starting. */ initRelays(); //Setup the buttons initButtons(); //Setup the display initDisplay(); //Set the display to 00 updateDisplay(00); } void loop() { //Process the timer before processing input bool timerTick = timer.Timer(); //Only update the display when the time has changed if (timer.TimeHasChanged()) { //Get the time value from the timer unsigned long timerValue = timer.ShowSeconds(); updateDisplay(timerValue); } //Process the start button only when in STANDBY if (state == STATE_STANDBY) { //Read the start button's state startButtonState = digitalRead(BUTTON_START_PIN); //Check for the button press if (startButtonState == HIGH) { /* Debounce to prevent multi-fire before handling the button's * state */ delay(50); //Turn off the start button LED and turn on the stop button LED digitalWrite(LED_START_BUTTON_PIN, LOW); digitalWrite(LED_STOP_BUTTON_PIN, HIGH); //Change the state to COUNTDOWN state = STATE_COUNTDOWN; //Set the timer for 8 seconds and run it timer.SetTimer(0, 0, RUNTIME_COUNTDOWN); timer.StartTimer(); } } //Process the stop button only when RUNNING or is in COUNTDOWN mode if ((state == STATE_COUNTDOWN || state == STATE_RUNNING) && timerTick) { //Read the stop button's state stopButtonState = digitalRead(BUTTON_STOP_PIN); //Check for the button press if (stopButtonState == HIGH) { //Turn off the lamp digitalWrite(RELAY_LAMP_PIN, LOW); //Turn on the start button LED and turn off the stop button LED digitalWrite(LED_START_BUTTON_PIN, HIGH); digitalWrite(LED_STOP_BUTTON_PIN, LOW); //Change the state to STANDBY and stop the timer state = STATE_STANDBY; timer.StopTimer(); //Set the display to 00 updateDisplay(00); /* Debounce to prevent multi-fire before handling the button's * state */ delay(50); //debounce } } /* Check to see if the countdown has ended (when it is 00:00:00), and * update the state machine accordingly. */ if (timer.ShowHours() == 0 && timer.ShowMinutes() == 0 && timer.ShowSeconds() == 0) { //Change the state to RUNNING of we are in COUNTDOWN mode if (state == STATE_COUNTDOWN) { //Turn on the lamp digitalWrite(RELAY_LAMP_PIN, HIGH); //Change the state to RUNNING state = STATE_RUNNING; //Set the timer for 20 seconds and run it timer.SetTimer(0, 0, RUNTIME_RUNNING); timer.StartTimer(); } //Change the state to STANDBY if we are RUNNING else if (state == STATE_RUNNING) { //Turn off the lamp digitalWrite(RELAY_LAMP_PIN, LOW); //Turn on the start button LED and turn off the stop button LED digitalWrite(LED_START_BUTTON_PIN, HIGH); digitalWrite(LED_STOP_BUTTON_PIN, LOW); //Set the state to STANDBY because the cycle has ended state = STATE_STANDBY; } } }