#include <RTClib.h>
#include <Timezone.h> // https://github.com/JChristensen/Timezone
#include <Adafruit_GFX.h>
#include <Adafruit_NeoMatrix.h>
#include <Adafruit_NeoPixel.h>
RTC_DS1307 RTC; //Establish clock object RTC
// define pins
#define NEOPIN 6 // connect to DIN on NeoMatrix 8x8 via a resistor
DateTime currUTC_Time; //current clock time in DateTime format UTC
time_t AusEasternTime; //Australian Eastern Time in time_t format = UTC + 10 or 11
char daysOfTheWeek[7][12] = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"};
//**** flags - CHANGE THESE BEFORE COMPILING *********
int updateTime = 0; // Set to 1 to reset RTC's time (from PC), compile/upload, then set to 0 and compile/upload again.
int TimeZoneAdj = 10; //local time is UTC+10 or UTC+11 in daylight savings mode. This is the Std Time Adj
int secAdjToCompileTime = 30; //fudge factor to allow for slight delay between compiling and updating RTC
int m = 1; //Display Minutes LEDs 0=OFF, 1=ON
int oc = 1; //Display o'clock LEDs on the hour. 0=OFF, 1=ON
int mc = 1; //Display a different color on 'it is' for each minute between clock change (learn the colors and you can tell the time to the minute). 0=OFF, 1=ON
int ampm = 1; //Display AM & PM in a different color. 0=OFF, 1=ON
//********* Daylight savings in Australia East coast *************
/* clocks go back an hour at 2am (hence UTC+10) on the 1st Sunday and
go forward an hour at 3am (to UTC+11) on the first Sunday in April
2022 Sunday, 3 April, 3:00 am Sunday, 2 October, 2:00 am
2023 Sunday, 2 April, 3:00 am Sunday, 1 October, 2:00 am
2024 Sunday, 7 April, 3:00 am Sunday, 6 October, 2:00 am etc
*/
//We create a rule for this using the Timezone library for Australia Eastern Time Zone (Sydney, Melbourne)
// Define a TimeChangeRule as follows:
// TimeChangeRule myRule = {abbrev, week, dow, month, hour, offset in seconds};
TimeChangeRule aEDT = {"AEDT", First, Sun, Oct, 2, 660}; // Australian Eastern Daylight time = UTC + 11 hours (time when daylight savings is on between Oct and Mar)
TimeChangeRule aEST = {"AEST", First, Sun, Apr, 3, 600}; // Australian Eastern Standard time = UTC + 10 hours (time when daylight savings is off between Apr and Sep)
Timezone ausET(aEDT, aEST); //create a Timezone object ausET
int ledCount = 64; // the 8x8 grid of the Neomatrix
// configure for 8x8 neopixel matrix
Adafruit_NeoMatrix matrix = Adafruit_NeoMatrix(8, 8, NEOPIN,
NEO_MATRIX_TOP + NEO_MATRIX_LEFT +
NEO_MATRIX_COLUMNS + NEO_MATRIX_PROGRESSIVE,
NEO_GRB + NEO_KHZ800);
void setup() {
Serial.begin(9600);
Serial.println("===Setup started===");
currUTC_Time = DateTime(__DATE__, __TIME__); //UTC compile time
Serial.print("Compile Date in UTC format. ");
SerialPrintDateTime(currUTC_Time);
Serial.println("Starting RTC clock");
RTC.begin(); // begin clock
if (! RTC.isrunning()) updateTime = 1;
if (! RTC.begin()) updateTime = 1;
Serial.print("RTC needs to update? ");
Serial.println(updateTime);
if (updateTime == 1) {
Serial.println("Setting RTC from PC ...");
//RTC_SetTime(0, 0, currUTC_Time); //Save UTC Time
RTC_SetTime(TimeZoneAdj, secAdjToCompileTime, currUTC_Time); //Save UTC+10 Time
}
delay(1000);
//set LED pinmodes
pinMode(NEOPIN, OUTPUT);
matrix.begin();
testMatrix();
Serial.println("===Setup finished===");
//Test the word clock code...
/*
for (int h=0; h<8; h++)
for (int m=0; m<=59; m++){
Serial.print(" Hour ");
Serial.print(h*3);
Serial.print(" : ");
Serial.print(" Minute ");
Serial.print(m);
Serial.print(" : ");
GetWordTime(DateTime(2022, 1, 15, h*3, m, 0));
}
Serial.println("===Test finished===");
*/
}
void loop() {
DateTime currTime = RTC_GetTime();
Serial.print("Australian Time: ");
SerialPrintDateTime(currTime);
Serial.println();
delay(5000);
}
void SerialPrintDateTime(DateTime now){
Serial.print("Time: ");
Serial.print(now.year(), DEC);
Serial.print('/');
Serial.print(now.month(), DEC);
Serial.print('/');
Serial.print(now.day(), DEC);
Serial.print(" (");
Serial.print(daysOfTheWeek[now.dayOfTheWeek()]);
Serial.print(") ");
Serial.print(now.hour(), DEC);
Serial.print(':');
Serial.print(now.minute(), DEC);
Serial.print(':');
Serial.print(now.second(), DEC);
Serial.println();
}
//Function that receives ymd hms and returns a time_t variable
time_t tmConvert_t(int YYYY, byte MM, byte DD, byte hh, byte mm, byte ss){
tmElements_t tmSet;
tmSet.Year = YYYY - 1970;
tmSet.Month = MM;
tmSet.Day = DD;
tmSet.Hour = hh;
tmSet.Minute = mm;
tmSet.Second = ss;
return makeTime(tmSet);
}
//function that receives a DateTime variable and converts it to a time_t variable
time_t DateTime2Time(DateTime now){
return tmConvert_t( now.year(), now.month(), now.day(), now.hour(), now.minute(), now.second() );
}
//set the RTC with to UTC time
void RTC_SetTime(int DST_HH_Adj, int secAdj, DateTime TimeUsed){
//could use:
// RTC.adjust(DateTime(__DATE__, __TIME__)); <-- this is similar to what we use but with a seconds adj
// or RTC.adjust(DateTime(2017, 7, 16, 16, 35, 20));
int YYYY =TimeUsed.year() ;
byte MM = TimeUsed.month();
byte DD = TimeUsed.day();
byte hh = TimeUsed.hour();
byte mm = TimeUsed.minute();
byte ss = TimeUsed.second();
RTC.adjust(DateTime(YYYY, MM, DD, hh + DST_HH_Adj, mm, ss+secAdj));
}
DateTime RTC_GetTime(){
int DST_HH_Adj = 0;
currUTC_Time = RTC.now(); //read time on the RTC which should be in UTC+10 format
Serial.println("Getting UTC time");
SerialPrintDateTime(currUTC_Time);
AusEasternTime = DateTime2Time(currUTC_Time); //convert from DateTime format to time_t format
if (ausET.locIsDST(AusEasternTime)) DST_HH_Adj = 1;
int YYYY =currUTC_Time.year() ;
byte MM = currUTC_Time.month();
byte DD = currUTC_Time.day();
byte hh = currUTC_Time.hour();
byte mm = currUTC_Time.minute();
byte ss = currUTC_Time.second();
hh+=DST_HH_Adj;
return DateTime(YYYY, MM, DD, hh, mm, ss);
}