Project 05 - Digital Clock - 7 Segment Style Display

<< Click to Display Table of Contents >>

Navigation:  Projects >

Project 05 - Digital Clock - 7 Segment Style Display

This project demonstrates drawing a digital clock using the seven segment font. It uses the PCF8523T CleO library to interact with the PCF8523T RTC component to read the time and update the clock.

 

 

Component(s)

 

This project uses the following component(s) -

 

PCF8523T RTC

56mm, 80hm 0.5W(RMS) / 1W(Peak) Internal CleO speaker

 

 

Wiring Diagram

 

 

Project 05-Digital Clock-7SegmentStyle

 

 

Code

 

The following code shows how the setup() routine checks for the Oscillator Stop Flag (OSF) in PCF8523T RTC component. Based on the OSF flag, it shows the SetDateTime() widget or continues with the current date and time value from the RTC hardware. It then loads the seven segment font along with the play and setting icons. If the RTC is not present, then it uses the software timer to display the selected date and time.

 

The 1-wire library is first initialized to interact with the PCF8523T RTC component. Later the SetDateTime() widget is invoked which prompts the users to select the date and time. This information is stored in the epoch time. The Epoch time is converted to year, month, day of month, hour, minute, second and day of week using the EpochToDate() routine.

 

void setup() {

Serial.begin(115200);

 

 #ifdef _VARIANT_ARDUINO_DUE_X_

   Wire1.begin(); // Shield I2C pins connect to alt I2C bus on Arduino Due

 #else

   Wire.begin();

 #endif

 

if (rtc.begin() == -1) // RTC is not detected

 software_timer = true;

 

 /* Initialize CleO */

 CleO.begin();

 

 int16_t s, m, h, dayOfWeek, dayOfMonth, mon, y;

 if (software_timer == true) {

   CleO.SetDateTime("Date/Time", t0);

   CleO.EpochToDate(t0, y, mon, dayOfMonth, h, m, s, dayOfWeek);

   }

else if (!rtc.isrunning() || rtc.checkOSF() == 1) {

   CleO.SetDateTime("Date/Time", t0);

   CleO.EpochToDate(t0, y, mon, dayOfMonth, h, m, s, dayOfWeek);

   rtc.set_time(y, mon + 1, dayOfMonth, h, m, s, dayOfWeek);

 }

 else { /* RTC is running fine */

   rtc.get_time(y, mon, dayOfMonth, h, m, s, dayOfWeek);

   CleO.DateToEpoch(t0, y, mon - 1, dayOfMonth, h, m, s);

 }

 

 startTime = millis();

 

/* Start drawing the screen shot */

 CleO.Start();

 

  /* Show the screenshot */

 CleO.Show();

 

 CleO.DisplayRotate(2, 0);

 

 font = CleO.LoadFont("@Fonts/DSEG7ClassicMini-BoldItalic.ftfont");

 icon_play[0] = CleO.LoadIcon("@Icons/m48.ftico", ICON_PLAY_CIRCLE_OUTLINE);

 icon_play[1] = CleO.LoadIcon("@Icons/m48.ftico", ICON_PLAY_CIRCLE_FILLED);

 icon_setting = CleO.LoadIcon("@Icons/m48.ftico", ICON_SETTINGS);

}

 

The loop routine() checks for the touch events and then updates the seven segment display based on date and time values.

 

void loop() {

 touchControl();

 updateTimer();

}

 

The updateTimer() routine checks if the software timer should be used or not. Once the updated values of hour and seconds are received, it displays the seven segment fonts and icons.

 

