mirror of https://github.com/sqfmi/Watchy.git
Great build. have multiple faces!
parent
85bd057625
commit
94c962247e
|
@ -1,20 +0,0 @@
|
|||
// Self
|
||||
#include "DateTimeWatchFace.h"
|
||||
|
||||
// Fonts
|
||||
#include <Fonts/FreeMonoBold9pt7b.h>
|
||||
|
||||
void CDateTimeWatchFace::Draw(CWatchyExpanded::ADisplay& display, const tmElements_t& time)
|
||||
{
|
||||
CTimeWatchFace::Draw(display, time);
|
||||
|
||||
m_currentLocalTime.tm_wday = time.Wday - 1;
|
||||
m_currentLocalTime.tm_year = time.Year + 1970 - 1900;
|
||||
m_currentLocalTime.tm_mon = time.Month - 1;
|
||||
m_currentLocalTime.tm_mday = time.Day;
|
||||
|
||||
char buffer[32];
|
||||
strftime(buffer, sizeof(buffer), "%a %b %d, %Y", &m_currentLocalTime);
|
||||
display.print(buffer);
|
||||
display.println();
|
||||
};
|
|
@ -1,17 +0,0 @@
|
|||
#pragma once
|
||||
|
||||
// Time
|
||||
#include <TimeLib.h>
|
||||
|
||||
// Expanded
|
||||
#include "WatchFace.h"
|
||||
#include "WatchyExpanded.h"
|
||||
|
||||
// Faces
|
||||
#include "TimeWatchFace.h"
|
||||
|
||||
class CDateTimeWatchFace : public CTimeWatchFace
|
||||
{
|
||||
public:
|
||||
void Draw(CWatchyExpanded::ADisplay& display, const tmElements_t& time) override;
|
||||
};
|
|
@ -0,0 +1,39 @@
|
|||
// Self
|
||||
#include "DateWatchFace.h"
|
||||
|
||||
// Fonts
|
||||
#include <Fonts/FreeMonoBold9pt7b.h>
|
||||
|
||||
// Time
|
||||
#include <TimeLib.h>
|
||||
|
||||
void CDateWatchFace::Draw(CWatchyExpanded& expanded)
|
||||
{
|
||||
StartDraw(expanded.Display());
|
||||
CTimeWatchFace::DrawInternal(expanded);
|
||||
DrawInternal(expanded);
|
||||
};
|
||||
|
||||
void CDateWatchFace::StartDraw(CWatchyExpanded::ADisplay& display)
|
||||
{
|
||||
display.setFullWindow();
|
||||
display.fillScreen(GxEPD_BLACK);
|
||||
display.setFont(&FreeMonoBold9pt7b);
|
||||
display.setCursor(0, 15);
|
||||
};
|
||||
|
||||
void CDateWatchFace::DrawInternal(CWatchyExpanded& expanded)
|
||||
{
|
||||
CWatchyExpanded::ADisplay& display = expanded.Display();
|
||||
tmElements_t& time = expanded.Time();
|
||||
|
||||
m_currentLocalTime.tm_wday = time.Wday - 1;
|
||||
m_currentLocalTime.tm_year = time.Year + 1970 - 1900;
|
||||
m_currentLocalTime.tm_mon = time.Month - 1;
|
||||
m_currentLocalTime.tm_mday = time.Day;
|
||||
|
||||
char buffer[32];
|
||||
strftime(buffer, sizeof(buffer), "%a %b %d, %Y", &m_currentLocalTime);
|
||||
display.print(buffer);
|
||||
display.println();
|
||||
};
|
|
@ -0,0 +1,17 @@
|
|||
#pragma once
|
||||
|
||||
// Expanded
|
||||
#include "WatchFace.h"
|
||||
#include "WatchyExpanded.h"
|
||||
|
||||
// Faces
|
||||
#include "TimeWatchFace.h"
|
||||
|
||||
class CDateWatchFace : public CTimeWatchFace
|
||||
{
|
||||
public:
|
||||
void Draw(CWatchyExpanded& expanded) override;
|
||||
|
||||
void StartDraw(CWatchyExpanded::ADisplay& display);
|
||||
void DrawInternal(CWatchyExpanded& expanded);
|
||||
};
|
|
@ -0,0 +1,68 @@
|
|||
// Self
|
||||
#include "SyncNTP.h"
|
||||
|
||||
// GxEPD2
|
||||
#include <GxEPD2_BW.h>
|
||||
|
||||
// Fonts
|
||||
#include <Fonts/FreeMonoBold9pt7b.h>
|
||||
|
||||
// WiFi
|
||||
#include <WiFi.h>
|
||||
|
||||
// Watchy
|
||||
#include "WatchyRTC.h"
|
||||
|
||||
// NTP
|
||||
#include <NTPClient.h>
|
||||
|
||||
CSyncNTP::CSyncNTP(CWatchyExpanded& expanded) : CWatchyApp(expanded) {}
|
||||
|
||||
const char* CSyncNTP::Name() const
|
||||
{
|
||||
return "SyncNTP";
|
||||
}
|
||||
|
||||
void CSyncNTP::Work()
|
||||
{
|
||||
CWatchyExpanded::ADisplay& display = m_expanded.Display();
|
||||
display.setFullWindow();
|
||||
display.fillScreen(GxEPD_BLACK);
|
||||
display.setFont(&FreeMonoBold9pt7b);
|
||||
display.setTextColor(GxEPD_WHITE);
|
||||
display.setCursor(0, 10);
|
||||
display.println("Syncing NTP...");
|
||||
display.display(false); //full refresh
|
||||
|
||||
if(m_expanded.ConnectWiFi())
|
||||
{
|
||||
if (!SyncNTP(3600 * -7, 3600, "pool.ntp.org"))
|
||||
display.println("Failed to Sync NTP!");
|
||||
else
|
||||
display.println("Synced to NTP!");
|
||||
|
||||
WiFi.mode(WIFI_OFF);
|
||||
btStop();
|
||||
}
|
||||
else
|
||||
{
|
||||
display.println("WiFi Not Configured.");
|
||||
}
|
||||
|
||||
display.display(true); //full refresh
|
||||
delay(3000);
|
||||
}
|
||||
|
||||
//NTP sync - call after connecting to WiFi and remember to turn it back off
|
||||
bool CSyncNTP::SyncNTP(long gmt, int dst, String ntpServer)
|
||||
{
|
||||
WiFiUDP ntpUDP;
|
||||
NTPClient timeClient(ntpUDP, ntpServer.c_str(), gmt);
|
||||
timeClient.begin();
|
||||
if(!timeClient.forceUpdate())
|
||||
return false; //NTP sync failed
|
||||
tmElements_t tm;
|
||||
breakTime((time_t)timeClient.getEpochTime(), tm);
|
||||
m_expanded.RTC().set(tm);
|
||||
return true;
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
#pragma once
|
||||
|
||||
// Epanded
|
||||
#include "WatchyApp.h"
|
||||
|
||||
class CSyncNTP : public CWatchyApp
|
||||
{
|
||||
public:
|
||||
CSyncNTP(CWatchyExpanded& expanded);
|
||||
const char* Name() const override;
|
||||
void Work() override;
|
||||
|
||||
private:
|
||||
bool SyncNTP(long gmt, int dst, String ntpServer);
|
||||
};
|
||||
|
|
@ -4,13 +4,25 @@
|
|||
// Fonts
|
||||
#include <Fonts/FreeMonoBold9pt7b.h>
|
||||
|
||||
void CTimeWatchFace::Draw(CWatchyExpanded::ADisplay& display, const tmElements_t& time)
|
||||
void CTimeWatchFace::Draw(CWatchyExpanded& expanded)
|
||||
{
|
||||
CWatchyExpanded::ADisplay& display = expanded.Display();
|
||||
StartDraw(display);
|
||||
DrawInternal(expanded);
|
||||
};
|
||||
|
||||
void CTimeWatchFace::StartDraw(CWatchyExpanded::ADisplay& display)
|
||||
{
|
||||
display.setFullWindow();
|
||||
display.fillScreen(GxEPD_BLACK);
|
||||
display.setFont(&FreeMonoBold9pt7b);
|
||||
display.setCursor(0, 15);
|
||||
};
|
||||
|
||||
void CTimeWatchFace::DrawInternal(CWatchyExpanded& expanded)
|
||||
{
|
||||
CWatchyExpanded::ADisplay& display = expanded.Display();
|
||||
tmElements_t& time = expanded.Time();
|
||||
m_currentLocalTime.tm_hour = time.Hour;
|
||||
m_currentLocalTime.tm_min = time.Minute;
|
||||
m_currentLocalTime.tm_sec = time.Second;
|
||||
|
|
|
@ -10,7 +10,10 @@
|
|||
class CTimeWatchFace : public CWatchFace
|
||||
{
|
||||
public:
|
||||
void Draw(CWatchyExpanded::ADisplay& display, const tmElements_t& time) override;
|
||||
virtual void Draw(CWatchyExpanded& expanded) override;
|
||||
|
||||
void StartDraw(CWatchyExpanded::ADisplay& display);
|
||||
void DrawInternal(CWatchyExpanded& expanded);
|
||||
|
||||
protected:
|
||||
tm m_currentLocalTime;
|
||||
|
|
|
@ -10,6 +10,5 @@ class CWatchFace
|
|||
{
|
||||
public:
|
||||
CWatchFace() = default;
|
||||
//override this method for different watch faces
|
||||
virtual void Draw(CWatchyExpanded::ADisplay& display, const tmElements_t& time) = 0;
|
||||
virtual void Draw(CWatchyExpanded& expanded) = 0; //override this method for different watch faces
|
||||
};
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
// Self
|
||||
#include "WatchyApp.h"
|
||||
|
||||
|
||||
CWatchyApp::CWatchyApp(CWatchyExpanded& expanded) : m_expanded(expanded) {}
|
|
@ -1,7 +1,15 @@
|
|||
#pragma once
|
||||
|
||||
// Expanded
|
||||
#include "WatchyExpanded.h"
|
||||
|
||||
class CWatchyApp
|
||||
{
|
||||
public:
|
||||
CWatchyApp(CWatchyExpanded& expanded);
|
||||
virtual const char* Name() const = 0;
|
||||
virtual void Work() = 0;
|
||||
|
||||
protected:
|
||||
CWatchyExpanded& m_expanded;
|
||||
};
|
||||
|
||||
|
|
|
@ -8,14 +8,24 @@
|
|||
|
||||
// Faces
|
||||
#include "TimeWatchFace.h"
|
||||
#include "DateTimeWatchFace.h"
|
||||
#include "DateWatchFace.h"
|
||||
|
||||
// Apps
|
||||
#include "SyncNTP.h"
|
||||
|
||||
// Fonts
|
||||
#include <Fonts/FreeMonoBold9pt7b.h>
|
||||
|
||||
// WiFi
|
||||
#include <WiFi.h>
|
||||
|
||||
RTC_DATA_ATTR SExpandedData g_data;
|
||||
|
||||
CWatchyExpanded::CWatchyExpanded() : m_display(GxEPD2_154_D67(wcd::cs, wcd::dc, wcd::reset, wcd::busy)), m_data(g_data)
|
||||
{
|
||||
AddWatchFace(new CTimeWatchFace);
|
||||
AddWatchFace(new CDateTimeWatchFace);
|
||||
AddWatchFace(new CDateWatchFace);
|
||||
AddApp(new CSyncNTP(*this));
|
||||
}
|
||||
|
||||
void CWatchyExpanded::AddWatchFace(CWatchFace* pFace)
|
||||
|
@ -23,6 +33,11 @@ void CWatchyExpanded::AddWatchFace(CWatchFace* pFace)
|
|||
m_faces.push_back(pFace);
|
||||
}
|
||||
|
||||
void CWatchyExpanded::AddApp(CWatchyApp* pApp)
|
||||
{
|
||||
m_apps.push_back(pApp);
|
||||
}
|
||||
|
||||
void CWatchyExpanded::Run()
|
||||
{
|
||||
const esp_sleep_wakeup_cause_t wakeup_reason = esp_sleep_get_wakeup_cause(); //get wake up reason
|
||||
|
@ -37,7 +52,7 @@ void CWatchyExpanded::Run()
|
|||
switch (wakeup_reason)
|
||||
{
|
||||
case ESP_SLEEP_WAKEUP_EXT0: //RTC Alarm
|
||||
if(m_guiState == wc::kWatchFace_State)
|
||||
if(m_data.m_guiState == SExpandedData::guiState::face)
|
||||
m_UpdateWatchFace = true;
|
||||
break;
|
||||
case ESP_SLEEP_WAKEUP_EXT1: //button Press
|
||||
|
@ -50,11 +65,37 @@ void CWatchyExpanded::Run()
|
|||
if (m_UpdateWatchFace)
|
||||
{
|
||||
m_rtc.read(m_currentTime);
|
||||
UpdateScreen(false); // full update
|
||||
UpdateScreen(true); // full update
|
||||
}
|
||||
DeepSleep();
|
||||
}
|
||||
|
||||
CWatchyExpanded::ADisplay& CWatchyExpanded::Display()
|
||||
{
|
||||
return m_display;
|
||||
}
|
||||
|
||||
WatchyRTC& CWatchyExpanded::RTC()
|
||||
{
|
||||
return m_rtc;
|
||||
}
|
||||
|
||||
tmElements_t& CWatchyExpanded::Time()
|
||||
{
|
||||
return m_currentTime;
|
||||
}
|
||||
|
||||
bool CWatchyExpanded::ConnectWiFi()
|
||||
{
|
||||
//WiFi not setup, you can also use hard coded credentials with WiFi.begin(SSID,PASS);
|
||||
if(wl_status_t::WL_CONNECT_FAILED == WiFi.begin())
|
||||
return false;
|
||||
|
||||
WiFi.waitForConnectResult();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void CWatchyExpanded::Init()
|
||||
{
|
||||
if (!m_data.m_init)
|
||||
|
@ -73,33 +114,62 @@ void CWatchyExpanded::DisplayBusyCallback(const void*)
|
|||
void CWatchyExpanded::UpdateScreen(const bool partial_update)
|
||||
{
|
||||
m_display.setFullWindow();
|
||||
m_currentTime.Month = 4;
|
||||
m_faces[m_data.m_face % m_faces.size()]->Draw(m_display, m_currentTime);
|
||||
m_faces[m_data.m_face % m_faces.size()]->Draw(*this);
|
||||
m_display.display(partial_update); //partial refresh
|
||||
m_guiState = wc::kWatchFace_State;
|
||||
m_data.m_guiState = SExpandedData::guiState::face;
|
||||
}
|
||||
|
||||
void CWatchyExpanded::DeepSleep()
|
||||
{
|
||||
m_display.hibernate();
|
||||
m_data.m_init = false;
|
||||
m_rtc.clearAlarm(); //resets the alarm flag in the RTC
|
||||
m_rtc.clearAlarm(); // resets the alarm flag in the RTC
|
||||
|
||||
for(int i = 0; i < 40; ++i) // Set pins 0-39 to input to avoid power leaking out
|
||||
pinMode(i, INPUT);
|
||||
|
||||
esp_sleep_enable_ext0_wakeup(wc::rtc_pin, 0); //enable deep sleep wake on RTC interrupt
|
||||
esp_sleep_enable_ext1_wakeup(wc::btn_pin_mask, ESP_EXT1_WAKEUP_ANY_HIGH); //enable deep sleep wake on button press
|
||||
esp_sleep_enable_ext0_wakeup(wcp::rtc_pin, 0); //enable deep sleep wake on RTC interrupt
|
||||
esp_sleep_enable_ext1_wakeup(wcp::btn_pin_mask, ESP_EXT1_WAKEUP_ANY_HIGH); //enable deep sleep wake on button press
|
||||
esp_deep_sleep_start();
|
||||
}
|
||||
|
||||
void CWatchyExpanded::HandleButtonPress()
|
||||
{
|
||||
const uint64_t kWakeupBit = esp_sleep_get_ext1_wakeup_status();
|
||||
if (kWakeupBit & wc::up_btn_mask)
|
||||
BackFace();
|
||||
else if (kWakeupBit & wc::down_btn_mask)
|
||||
ForwardFace();
|
||||
if (m_data.m_guiState == SExpandedData::guiState::face)
|
||||
{
|
||||
if (kWakeupBit & wcp::up_btn_mask)
|
||||
BackFace();
|
||||
else if (kWakeupBit & wcp::down_btn_mask)
|
||||
ForwardFace();
|
||||
else if (kWakeupBit & wcp::menu_btn_mask)
|
||||
Menu();
|
||||
}
|
||||
else if (m_data.m_guiState == SExpandedData::guiState::menu)
|
||||
{
|
||||
if (kWakeupBit & wcp::back_btn_mask)
|
||||
{
|
||||
m_data.m_guiState = SExpandedData::guiState::face;
|
||||
m_UpdateWatchFace = true;
|
||||
}
|
||||
else if (kWakeupBit & wcp::menu_btn_mask)
|
||||
{
|
||||
m_apps[m_data.menu % m_apps.size()]->Work();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CWatchyExpanded::Menu()
|
||||
{
|
||||
m_display.setFullWindow();
|
||||
m_display.fillScreen(GxEPD_BLACK);
|
||||
m_display.setFont(&FreeMonoBold9pt7b);
|
||||
m_display.setCursor(0, 15);
|
||||
|
||||
for (const CWatchyApp* pApp : m_apps)
|
||||
m_display.println(pApp->Name());
|
||||
m_data.m_guiState = SExpandedData::guiState::menu;
|
||||
m_display.display(true);
|
||||
}
|
||||
|
||||
void CWatchyExpanded::BackFace()
|
||||
|
@ -131,3 +201,11 @@ uint16_t CWatchyExpanded::_readRegister(uint8_t address, uint8_t reg, uint8_t *d
|
|||
data[++i] = Wire.read();
|
||||
return 0;
|
||||
}
|
||||
|
||||
float CWatchyExpanded::BatteryVoltage()
|
||||
{
|
||||
if(m_rtc.rtcType == DS3231)
|
||||
return analogReadMilliVolts(wcp::batt_adc_pin) / 1000.0f * 2.0f; // Battery voltage goes through a 1/2 divider.
|
||||
else
|
||||
return analogReadMilliVolts(wcp::batt_adc_pin) / 1000.0f * 2.0f;
|
||||
}
|
||||
|
|
|
@ -23,28 +23,48 @@ struct SExpandedData
|
|||
{
|
||||
bool m_init = true;
|
||||
std::uint8_t m_face = 0;
|
||||
|
||||
enum guiState : std::uint8_t
|
||||
{
|
||||
face,
|
||||
menu
|
||||
} m_guiState = guiState::face;
|
||||
|
||||
std::uint8_t m_menuItem = 0;
|
||||
};
|
||||
|
||||
class CWatchyExpanded
|
||||
{
|
||||
public:
|
||||
using ADisplay = GxEPD2_BW<GxEPD2_154_D67, GxEPD2_154_D67::HEIGHT>;
|
||||
|
||||
CWatchyExpanded();
|
||||
|
||||
void AddWatchFace(CWatchFace* pFace);
|
||||
void AddApp(CWatchyApp* pApp);
|
||||
void Init();
|
||||
void Run();
|
||||
|
||||
using ADisplay = GxEPD2_BW<GxEPD2_154_D67, GxEPD2_154_D67::HEIGHT>;
|
||||
bool ConnectWiFi();
|
||||
|
||||
ADisplay& Display();
|
||||
WatchyRTC& RTC();
|
||||
tmElements_t& Time();
|
||||
float BatteryVoltage();
|
||||
|
||||
private:
|
||||
static void DisplayBusyCallback(const void*);
|
||||
|
||||
void UpdateScreen(const bool fullUpdate);
|
||||
void DeepSleep();
|
||||
|
||||
void HandleButtonPress();
|
||||
|
||||
void BackFace();
|
||||
void ForwardFace();
|
||||
|
||||
void Menu();
|
||||
|
||||
void _bmaConfig();
|
||||
static uint16_t _readRegister(uint8_t address, uint8_t reg, uint8_t *data, uint16_t len);
|
||||
|
||||
|
@ -53,7 +73,7 @@ class CWatchyExpanded
|
|||
|
||||
ADisplay m_display;
|
||||
tmElements_t m_currentTime;
|
||||
std::int8_t m_guiState = 0;
|
||||
|
||||
WatchyRTC m_rtc;
|
||||
SExpandedData& m_data;
|
||||
bool m_UpdateWatchFace = false;
|
||||
|
|
|
@ -1,118 +1,122 @@
|
|||
#include "WatchyRTC.h"
|
||||
|
||||
WatchyRTC::WatchyRTC()
|
||||
: rtc_ds(false) {}
|
||||
: rtc_ds(false) {}
|
||||
|
||||
void WatchyRTC::init(){
|
||||
byte error;
|
||||
Wire.beginTransmission(RTC_DS_ADDR);
|
||||
error = Wire.endTransmission();
|
||||
if(error == 0){
|
||||
rtcType = DS3231;
|
||||
}else{
|
||||
Wire.beginTransmission(RTC_PCF_ADDR);
|
||||
error = Wire.endTransmission();
|
||||
if(error == 0){
|
||||
rtcType = PCF8563;
|
||||
}else{
|
||||
//RTC Error
|
||||
}
|
||||
}
|
||||
void WatchyRTC::init()
|
||||
{
|
||||
byte error;
|
||||
Wire.beginTransmission(RTC_DS_ADDR);
|
||||
error = Wire.endTransmission();
|
||||
if(error == 0)
|
||||
{
|
||||
rtcType = DS3231;
|
||||
}
|
||||
else
|
||||
{
|
||||
Wire.beginTransmission(RTC_PCF_ADDR);
|
||||
error = Wire.endTransmission();
|
||||
if(error == 0)
|
||||
rtcType = PCF8563;
|
||||
}
|
||||
}
|
||||
|
||||
void WatchyRTC::config(String datetime){ //String datetime format is YYYY:MM:DD:HH:MM:SS
|
||||
if(rtcType == DS3231){
|
||||
_DSConfig(datetime);
|
||||
}else{
|
||||
_PCFConfig(datetime);
|
||||
}
|
||||
if(rtcType == DS3231){
|
||||
_DSConfig(datetime);
|
||||
}else{
|
||||
_PCFConfig(datetime);
|
||||
}
|
||||
}
|
||||
|
||||
void WatchyRTC::clearAlarm(){
|
||||
if(rtcType == DS3231){
|
||||
rtc_ds.alarm(ALARM_2);
|
||||
}else{
|
||||
int nextAlarmMinute = 0;
|
||||
rtc_pcf.clearAlarm(); //resets the alarm flag in the RTC
|
||||
nextAlarmMinute = rtc_pcf.getMinute();
|
||||
nextAlarmMinute = (nextAlarmMinute == 59) ? 0 : (nextAlarmMinute + 1); //set alarm to trigger 1 minute from now
|
||||
rtc_pcf.setAlarm(nextAlarmMinute, 99, 99, 99);
|
||||
}
|
||||
void WatchyRTC::clearAlarm()
|
||||
{
|
||||
if(rtcType == DS3231)
|
||||
{
|
||||
rtc_ds.alarm(ALARM_2);
|
||||
}
|
||||
else
|
||||
{
|
||||
rtc_pcf.clearAlarm(); //resets the alarm flag in the RTC
|
||||
int nextAlarmMinute = rtc_pcf.getMinute();
|
||||
nextAlarmMinute = (nextAlarmMinute == 59) ? 0 : (nextAlarmMinute + 1); //set alarm to trigger 1 minute from now
|
||||
rtc_pcf.setAlarm(nextAlarmMinute, 99, 99, 99);
|
||||
}
|
||||
}
|
||||
|
||||
void WatchyRTC::read(tmElements_t &tm){
|
||||
if(rtcType == DS3231){
|
||||
rtc_ds.read(tm);
|
||||
}else{
|
||||
tm.Year = y2kYearToTm(rtc_pcf.getYear());
|
||||
tm.Month = rtc_pcf.getMonth();
|
||||
tm.Day = rtc_pcf.getDay();
|
||||
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();
|
||||
}
|
||||
if(rtcType == DS3231){
|
||||
rtc_ds.read(tm);
|
||||
}else{
|
||||
tm.Year = y2kYearToTm(rtc_pcf.getYear());
|
||||
tm.Month = rtc_pcf.getMonth();
|
||||
tm.Day = rtc_pcf.getDay();
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
||||
void WatchyRTC::set(tmElements_t tm){
|
||||
if(rtcType == DS3231){
|
||||
time_t t = makeTime(tm);
|
||||
rtc_ds.set(t);
|
||||
}else{
|
||||
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();
|
||||
}
|
||||
if(rtcType == DS3231){
|
||||
time_t t = makeTime(tm);
|
||||
rtc_ds.set(t);
|
||||
}else{
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t WatchyRTC::temperature(){
|
||||
if(rtcType == DS3231){
|
||||
return rtc_ds.temperature();
|
||||
}else{
|
||||
return 255; //error
|
||||
}
|
||||
if(rtcType == DS3231){
|
||||
return rtc_ds.temperature();
|
||||
}else{
|
||||
return 255; //error
|
||||
}
|
||||
}
|
||||
|
||||
void WatchyRTC::_DSConfig(String datetime){ //String datetime is YYYY:MM:DD:HH:MM:SS
|
||||
if(datetime != ""){
|
||||
tmElements_t tm;
|
||||
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);
|
||||
rtc_ds.set(t);
|
||||
}
|
||||
//https://github.com/JChristensen/DS3232RTC
|
||||
rtc_ds.squareWave(SQWAVE_NONE); //disable square wave output
|
||||
rtc_ds.setAlarm(ALM2_EVERY_MINUTE, 0, 0, 0, 0); //alarm wakes up Watchy every minute
|
||||
rtc_ds.alarmInterrupt(ALARM_2, true); //enable alarm interrupt
|
||||
if(datetime != ""){
|
||||
tmElements_t tm;
|
||||
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);
|
||||
rtc_ds.set(t);
|
||||
}
|
||||
//https://github.com/JChristensen/DS3232RTC
|
||||
rtc_ds.squareWave(SQWAVE_NONE); //disable square wave output
|
||||
rtc_ds.setAlarm(ALM2_EVERY_MINUTE, 0, 0, 0, 0); //alarm wakes up Watchy every minute
|
||||
rtc_ds.alarmInterrupt(ALARM_2, true); //enable alarm interrupt
|
||||
}
|
||||
|
||||
void WatchyRTC::_PCFConfig(String datetime){ //String datetime is YYYY:MM:DD:HH:MM:SS
|
||||
if(datetime != ""){
|
||||
tmElements_t tm;
|
||||
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(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);
|
||||
}
|
||||
//on POR event, PCF8563 sets month to 0, which will give an error since months are 1-12
|
||||
clearAlarm();
|
||||
if(datetime != ""){
|
||||
tmElements_t tm;
|
||||
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(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);
|
||||
}
|
||||
//on POR event, PCF8563 sets month to 0, which will give an error since months are 1-12
|
||||
clearAlarm();
|
||||
}
|
||||
|
||||
String WatchyRTC::_getValue(String data, char separator, int index)
|
||||
|
@ -122,11 +126,11 @@ String WatchyRTC::_getValue(String data, char separator, int index)
|
|||
int maxIndex = data.length()-1;
|
||||
|
||||
for(int i=0; i<=maxIndex && found<=index; i++){
|
||||
if(data.charAt(i)==separator || i==maxIndex){
|
||||
found++;
|
||||
strIndex[0] = strIndex[1]+1;
|
||||
strIndex[1] = (i == maxIndex) ? i+1 : i;
|
||||
}
|
||||
if(data.charAt(i)==separator || i==maxIndex){
|
||||
found++;
|
||||
strIndex[0] = strIndex[1]+1;
|
||||
strIndex[1] = (i == maxIndex) ? i+1 : i;
|
||||
}
|
||||
}
|
||||
|
||||
return found>index ? data.substring(strIndex[0], strIndex[1]) : "";
|
||||
|
|
|
@ -30,9 +30,6 @@
|
|||
namespace watchy_config
|
||||
{
|
||||
|
||||
// Menu
|
||||
constexpr std::int8_t kWatchFace_State{-1};
|
||||
|
||||
namespace display
|
||||
{
|
||||
// Display
|
||||
|
@ -46,16 +43,32 @@ constexpr std::uint8_t reset{9};
|
|||
constexpr std::uint8_t busy{19};
|
||||
};
|
||||
|
||||
namespace pins
|
||||
{
|
||||
|
||||
// RTC pins
|
||||
constexpr gpio_num_t rtc_pin{GPIO_NUM_27};
|
||||
|
||||
#define ARDUINO_WATCHY_V20 1
|
||||
|
||||
#if defined (ARDUINO_WATCHY_V10)
|
||||
constexpr std::uint64_t up_btn_mask{GPIO_SEL_32};
|
||||
#elif defined (ARDUINO_WATCHY_V15)
|
||||
constexpr std::uint64_t up_btn_mask{GPIO_SEL_32};
|
||||
#elif defined (ARDUINO_WATCHY_V20)
|
||||
constexpr std::uint64_t up_btn_mask{GPIO_SEL_35};
|
||||
constexpr std:: uint8_t batt_adc_pin{34};
|
||||
#endif
|
||||
|
||||
// btn pins & masks
|
||||
constexpr std::uint64_t menu_btn_mask{GPIO_SEL_26};
|
||||
constexpr std::uint64_t back_btn_mask{GPIO_SEL_25};
|
||||
constexpr std::uint64_t up_btn_mask{GPIO_SEL_32};
|
||||
constexpr std::uint64_t down_btn_mask{GPIO_SEL_4};
|
||||
constexpr std::uint64_t btn_pin_mask{menu_btn_mask|back_btn_mask|up_btn_mask|down_btn_mask};
|
||||
|
||||
};
|
||||
};
|
||||
|
||||
namespace wc = watchy_config;
|
||||
namespace wcd = watchy_config::display;
|
||||
namespace wcp = watchy_config::pins;
|
||||
|
|
Loading…
Reference in New Issue