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:
Top Comments