void updateTimer() {

 uint32_t color = 0xff4040UL; // bright red

 int16_t s, m, h, dayOfWeek, dayOfMonth, mon, y;

 char buf[12];

 

 if (software_timer == false) {

rtc.get_time(y, mon, dayOfMonth, h, m, s, dayOfWeek);

 else {

   elapsedTime = (millis() - startTime) / 1000L;

   CleO.EpochToDate(t0 + elapsedTime, y, mon, dayOfMonth, h, m, s, dayOfWeek);

   mon += 1; /* CleO.EpochToDate() gives January month as 0 */

   dayOfWeek += 1; /* CleO.EpochToDate() gives Sunday as 0 */

 }

 

 /* update speaking time */

 speak_hour = h, speak_min = m;

 

 /* Start drawing the screen shot */

 CleO.Start();

 

 /* Draw hour, minute and second */

 sprintf(buf, "%02d   %02d   %02d", h, m, s);

 CleO.StringExt(font, 240, 0, color, TM, 0, 0, buf);

 

/* Draw month and day of month */

 sprintf(buf, "%02d   %02d", dayOfMonth, mon);

 CleO.StringExt(font, 240, 160, color, MM, 0, 0, buf);

 

/* Draw year */

 sprintf(buf, "%d", y);

 CleO.StringExt(font, 240, 244, color, TM, 0, 0, buf);

 

/* Draw play icon */

 CleO.Tag(100);

 CleO.Bitmap(icon_play[playing], 20, 250);

 

 /* Draw setting icon */

 CleO.Tag(101);

 CleO.Bitmap(icon_setting, 410, 250);

 

 /* Show the clock */

 CleO.Show();

}

 

The touchControl() routine checks for the play or setting button press events.

 

This project has the capabilities of presenting the time as sound. The sound plays the current time displayed on the screen. On pressing the play icon, it plays the WAV files stored on the device based on the hour and minutes value. For various values of hour and minute, the AudioPlay() command is used to play the relevant WAV files. The following code snippet shows how to play different sounds on touch -

 

/* updateTimer() routine is called to update UI while speaking time */

void processTags(int16_t tag) {

 char buf[40];

 if (tag == 100) {

   CleO.AudioPlay("@Music/Sounds/TheTimeIsNow.wav", PLAY_WAIT);

   updateTimer();

 

   if (speak_hour > 12)

     speak_hour -= 12;

 

   if (speak_hour == 0 || speak_hour == 12)

     CleO.AudioPlay("@Music/Sounds/12.wav", PLAY_WAIT);

   else {

     sprintf(buf, "@Music/Sounds/%d.wav", speak_hour);

     CleO.AudioPlay(buf, PLAY_WAIT);

   }

 

   updateTimer();

   CleO.AudioPlay("@Music/Sounds/oClock.wav", PLAY_WAIT);

   updateTimer();

 

   if (speak_min > 0) {

     if (speak_min < 21 || speak_min == 30 || speak_min == 40 || speak_min == 50) {

       sprintf(buf, "@Music/Sounds/%d.wav", speak_min);

       CleO.AudioPlay(buf, PLAY_WAIT);

       updateTimer();

     } else {

       if (speak_min < 30)

         CleO.AudioPlay("@Music/Sounds/20.wav", PLAY_WAIT);

       else if (speak_min < 40)

         CleO.AudioPlay("@Music/Sounds/30.wav", PLAY_WAIT);

       else if (speak_min < 50)

         CleO.AudioPlay("@Music/Sounds/40.wav", PLAY_WAIT);

       else

         CleO.AudioPlay("@Music/Sounds/50.wav", PLAY_WAIT);

 

       updateTimer();

       sprintf(buf, "@Music/Sounds/%d.wav", speak_min % 10);

       CleO.AudioPlay(buf, PLAY_WAIT);

       updateTimer();

     }

 

     CleO.AudioPlay("@Music/Sounds/minutes.wav", PLAY_WAIT);

     updateTimer();

   }

 } else if (tag == 101) { /* setting button is pressed */

   CleO.Start();

   CleO.Show();  

 

/* Set screen coordinate in portrait mode */

   CleO.DisplayRotate(1, 0);

   int16_t s = 0, m = 0, h = 0, dayOfWeek = 0, dayOfMonth = 0, mon = 0, y = 0;

   elapsedTime = (millis() - startTime) / 1000L;

   uint32_t t1 = t0 + elapsedTime;

   int16_t ret = CleO.SetDateTime("Date/Time", t1);

   CleO.Start();

   CleO.Show();  

 

/* Set screen coordinate in landscape mode */

   CleO.DisplayRotate(2, 0);

 

   if (0 == ret) {

     CleO.EpochToDate(t1, y, mon, dayOfMonth, h, m, s, dayOfWeek);

     rtc.set_time(y, mon + 1, dayOfMonth, h, m, s, dayOfWeek);

     startTime = millis();

     t0 = t1;

   }

 }

}

 

 

Output

 

 

Project05-DigitalClock-7SegmentDisplay