Native NTP support & bug fixes

- Added native NTP sync support
- Fixed bug with WiFi AP not working due to busy lightsleep callback
- Removed year offsets and use TimeLib macros for consistency
pull/133/head v1.3.0
sqfmi 2021-12-29 02:06:38 -05:00
parent 1bfbc55f4a
commit 12915a48e6
7 changed files with 99 additions and 70 deletions

View File

@ -70,7 +70,7 @@ void Watchy7SEG::drawDate(){
}
display.println(currentTime.Day);
display.setCursor(5, 150);
display.println(currentTime.Year + YEAR_OFFSET);// offset from 1970, since year is stored in uint8_t
display.println(tmYearToCalendar(currentTime.Year));// offset from 1970, since year is stored in uint8_t
}
void Watchy7SEG::drawSteps(){
// reset step counter at midnight

View File

@ -1,6 +1,6 @@
{
"name": "Watchy",
"version": "1.2.12",
"version": "1.3.0",
"description": "Watchy - An Open Source E-Paper Watch by SQFMI",
"authors": [
{

View File

@ -1,5 +1,5 @@
name=Watchy
version=1.2.12
version=1.3.0
author=SQFMI
maintainer=SQFMI
sentence=Watchy - An Open Source E-Paper Watch by SQFMI

View File

@ -316,7 +316,7 @@ void Watchy::setTime(){
int8_t hour = currentTime.Hour;
int8_t day = currentTime.Day;
int8_t month = currentTime.Month;
int8_t year = currentTime.Year;
int8_t year = tmYearToY2k(currentTime.Year);
int8_t setIndex = SET_HOUR;
@ -452,7 +452,7 @@ void Watchy::setTime(){
tmElements_t tm;
tm.Month = month;
tm.Day = day;
tm.Year = year;
tm.Year = y2kYearToTm(year);
tm.Hour = hour;
tm.Minute = minute;
tm.Second = 0;
@ -556,8 +556,9 @@ void Watchy::drawWatchFace(){
weatherData Watchy::getWeatherData(){
if(weatherIntervalCounter >= WEATHER_UPDATE_INTERVAL){ //only update if WEATHER_UPDATE_INTERVAL has elapsed i.e. 30 minutes
if(connectWiFi()){//Use Weather API for live data if WiFi is connected
HTTPClient http;
if(connectWiFi()){
RTC.syncNtpTime(); //Sync NTP
HTTPClient http; //Use Weather API for live data if WiFi is connected
http.setConnectTimeout(3000);//3 second max timeout
String weatherQueryURL = String(OPENWEATHERMAP_URL) + String(CITY_NAME) + String(",") + String(COUNTRY_CODE) + String("&units=") + String(TEMP_UNIT) + String("&appid=") + String(OPENWEATHERMAP_APIKEY);
http.begin(weatherQueryURL.c_str());
@ -715,41 +716,43 @@ void Watchy::_bmaConfig(){
}
void Watchy::setupWifi(){
WiFiManager wifiManager;
wifiManager.resetSettings();
wifiManager.setTimeout(WIFI_AP_TIMEOUT);
wifiManager.setAPCallback(_configModeCallback);
display.setFullWindow();
display.fillScreen(GxEPD_BLACK);
display.setFont(&FreeMonoBold9pt7b);
display.setTextColor(GxEPD_WHITE);
if(!wifiManager.autoConnect(WIFI_AP_SSID)) {//WiFi setup failed
display.println("Setup failed &");
display.println("timed out!");
}else{
display.println("Connected to");
display.println(WiFi.SSID());
}
display.display(false); //full refresh
//turn off radios
WiFi.mode(WIFI_OFF);
btStop();
guiState = APP_STATE;
display.epd2.setBusyCallback(0); //temporarily disable lightsleep on busy
WiFiManager wifiManager;
wifiManager.resetSettings();
wifiManager.setTimeout(WIFI_AP_TIMEOUT);
wifiManager.setAPCallback(_configModeCallback);
display.setFullWindow();
display.fillScreen(GxEPD_BLACK);
display.setFont(&FreeMonoBold9pt7b);
display.setTextColor(GxEPD_WHITE);
if(!wifiManager.autoConnect(WIFI_AP_SSID)) {//WiFi setup failed
display.println("Setup failed &");
display.println("timed out!");
}else{
RTC.syncNtpTime(); //sync ntp
display.println("Connected to");
display.println(WiFi.SSID());
}
display.display(false); //full refresh
//turn off radios
WiFi.mode(WIFI_OFF);
btStop();
display.epd2.setBusyCallback(displayBusyCallback); //enable lightsleep on busy
guiState = APP_STATE;
}
void Watchy::_configModeCallback (WiFiManager *myWiFiManager) {
display.setFullWindow();
display.fillScreen(GxEPD_BLACK);
display.setFont(&FreeMonoBold9pt7b);
display.setTextColor(GxEPD_WHITE);
display.setCursor(0, 30);
display.println("Connect to");
display.print("SSID: ");
display.println(WIFI_AP_SSID);
display.print("IP: ");
display.println(WiFi.softAPIP());
display.display(false); //full refresh
display.setFullWindow();
display.fillScreen(GxEPD_BLACK);
display.setFont(&FreeMonoBold9pt7b);
display.setTextColor(GxEPD_WHITE);
display.setCursor(0, 30);
display.println("Connect to");
display.print("SSID: ");
display.println(WIFI_AP_SSID);
display.print("IP: ");
display.println(WiFi.softAPIP());
display.display(false); //full refresh
}
bool Watchy::connectWiFi(){

View File

@ -20,7 +20,7 @@ void WatchyRTC::init(){
}
}
void WatchyRTC::config(String datetime){
void WatchyRTC::config(String datetime){ //String datetime format is YYYY:MM:DD:HH:MM:SS
if(rtcType == DS3231){
_DSConfig(datetime);
}else{
@ -43,17 +43,11 @@ void WatchyRTC::clearAlarm(){
void WatchyRTC::read(tmElements_t &tm){
if(rtcType == DS3231){
rtc_ds.read(tm);
tm.Year = tm.Year - 30; //reset to offset from 2000
}else{
tm.Year = y2kYearToTm(rtc_pcf.getYear());
tm.Month = rtc_pcf.getMonth();
if(tm.Month == 0){ //PCF8563 POR sets month = 0 for some reason
tm.Month = 1;
tm.Year = 21;
}else{
tm.Year = rtc_pcf.getYear();
}
tm.Day = rtc_pcf.getDay();
tm.Wday = rtc_pcf.getWeekday() + 1;
tm.Wday = rtc_pcf.getWeekday() + 1; //TimeLib & DS3231 has Wday range of 1-7, but PCF8563 stores day of week in 0-6 range
tm.Hour = rtc_pcf.getHour();
tm.Minute = rtc_pcf.getMinute();
tm.Second = rtc_pcf.getSecond();
@ -62,11 +56,14 @@ void WatchyRTC::read(tmElements_t &tm){
void WatchyRTC::set(tmElements_t tm){
if(rtcType == DS3231){
tm.Year = tm.Year + 2000 - YEAR_OFFSET_DS;
time_t t = makeTime(tm);
rtc_ds.set(t);
}else{
rtc_pcf.setDate(tm.Day, _getDayOfWeek(tm.Day, tm.Month, tm.Year+YEAR_OFFSET_PCF), tm.Month, 0, tm.Year);
time_t t = makeTime(tm); //make and break to calculate tm.Wday
breakTime(t, tm);
//day, weekday, month, century(1=1900, 0=2000), year(0-99)
rtc_pcf.setDate(tm.Day, tm.Wday - 1, tm.Month, 0, tmYearToY2k(tm.Year)); //TimeLib & DS3231 has Wday range of 1-7, but PCF8563 stores day of week in 0-6 range
//hr, min, sec
rtc_pcf.setTime(tm.Hour, tm.Minute, tm.Second);
clearAlarm();
}
@ -80,10 +77,10 @@ uint8_t WatchyRTC::temperature(){
}
}
void WatchyRTC::_DSConfig(String datetime){
void WatchyRTC::_DSConfig(String datetime){ //String datetime is YYYY:MM:DD:HH:MM:SS
if(datetime != ""){
tmElements_t tm;
tm.Year = _getValue(datetime, ':', 0).toInt() - YEAR_OFFSET_DS;//offset from 1970, since year is stored in uint8_t
tm.Year = CalendarYrToTm(_getValue(datetime, ':', 0).toInt()); //YYYY - 1970
tm.Month = _getValue(datetime, ':', 1).toInt();
tm.Day = _getValue(datetime, ':', 2).toInt();
tm.Hour = _getValue(datetime, ':', 3).toInt();
@ -98,30 +95,54 @@ void WatchyRTC::_DSConfig(String datetime){
rtc_ds.alarmInterrupt(ALARM_2, true); //enable alarm interrupt
}
void WatchyRTC::_PCFConfig(String datetime){
void WatchyRTC::_PCFConfig(String datetime){ //String datetime is YYYY:MM:DD:HH:MM:SS
if(datetime != ""){
tmElements_t tm;
int Year = _getValue(datetime, ':', 0).toInt();
int Month = _getValue(datetime, ':', 1).toInt();
int Day = _getValue(datetime, ':', 2).toInt();
int Hour = _getValue(datetime, ':', 3).toInt();
int Minute = _getValue(datetime, ':', 4).toInt();
int Second = _getValue(datetime, ':', 5).toInt();
tm.Year = CalendarYrToTm(_getValue(datetime, ':', 0).toInt()); //YYYY - 1970
tm.Month = _getValue(datetime, ':', 1).toInt();
tm.Day = _getValue(datetime, ':', 2).toInt();
tm.Hour = _getValue(datetime, ':', 3).toInt();
tm.Minute = _getValue(datetime, ':', 4).toInt();
tm.Second = _getValue(datetime, ':', 5).toInt();
time_t t = makeTime(tm); //make and break to calculate tm.Wday
breakTime(t, tm);
//day, weekday, month, century(1=1900, 0=2000), year(0-99)
rtc_pcf.setDate(Day, _getDayOfWeek(Day, Month, Year), Month, 0, Year - YEAR_OFFSET_PCF);//offset from 2000
rtc_pcf.setDate(tm.Day, tm.Wday - 1, tm.Month, 0, tmYearToY2k(tm.Year)); //TimeLib & DS3231 has Wday range of 1-7, but PCF8563 stores day of week in 0-6 range
//hr, min, sec
rtc_pcf.setTime(Hour, Minute, Second);
rtc_pcf.setTime(tm.Hour, tm.Minute, tm.Second);
}
//on POR event, PCF8563 sets month to 0, which will give an error since months are 1-12
clearAlarm();
}
int WatchyRTC::_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;
void WatchyRTC::syncNtpTime(){ //NTP sync - call after connecting to WiFi and remember to turn it back off
configTime(GMT_OFFSET_SEC, DST_OFFSET_SEC, NTP_SERVER);
struct tm timeinfo;
if(!getLocalTime(&timeinfo)){
return; //NTP sync failed
}
/****************************************************
struct tm
{
int tm_sec; // Seconds [0,60].
int tm_min; // Minutes [0,59].
int tm_hour; // Hour [0,23].
int tm_mday; // Day of month [1,31].
int tm_mon; // Month of year [0,11].
int tm_year; // Years since 1900.
int tm_wday; // Day of week [0,6] (Sunday =0).
int tm_yday; // Day of year [0,365].
int tm_isdst; // Daylight Savings flag.
}
****************************************************/
tmElements_t tm;
tm.Year = CalendarYrToTm(timeinfo.tm_year + 1900);
tm.Month = timeinfo.tm_mon + 1; //tm.Month 1 - 12
tm.Day = timeinfo.tm_mday;
tm.Hour = timeinfo.tm_hour;
tm.Minute = timeinfo.tm_min;
tm.Second = timeinfo.tm_sec;
set(tm);
}
String WatchyRTC::_getValue(String data, char separator, int index)

View File

@ -3,6 +3,8 @@
#include <DS3232RTC.h>
#include <Rtc_Pcf8563.h>
#include "config.h"
#include "time.h"
#define DS3231 0
#define PCF8563 1
@ -19,10 +21,11 @@ class WatchyRTC {
public:
WatchyRTC();
void init();
void config(String datetime);
void config(String datetime); //String datetime format is YYYY:MM:DD:HH:MM:SS
void clearAlarm();
void read(tmElements_t &tm);
void set(tmElements_t tm);
void syncNtpTime();
uint8_t temperature();
private:
void _DSConfig(String datetime);

View File

@ -48,8 +48,10 @@
#define SET_YEAR 2
#define SET_MONTH 3
#define SET_DAY 4
#define YEAR_OFFSET 2000
#define HOUR_12_24 24
#define NTP_SERVER "pool.ntp.org"
#define GMT_OFFSET_SEC 3600 * -5 //New York is UTC -5
#define DST_OFFSET_SEC 3600
//BLE OTA
#define BLE_DEVICE_NAME "Watchy BLE OTA"
#define WATCHFACE_NAME "Watchy 7 Segment"