From 74d5ec6097561495ec429a98e080f2ef64cc2dea Mon Sep 17 00:00:00 2001 From: SQFMI Date: Sun, 21 Nov 2021 22:51:01 -0500 Subject: [PATCH] add support for pcf8563 RTC --- src/Watchy.cpp | 125 +++++++++++++++++++++++++++++-------------------- src/Watchy.h | 4 +- src/config.h | 4 +- 3 files changed, 80 insertions(+), 53 deletions(-) diff --git a/src/Watchy.cpp b/src/Watchy.cpp index 8f6eef4..39c0097 100644 --- a/src/Watchy.cpp +++ b/src/Watchy.cpp @@ -1,6 +1,6 @@ #include "Watchy.h" -DS3232RTC Watchy::RTC(false); +Rtc_Pcf8563 Watchy::RTC; GxEPD2_BW Watchy::display(GxEPD2_154_D67(CS, DC, RESET, BUSY)); RTC_DATA_ATTR int guiState; @@ -34,32 +34,23 @@ void Watchy::init(String datetime){ esp_sleep_wakeup_cause_t wakeup_reason; wakeup_reason = esp_sleep_get_wakeup_cause(); //get wake up reason Wire.begin(SDA, SCL); //init i2c + int nextAlarmMinute; switch (wakeup_reason) { - #ifdef ESP_RTC - case ESP_SLEEP_WAKEUP_TIMER: //ESP Internal RTC - if(guiState == WATCHFACE_STATE){ - RTC.read(currentTime); - currentTime.Minute++; - tmElements_t tm; - tm.Month = currentTime.Month; - tm.Day = currentTime.Day; - tm.Year = currentTime.Year; - tm.Hour = currentTime.Hour; - tm.Minute = currentTime.Minute; - tm.Second = 0; - time_t t = makeTime(tm); - RTC.set(t); - RTC.read(currentTime); - showWatchFace(true); //partial updates on tick - } - break; - #endif case ESP_SLEEP_WAKEUP_EXT0: //RTC Alarm - RTC.alarm(ALARM_2); //resets the alarm flag in the RTC + RTC.clearAlarm(); //resets the alarm flag in the RTC + nextAlarmMinute = RTC.getMinute(); + nextAlarmMinute = (nextAlarmMinute == 59) ? 0 : (nextAlarmMinute + 1); //set alarm to trigger 1 minute from now + RTC.setAlarm(nextAlarmMinute, 99, 99, 99); if(guiState == WATCHFACE_STATE){ - RTC.read(currentTime); + currentTime.Month = RTC.getMonth(); + currentTime.Day = RTC.getDay(); + currentTime.Year = RTC.getYear(); + currentTime.Hour = RTC.getHour(); + currentTime.Minute = RTC.getMinute(); + currentTime.Second = RTC.getSecond(); + currentTime.Wday = RTC.getWeekday() + 1; showWatchFace(true); //partial updates on tick } break; @@ -78,19 +69,13 @@ void Watchy::init(String datetime){ } void Watchy::deepSleep(){ - #ifndef ESP_RTC esp_sleep_enable_ext0_wakeup(RTC_PIN, 0); //enable deep sleep wake on RTC interrupt - #endif - #ifdef ESP_RTC - esp_sleep_enable_timer_wakeup(60000000); - #endif esp_sleep_enable_ext1_wakeup(BTN_PIN_MASK, ESP_EXT1_WAKEUP_ANY_HIGH); //enable deep sleep wake on button press esp_deep_sleep_start(); } void Watchy::_rtcConfig(String datetime){ if(datetime != NULL){ - const time_t FUDGE(30);//fudge factor to allow for upload time, etc. (seconds, YMMV) tmElements_t tm; tm.Year = getValue(datetime, ':', 0).toInt() - YEAR_OFFSET;//offset from 1970, since year is stored in uint8_t tm.Month = getValue(datetime, ':', 1).toInt(); @@ -99,20 +84,29 @@ void Watchy::_rtcConfig(String datetime){ tm.Minute = getValue(datetime, ':', 4).toInt(); tm.Second = getValue(datetime, ':', 5).toInt(); - time_t t = makeTime(tm) + FUDGE; - RTC.set(t); + RTC.initClock(); + //day, weekday, month, century(1=1900, 0=2000), year(0-99) + RTC.setDate(tm.Day, getDayOfWeek(tm.Day, tm.Month, tm.Year+YEAR_OFFSET), tm.Month, 0, tm.Year); + //hr, min, sec + RTC.setTime(tm.Hour, tm.Minute, tm.Second); } - //https://github.com/JChristensen/DS3232RTC - RTC.squareWave(SQWAVE_NONE); //disable square wave output - //RTC.set(compileTime()); //set RTC time to compile time - RTC.setAlarm(ALM2_EVERY_MINUTE, 0, 0, 0, 0); //alarm wakes up Watchy every minute - RTC.alarmInterrupt(ALARM_2, true); //enable alarm interrupt - RTC.read(currentTime); + RTC.clearAlarm(); + int nextAlarmMinute = RTC.getMinute(); + nextAlarmMinute = (nextAlarmMinute == 59) ? 0 : (nextAlarmMinute + 1); + RTC.setAlarm(nextAlarmMinute, 99, 99, 99); + currentTime.Month = RTC.getMonth(); + currentTime.Day = RTC.getDay(); + currentTime.Year = RTC.getYear(); + currentTime.Hour = RTC.getHour(); + currentTime.Minute = RTC.getMinute(); + currentTime.Second = RTC.getSecond(); + currentTime.Wday = RTC.getWeekday() + 1; } void Watchy::handleButtonPress(){ uint64_t wakeupBit = esp_sleep_get_ext1_wakeup_status(); + int nextAlarmMinute; //Menu Button if (wakeupBit & MENU_BTN_MASK){ if(guiState == WATCHFACE_STATE){//enter menu state if coming from watch face @@ -148,13 +142,22 @@ void Watchy::handleButtonPress(){ //Back Button else if (wakeupBit & BACK_BTN_MASK){ if(guiState == MAIN_MENU_STATE){//exit to watch face if already in menu - RTC.alarm(ALARM_2); //resets the alarm flag in the RTC - RTC.read(currentTime); - showWatchFace(false); + RTC.clearAlarm(); + nextAlarmMinute = RTC.getMinute(); + nextAlarmMinute = (nextAlarmMinute == 59) ? 0 : (nextAlarmMinute + 1); + RTC.setAlarm(nextAlarmMinute, 99, 99, 99); + currentTime.Month = RTC.getMonth(); + currentTime.Day = RTC.getDay(); + currentTime.Year = RTC.getYear(); + currentTime.Hour = RTC.getHour(); + currentTime.Minute = RTC.getMinute(); + currentTime.Second = RTC.getSecond(); + currentTime.Wday = RTC.getWeekday() + 1; + showWatchFace(false); }else if(guiState == APP_STATE){ - showMenu(menuIndex, false);//exit to menu if already in app + showMenu(menuIndex, false);//exit to menu if already in app }else if(guiState == FW_UPDATE_STATE){ - showMenu(menuIndex, false);//exit to menu if already in app + showMenu(menuIndex, false);//exit to menu if already in app } } //Up Button @@ -221,8 +224,17 @@ void Watchy::handleButtonPress(){ }else if(digitalRead(BACK_BTN_PIN) == 1){ lastTimeout = millis(); if(guiState == MAIN_MENU_STATE){//exit to watch face if already in menu - RTC.alarm(ALARM_2); //resets the alarm flag in the RTC - RTC.read(currentTime); + RTC.clearAlarm(); + nextAlarmMinute = RTC.getMinute(); + nextAlarmMinute = (nextAlarmMinute == 59) ? 0 : (nextAlarmMinute + 1); + RTC.setAlarm(nextAlarmMinute, 99, 99, 99); + currentTime.Month = RTC.getMonth(); + currentTime.Day = RTC.getDay(); + currentTime.Year = RTC.getYear(); + currentTime.Hour = RTC.getHour(); + currentTime.Minute = RTC.getMinute(); + currentTime.Second = RTC.getSecond(); + currentTime.Wday = RTC.getWeekday() + 1; showWatchFace(false); break; //leave loop }else if(guiState == APP_STATE){ @@ -360,7 +372,12 @@ void Watchy::setTime(){ guiState = APP_STATE; - RTC.read(currentTime); + currentTime.Month = RTC.getMonth(); + currentTime.Day = RTC.getDay(); + currentTime.Year = RTC.getYear(); + currentTime.Hour = RTC.getHour(); + currentTime.Minute = RTC.getMinute(); + currentTime.Second = RTC.getSecond(); int8_t minute = currentTime.Minute; int8_t hour = currentTime.Hour; @@ -502,17 +519,16 @@ void Watchy::setTime(){ display.hibernate(); - const time_t FUDGE(10);//fudge factor to allow for upload time, etc. (seconds, YMMV) tmElements_t tm; tm.Month = month; tm.Day = day; - tm.Year = year + 2000 - YEAR_OFFSET;//offset from 1970, since year is stored in uint8_t + tm.Year = year;//offset from 1970, since year is stored in uint8_t tm.Hour = hour; tm.Minute = minute; tm.Second = 0; - time_t t = makeTime(tm) + FUDGE; - RTC.set(t); + RTC.setDate(tm.Day, getDayOfWeek(tm.Day, tm.Month, tm.Year+YEAR_OFFSET), tm.Month, 0, tm.Year); + RTC.setTime(tm.Hour, tm.Minute, tm.Second); showMenu(menuIndex, false); @@ -632,8 +648,8 @@ weatherData Watchy::getWeatherData(){ //turn off radios WiFi.mode(WIFI_OFF); btStop(); - }else{//No WiFi, use RTC Temperature - uint8_t temperature = RTC.temperature() / 4; //celsius + }else{//No WiFi, No RTC Temperature, default to 25C + uint8_t temperature = 25; //celsius if(strcmp(TEMP_UNIT, "imperial") == 0){ temperature = temperature * 9. / 5. + 32.; //fahrenheit } @@ -944,6 +960,15 @@ void Watchy::updateFWBegin(){ showMenu(menuIndex, false); } +int Watchy::getDayOfWeek(int d, int m, int y) +{ + static int t[] = { 0, 3, 2, 5, 0, 3, + 5, 1, 4, 6, 2, 4 }; + y -= m < 3; + return ( y + y / 4 - y / 100 + + y / 400 + t[m - 1] + d) % 7; +} + // time_t compileTime() // { // const time_t FUDGE(10); //fudge factor to allow for upload time, etc. (seconds, YMMV) diff --git a/src/Watchy.h b/src/Watchy.h index 887d58e..3d2f46c 100644 --- a/src/Watchy.h +++ b/src/Watchy.h @@ -6,6 +6,7 @@ #include #include #include +#include #include #include #include @@ -21,7 +22,7 @@ typedef struct weatherData{ class Watchy { public: - static DS3232RTC RTC; + static Rtc_Pcf8563 RTC; static GxEPD2_BW display; tmElements_t currentTime; public: @@ -43,6 +44,7 @@ class Watchy { bool connectWiFi(); weatherData getWeatherData(); void updateFWBegin(); + int getDayOfWeek(int d, int m, int y); void showWatchFace(bool partialRefresh); virtual void drawWatchFace(); //override this method for different watch faces diff --git a/src/config.h b/src/config.h index 757c90e..d180d06 100644 --- a/src/config.h +++ b/src/config.h @@ -4,7 +4,7 @@ //pins #define SDA 21 #define SCL 22 -#define ADC_PIN 33 +#define ADC_PIN 35 #define RTC_PIN GPIO_NUM_27 #define CS 5 #define DC 10 @@ -47,7 +47,7 @@ #define SET_YEAR 2 #define SET_MONTH 3 #define SET_DAY 4 -#define YEAR_OFFSET 1970 +#define YEAR_OFFSET 2000 #define HOUR_12_24 24 //BLE OTA #define BLE_DEVICE_NAME "Watchy BLE OTA"