Mirko Pavleski
Published © GPL3+

Arduino HPDL1414 Retro Clock with Set and Alarm Functions

Unusual Retro clock that shows the time on retro displays made by Hewlett-Packard at the turn of the last century.

BeginnerFull instructions provided2 hours138
Arduino HPDL1414 Retro Clock with Set and Alarm Functions

Things used in this project

Hardware components

Arduino Nano R3
Arduino Nano R3
×1
HPDL-1414 Led displays
×2
DS3231M - ±5ppm, I2C Real-Time Clock
Maxim Integrated DS3231M - ±5ppm, I2C Real-Time Clock
×1
Pushbutton Switch, Momentary
Pushbutton Switch, Momentary
×3
Buzzer
Buzzer
×1

Software apps and online services

Arduino IDE
Arduino IDE

Hand tools and fabrication machines

Soldering iron (generic)
Soldering iron (generic)
Solder Wire, Lead Free
Solder Wire, Lead Free

Story

Read more

Schematics

Schematic

..

Code

Code

C/C++
..
#include <HPDL1414.h>
#include <RTClib.h>
#include <Wire.h>

const byte dataPins[7] = {2, 3, 4, 5, 6, 7, 8};  // Segment data pins: D0 - D6
const byte addrPins[2] = {A1, A2};               // Segment address pins: A0, A1
const byte wrenPins[] = {A0, A3};                // Write Enable pins (left to right)

RTC_DS3231 rtc;
char msg[] = "         *** MICRO CLOCK - MIRCEMK ***        ";
char t[32];
HPDL1414 hpdl(dataPins, addrPins, wrenPins, sizeof(wrenPins));

// Button pins
const int buttonHourPin = 9;
const int buttonMinutePin = 10;
const int buttonSetPin = 11;

// Buzzer pin
const int buzzerPin = 12;  // Add a pin for the buzzer

// Variables for setting time and alarm manually
int hours = 0;
int minutes = 0;
int alarmHours = 0;
int alarmMinutes = 0;
bool setMode = false;      // Time setting mode flag
bool alarmMode = false;    // Alarm setting mode flag
bool alarmEnabled = false; // Alarm enabled flag
bool alarmActive = false;  // Alarm active (sounding) flag
bool alarmAcknowledged = false; // Alarm acknowledged (stopped) flag

// Buzzer timing
unsigned long previousMillis = 0;
const long beepInterval = 500;  // 500ms on, 500ms off
bool buzzerState = false;       // To track buzzer state (on/off)

void setup() {
  Serial.begin(9600);
  Wire.begin();
  hpdl.begin();
  hpdl.clear();

  // Set up buttons and buzzer
  pinMode(buttonHourPin, INPUT_PULLUP);
  pinMode(buttonMinutePin, INPUT_PULLUP);
  pinMode(buttonSetPin, INPUT_PULLUP);
  pinMode(buzzerPin, OUTPUT);
  digitalWrite(buzzerPin, LOW);  // Make sure the buzzer is off initially

  // Display scrolling message at startup
  for (byte i = 0; i < (sizeof(msg) / sizeof(char)); i++) {
    for (byte j = 0; j < 16; j++) {
      hpdl.setCursor(j);
      if (i + j < (sizeof(msg) / sizeof(char))) {
        hpdl.print(msg[i + j]);
      } else {
        hpdl.print(" ");
      }
    }
    delay(200);
  }

  rtc.begin();
  // Initialize time variables from the RTC
  DateTime now = rtc.now();
  hours = now.hour();
  minutes = now.minute();
}

void loop() {
  // Get the current time from the RTC
  DateTime now = rtc.now();

  // Check if the alarm is active (buzzer sounding)
  if (alarmActive) {
    unsigned long currentMillis = millis();
    
    // Toggle the buzzer every 500ms (buzzerState controls on/off)
    if (currentMillis - previousMillis >= beepInterval) {
      previousMillis = currentMillis;  // Save the last time the buzzer toggled
      buzzerState = !buzzerState;      // Toggle the buzzer state
      digitalWrite(buzzerPin, buzzerState ? HIGH : LOW);  // Turn the buzzer on or off
    }

    // Check if D11 is pressed to stop the alarm
    if (digitalRead(buttonSetPin) == LOW) {
      alarmActive = false;  // Stop the alarm
      alarmAcknowledged = true;  // Mark the alarm as acknowledged
      digitalWrite(buzzerPin, LOW);  // Turn off the buzzer
      delay(500);  // Debounce delay
      return;  // Return to normal loop operation
    }
  }

  // Check if we are in time or alarm setting mode
  if (setMode) {
    // Display the manually set time
    sprintf(t, "%02d-%02d", hours, minutes);
    hpdl.clear();
    hpdl.print(t);

    // Check if buttons to adjust hours or minutes are pressed
    if (digitalRead(buttonHourPin) == LOW) {
      hours = (hours + 1) % 24;  // Increment hours and roll over after 23
      delay(200);  // Debouncing
    }
    if (digitalRead(buttonMinutePin) == LOW) {
      minutes = (minutes + 1) % 60;  // Increment minutes and roll over after 59
      delay(200);  // Debouncing
    }
  } else if (alarmMode) {
    // Display the manually set alarm time
    sprintf(t, "A%02d-%02d", alarmHours, alarmMinutes);
    hpdl.clear();
    hpdl.print(t);

    // Check if buttons to adjust alarm hours or minutes are pressed
    if (digitalRead(buttonHourPin) == LOW) {
      alarmHours = (alarmHours + 1) % 24;  // Increment alarm hours and roll over after 23
      delay(200);  // Debouncing
    }
    if (digitalRead(buttonMinutePin) == LOW) {
      alarmMinutes = (alarmMinutes + 1) % 60;  // Increment alarm minutes and roll over after 59
      delay(200);  // Debouncing
    }
  } else {
    // Normal operation: Display the current time from the RTC
    sprintf(t, "%02d-%02d-%02d", now.hour(), now.minute(), now.second());
    hpdl.clear();
    hpdl.print(t);

    // Check if the current time matches the alarm time and alarm is not acknowledged
    if (alarmEnabled && !alarmAcknowledged && now.hour() == alarmHours && now.minute() == alarmMinutes && now.second() == 0) {
      alarmActive = true;  // Mark the alarm as active
      previousMillis = millis();  // Initialize the timer for buzzer beeping
    }

    // Reset the alarm acknowledgement flag if the minute has changed
    if (now.minute() != alarmMinutes) {
      alarmAcknowledged = false;  // Allow the alarm to trigger again when the time matches next
    }
  }

  // Check if the Set button (buttonSetPin) is pressed to toggle between modes
  if (digitalRead(buttonSetPin) == LOW && !alarmActive) {
    if (setMode) {
      // Exiting time set mode, update the RTC with the manually set time
      rtc.adjust(DateTime(2024, 1, 1, hours, minutes, 0));  // Arbitrary date
      setMode = false;
      alarmMode = true;  // Move to alarm setting mode
    } else if (alarmMode) {
      // Exiting alarm set mode, enable the alarm
      alarmEnabled = true;
      alarmMode = false; // Back to normal mode
    } else {
      // Enter time setting mode
      setMode = true;
    }
    delay(500);  // Debouncing delay
  }
}

Credits

Mirko Pavleski

Mirko Pavleski

147 projects • 1267 followers

Comments