Smart Alarm Clock

Enter Your Electronics & Design Project for Your Chance to Win a $100 Shopping Cart!

Back to The Project14 homepage

Project14 Home
Monthly Themes
Monthly Theme Poll

 


The basic idea was to create self-adjusting clock which should work in CET time zone with support for daylight saving. As source of time I have used a GPS signal received from NEO-7M module which have serial port. As display I have used a nice 2.9 inch module with e-paper. All this modules are connected to Arduino Nano.

 

Below there is connection diagram of modules:
- GPS module uses serial for communication,
- e-Paper display uses 4-line SPI for communication.

 

Program was written in Arduino IDE. I have used following libraries:

- TinyGPS++ - for decoding of received GPS signal and parsing of time and date,

- U8g2lib - for driving e-paper display,

- Timezone - for managing time and date in given time zone and support of DST.

 

Here is diagram with flow of program:

1. First step is initialization of platform: software serial for receiving data from GPS module, e-paper display, initial value of date and time.

2. At second step we are receiving data from serial port. Received GPS signal is parsed.

3. If GPS data is valid we are updating date and time.

4. At this stage we are updating time on e-paper display.

Source code is also available in attachment.

/* 
   Self-adjusting clock for CET time zone with DST 
   by kk99 
   2018 
*/

#include <SoftwareSerial.h>
#include <TinyGPS++.h>
#include <SPI.h>
#include <U8g2lib.h>
#include <Timezone.h>
#include <Arduino.h>

// GPS handle
TinyGPSPlus gps;

// EDP handle
U8G2_IL3820_V2_296X128_1_4W_HW_SPI u8g2(U8G2_R0, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8);

// Central European Time
TimeChangeRule CEST = {"CEST", Last, Sun, Mar, 2, 120}; // Central European Summer Time
TimeChangeRule CET = {"CET ", Last, Sun, Oct, 3, 60};   // Central European Standard Time
Timezone CE(CEST, CET);
TimeChangeRule *tcr;

// Serial handle
SoftwareSerial softSerial(3, 2);

void setup() {
  // put your setup code here, to run once:
  u8g2.begin();
  softSerial.begin(9600);
  setTime(00, 00, 00, 01, 01, 1970);
}

void loop() {
  // put your main code here, to run repeatedly:
  readGPSData(1000);
  updateTime();
  displayTime();
  delay(59000);
}

static void readGPSData(unsigned long timeoutMs)
{
  unsigned long start = millis();
  do
  {
    while (softSerial.available())
      gps.encode(softSerial.read());
  } while (millis() - start < timeoutMs);
}

static void updateTime(void) {
  if (gps.time.isValid() && gps.date.isValid()) {
    setTime(gps.time.hour(), gps.time.minute(), gps.time.second(), gps.date.day(), gps.date.month(), gps.date.year());
  }
}

static void displayTime(void)
{
  const unsigned timeLength = 6;
  char timeValue[timeLength];
  time_t utc = now();
  time_t local = CE.toLocal(utc, &tcr);
  snprintf(timeValue, timeLength, "%02d:%02d", hour(local), minute(local));
  u8g2.firstPage();
  do {
    u8g2.setFont(u8g2_font_logisoso78_tn);
    u8g2.drawStr(26, 103, timeValue);
    } while (u8g2.nextPage());
}

 

Here is short video presentation: