Programmable Arduino Timer

Project to making a programmable timer with an Arduino Uno, a 7-segment 8-digit MAX7219 display, and a 4×4 keypad.

Project description

In this project I built a timer that can be used in various applications with the advantage of being programmable with a 4×4 membrane keyboard for programming hours, minutes, seconds and milliseconds.

The time programming is done via the ‘A’ key, after entering the time in HH:MM:SS:MS, just press the ‘D’ key to start the countdown, A beep sounds at each decrement of each second. When the timer come to 0, the LEDs lights and a continuous beep sounds.

The wiring is not very complicated, the connection of the display is 5 wires, for my project it is assigned to pins 12, 11, 10 (DIN, CLK, CS), and 5V and GND outputs of the Arduino UNO for the power of the display.

The 4×4 membrane keypad was assigned to pins 5, 4, 3, 2 for horizontal and 9, 8, 7, 6 for columns.

The buzzer has pin 18 and GND, and leds on pin 13 and GND.

A battery was added and connected to the VIN power supply of the Arduino with a 2-position switch for power-up.

I modified the original display, and I used larger displays 2 digits 7 segments separated by leds to give a more interesting look to my timer. There was a long work of wiring on the prototype board.

Code

Countdown timer for MAX7219

Complete code for programmable timer MAX7219.

#include <Keypad.h>
#include <LedControl.h>
#include <SPI.h>

const byte ROWS = 4; 
const byte COLS = 4; 
char keys[ROWS][COLS] = {
  {'1', '2', '3', 'A'},
  {'4', '5', '6', 'B'},
  {'7', '8', '9', 'C'},
  {'*', '0', '#', 'D'}
};
byte rowPins[ROWS] = {5, 4, 3, 2}; 
byte colPins[COLS] = {9, 8, 7, 6}; 

Keypad keypadObj = Keypad(makeKeymap(keys), rowPins, colPins, ROWS, COLS);
LedControl lc = LedControl(12, 11, 10, 1);

long csecondsLeft;
int decrement = 3;
bool explosed = false;

long hours = 0;
long minutes = 0;
long seconds = 0;
long hundredths = 0;

char keypadOutput[32] = {0};
byte playSound = 18;

void setup() {
  csecondsLeft = 0;
  Serial.begin(9600);
  lc.shutdown(0, false);
  lc.setIntensity(0, 8);
  lc.clearDisplay(0);
  pinMode(13, OUTPUT);
  pinMode(18, OUTPUT);
  analogWrite(18, 0);
}

bool isProgrammingTime = false;
String inputKeys = ""; 
String programmedTime = ""; 
bool isCountingDown = false; 

void updateDisplay() {

  long remainingSeconds = csecondsLeft / 100;

  hours = remainingSeconds / 3600;
  remainingSeconds %= 3600;
  minutes = remainingSeconds / 60;
  seconds = remainingSeconds % 60;
  hundredths = csecondsLeft % 100;

  lc.setDigit(0, 7, hours / 10, false);
  lc.setDigit(0, 6, hours % 10, false);
  lc.setDigit(0, 5, minutes / 10, false); 
  lc.setDigit(0, 4, minutes % 10, false);
  lc.setDigit(0, 3, seconds / 10, false);
  lc.setDigit(0, 2, seconds % 10, false);
  lc.setDigit(0, 1, hundredths / 10, false);
  lc.setDigit(0, 0, hundredths % 10, false);
}

void programTime() {

  if (inputKeys.length() >= 8) {

    inputKeys = inputKeys.substring(0, 8);

    programmedTime = inputKeys.substring(0, 2) + ":" + inputKeys.substring(2, 4) + ":" + inputKeys.substring(4, 6) + ":" + inputKeys.substring(6, 8);

    Serial.print("inputKeys: "); Serial.println(inputKeys);
    Serial.print("programmedTime: "); Serial.println(programmedTime);

    lc.clearDisplay(0);

    inputKeys = "";
  }
}

void startCountdown() {

  Serial.println("Starting countdown...");

  if (programmedTime.length() == 11) { 
    hours = programmedTime.substring(0, 2).toInt();
    minutes = programmedTime.substring(3, 5).toInt();
    seconds = programmedTime.substring(6, 8).toInt();
    hundredths = programmedTime.substring(9, 11).toInt();

    csecondsLeft = ((hours * 3600) + (minutes * 60) + seconds) * 100 + hundredths;
  } else {
    Serial.println("Invalid programmed time. Please enter a time greater than zero.");
    return;
  }
 
  updateDisplay();
  isCountingDown = true; 
}


void loop() {
  char key = keypadObj.getKey();

  if (key) {
    Serial.print("Key Pressed: ");
    Serial.println(key);

    if (key >= '0' && key <= '9') {
      int num = key - '0';
      int displayIndex = 7 - inputKeys.length();
      lc.setDigit(0, displayIndex, num, false);
      inputKeys += key;
      tone(playSound, 1000, 50);
    }

    if (!isProgrammingTime && key == 'A') { 

      Serial.println("Programming time...");
      isProgrammingTime = true;
      inputKeys = ""; 
      programmedTime = ""; 
      lc.clearDisplay(0); 

    } else if (isProgrammingTime && key == 'D') { 

  isProgrammingTime = false;
  programTime();
  Serial.print("Programmed Time: ");
  Serial.println(programmedTime);
  startCountdown();
  programmedTime = ""; 
}
  }

  else if (isCountingDown) {

      delay(30); 
      csecondsLeft -= decrement;

      if (csecondsLeft < 0) {
        csecondsLeft = 0;
        if (!explosed) {
          tone(playSound, 1000, 50);
          digitalWrite(13, HIGH);
        }
        explosed = true;
      }
      updateDisplay(); 
      if (csecondsLeft % 35 == 0) {
        tone(playSound, 3236, 50);
      }
    
  }
}

Similar Posts

Leave a Reply