index : arduino-lamp-timer.git

ascending towards madness

#include <Arduino.h>

#include <CountUpDownTimer.h>



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

        }

    }

}