Add accelerometer interrupts and option to update the watch face less frequently
This commit is contained in:
		
							parent
							
								
									6609a3ab13
								
							
						
					
					
						commit
						ca117ea3fc
					
				
					 6 changed files with 112 additions and 14 deletions
				
			
		| 
						 | 
					@ -1,6 +1,7 @@
 | 
				
			||||||
#include "WatchFace.h"
 | 
					#include "WatchFace.h"
 | 
				
			||||||
#include "SevenSegment.h"
 | 
					#include "SevenSegment.h"
 | 
				
			||||||
#include <cmath>
 | 
					#include <cmath>
 | 
				
			||||||
 | 
					#include <Fonts/FreeSans9pt7b.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
RTC_DATA_ATTR bool WatchFace::m_menuSetup = false;
 | 
					RTC_DATA_ATTR bool WatchFace::m_menuSetup = false;
 | 
				
			||||||
RTC_DATA_ATTR bool WatchFace::m_inMenu = false;
 | 
					RTC_DATA_ATTR bool WatchFace::m_inMenu = false;
 | 
				
			||||||
| 
						 | 
					@ -62,6 +63,16 @@ void WatchFace::HandleButtonPress(uint64_t buttonMask)
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void WatchFace::HandleDoubleTap()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  ShowWatchFace(true);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void WatchFace::HandleTilt()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  ShowWatchFace(true);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void WatchFace::DrawWatchFace(bool partialRefresh)
 | 
					void WatchFace::DrawWatchFace(bool partialRefresh)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  if (m_inMenu) {
 | 
					  if (m_inMenu) {
 | 
				
			||||||
| 
						 | 
					@ -130,10 +141,15 @@ void WatchFace::SetupVolatileMenuStuff()
 | 
				
			||||||
					1 // pageNum
 | 
										1 // pageNum
 | 
				
			||||||
				},
 | 
									},
 | 
				
			||||||
				{
 | 
									{
 | 
				
			||||||
					"Set TZ", // title
 | 
										"Set Timezone", // title
 | 
				
			||||||
					nullptr, // callback
 | 
										nullptr, // callback
 | 
				
			||||||
					2 // pageNum
 | 
										2 // pageNum
 | 
				
			||||||
				},
 | 
									},
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					          "Reset Steps", // title
 | 
				
			||||||
 | 
					          nullptr, // callback
 | 
				
			||||||
 | 
					          3 // pageNum
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
				{
 | 
									{
 | 
				
			||||||
					"Back", // title
 | 
										"Back", // title
 | 
				
			||||||
					nullptr, // callback
 | 
										nullptr, // callback
 | 
				
			||||||
| 
						 | 
					@ -191,6 +207,24 @@ void WatchFace::SetupVolatileMenuStuff()
 | 
				
			||||||
					0 // pageNum
 | 
										0 // pageNum
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
			},
 | 
								},
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								0, // backPageNum
 | 
				
			||||||
 | 
								"RESET STEPS", // title
 | 
				
			||||||
 | 
								ALIGNMENT_CENTER, // titleAlignment
 | 
				
			||||||
 | 
								"Confirm?", // body
 | 
				
			||||||
 | 
								{ // Menu items
 | 
				
			||||||
 | 
									{
 | 
				
			||||||
 | 
										"No", // title
 | 
				
			||||||
 | 
										nullptr, // callback
 | 
				
			||||||
 | 
										0 // pageNum
 | 
				
			||||||
 | 
									},
 | 
				
			||||||
 | 
									{
 | 
				
			||||||
 | 
										"Yes", // title
 | 
				
			||||||
 | 
										std::bind(&WatchFace::MenuConfirmResetSteps, this), // callback
 | 
				
			||||||
 | 
										0 // pageNum
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	};
 | 
						};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -229,3 +263,14 @@ void WatchFace::MenuTimeZoneSelected(int tzOffset)
 | 
				
			||||||
		DrawWatchFace(false);
 | 
							DrawWatchFace(false);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void WatchFace::MenuConfirmResetSteps()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  ResetSteps();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if (m_inMenu) {
 | 
				
			||||||
 | 
					    m_inMenu = false;
 | 
				
			||||||
 | 
					    m_menu.Reset();
 | 
				
			||||||
 | 
					    DrawWatchFace(false);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -8,6 +8,8 @@ class WatchFace : public Watchy
 | 
				
			||||||
public:
 | 
					public:
 | 
				
			||||||
  void Setup() override; // Called after hardware is set up
 | 
					  void Setup() override; // Called after hardware is set up
 | 
				
			||||||
  void HandleButtonPress(uint64_t buttonMask) override;
 | 
					  void HandleButtonPress(uint64_t buttonMask) override;
 | 
				
			||||||
 | 
					  void HandleDoubleTap() override;
 | 
				
			||||||
 | 
					  void HandleTilt() override;
 | 
				
			||||||
  void DrawWatchFace(bool partialRefresh = false) override;
 | 
					  void DrawWatchFace(bool partialRefresh = false) override;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
private:
 | 
					private:
 | 
				
			||||||
| 
						 | 
					@ -21,4 +23,5 @@ private:
 | 
				
			||||||
  void MenuExited();
 | 
					  void MenuExited();
 | 
				
			||||||
  void MenuNTPSyncSelected();
 | 
					  void MenuNTPSyncSelected();
 | 
				
			||||||
  void MenuTimeZoneSelected(int tzOffset);
 | 
					  void MenuTimeZoneSelected(int tzOffset);
 | 
				
			||||||
 | 
					  void MenuConfirmResetSteps();
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
| 
						 | 
					@ -1,11 +1,11 @@
 | 
				
			||||||
#include "Watchy.h"
 | 
					#include "Watchy.h"
 | 
				
			||||||
 | 
					#include "bma423.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
WatchyDisplayBase Watchy::m_displayBase;
 | 
					WatchyDisplayBase Watchy::m_displayBase;
 | 
				
			||||||
WatchyDisplay Watchy::m_display(Watchy::m_displayBase);
 | 
					WatchyDisplay Watchy::m_display(Watchy::m_displayBase);
 | 
				
			||||||
WatchyRTC Watchy::m_RTC;
 | 
					WatchyRTC Watchy::m_RTC;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
RTC_DATA_ATTR BMA423 Watchy::m_sensor;
 | 
					RTC_DATA_ATTR BMA423 Watchy::m_sensor;
 | 
				
			||||||
 | 
					 | 
				
			||||||
RTC_DATA_ATTR bool g_displayFullInit = true;
 | 
					RTC_DATA_ATTR bool g_displayFullInit = true;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Watchy::Watchy()
 | 
					Watchy::Watchy()
 | 
				
			||||||
| 
						 | 
					@ -35,8 +35,28 @@ void Watchy::Init()
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    case ESP_SLEEP_WAKEUP_EXT1:
 | 
					    case ESP_SLEEP_WAKEUP_EXT1:
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
      // Button press
 | 
					 | 
				
			||||||
      uint64_t wakeupBit = esp_sleep_get_ext1_wakeup_status();
 | 
					      uint64_t wakeupBit = esp_sleep_get_ext1_wakeup_status();
 | 
				
			||||||
 | 
					      if (wakeupBit & ACC_INT_MASK) {
 | 
				
			||||||
 | 
					        m_sensor.getINT();
 | 
				
			||||||
 | 
					        uint8_t irqMask = m_sensor.getIRQMASK();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if(irqMask & BMA423_TILT_INT) {
 | 
				
			||||||
 | 
					          HandleTilt();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        if(irqMask & BMA423_WAKEUP_INT) {
 | 
				
			||||||
 | 
					          HandleDoubleTap();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        m_sensor.getINT();
 | 
				
			||||||
 | 
					      } else if (wakeupBit & BTN_PIN_MASK) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // Button press
 | 
				
			||||||
 | 
					        HandleButtonPress(wakeupBit);
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      // Button press
 | 
				
			||||||
      HandleButtonPress(wakeupBit);
 | 
					      HandleButtonPress(wakeupBit);
 | 
				
			||||||
      break;
 | 
					      break;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
| 
						 | 
					@ -75,7 +95,7 @@ void Watchy::DeepSleep()
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  esp_sleep_enable_ext0_wakeup((gpio_num_t)RTC_INT_PIN, 0); // enable deep sleep wake on RTC interrupt
 | 
					  esp_sleep_enable_ext0_wakeup((gpio_num_t)RTC_INT_PIN, 0); // enable deep sleep wake on RTC interrupt
 | 
				
			||||||
  esp_sleep_enable_ext1_wakeup(
 | 
					  esp_sleep_enable_ext1_wakeup(
 | 
				
			||||||
    BTN_PIN_MASK,
 | 
					    BTN_PIN_MASK | ACC_INT_MASK,
 | 
				
			||||||
    ESP_EXT1_WAKEUP_ANY_HIGH);
 | 
					    ESP_EXT1_WAKEUP_ANY_HIGH);
 | 
				
			||||||
  esp_deep_sleep_start();
 | 
					  esp_deep_sleep_start();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -103,6 +123,16 @@ float Watchy::GetBatteryVoltage()
 | 
				
			||||||
  return analogReadMilliVolts(BATT_ADC_PIN) / 1000.0f * 2.0f;
 | 
					  return analogReadMilliVolts(BATT_ADC_PIN) / 1000.0f * 2.0f;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					uint64_t Watchy::GetSteps()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  return m_sensor.getCounter();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void Watchy::ResetSteps()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  m_sensor.resetStepCounter();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void Watchy::ConnectWiFi()
 | 
					void Watchy::ConnectWiFi()
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  if(WiFi.begin(WIFI_SSID, WIFI_PASS) == WL_CONNECT_FAILED) {  
 | 
					  if(WiFi.begin(WIFI_SSID, WIFI_PASS) == WL_CONNECT_FAILED) {  
 | 
				
			||||||
| 
						 | 
					@ -233,7 +263,6 @@ void Watchy::BmaConfig()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // Enable BMA423 accelerometer
 | 
					  // Enable BMA423 accelerometer
 | 
				
			||||||
  // Warning : Need to use feature, you must first enable the accelerometer
 | 
					  // Warning : Need to use feature, you must first enable the accelerometer
 | 
				
			||||||
  // Warning : Need to use feature, you must first enable the accelerometer
 | 
					 | 
				
			||||||
  m_sensor.enableAccel();
 | 
					  m_sensor.enableAccel();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  struct bma4_int_pin_config config;
 | 
					  struct bma4_int_pin_config config;
 | 
				
			||||||
| 
						 | 
					@ -263,11 +292,13 @@ void Watchy::BmaConfig()
 | 
				
			||||||
  m_sensor.enableFeature(BMA423_WAKEUP, true);
 | 
					  m_sensor.enableFeature(BMA423_WAKEUP, true);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // Reset steps
 | 
					  // Reset steps
 | 
				
			||||||
  m_sensor.resetStepCounter();
 | 
					  //m_sensor.resetStepCounter();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // Turn on feature interrupt
 | 
					  // Turn on feature interrupt
 | 
				
			||||||
  m_sensor.enableStepCountInterrupt();
 | 
					  //m_sensor.enableStepCountInterrupt();
 | 
				
			||||||
  m_sensor.enableTiltInterrupt();
 | 
					
 | 
				
			||||||
  // It corresponds to isDoubleClick interrupt
 | 
					  if (WAKE_ON_ACCEL_EVENTS) {
 | 
				
			||||||
  m_sensor.enableWakeupInterrupt();
 | 
					    m_sensor.enableTiltInterrupt();
 | 
				
			||||||
 | 
					    m_sensor.enableWakeupInterrupt();
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -16,6 +16,8 @@ public:
 | 
				
			||||||
  void DeepSleep();
 | 
					  void DeepSleep();
 | 
				
			||||||
  void VibeMotor(uint8_t intervalMs = 100, uint8_t length = 20);
 | 
					  void VibeMotor(uint8_t intervalMs = 100, uint8_t length = 20);
 | 
				
			||||||
  float GetBatteryVoltage();
 | 
					  float GetBatteryVoltage();
 | 
				
			||||||
 | 
					  uint64_t GetSteps();
 | 
				
			||||||
 | 
					  void ResetSteps();
 | 
				
			||||||
  void ConnectWiFi();
 | 
					  void ConnectWiFi();
 | 
				
			||||||
  void SyncNTPTime();
 | 
					  void SyncNTPTime();
 | 
				
			||||||
  void DisconnectWiFi();
 | 
					  void DisconnectWiFi();
 | 
				
			||||||
| 
						 | 
					@ -26,9 +28,13 @@ public:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // Called after hardware is setup
 | 
					  // Called after hardware is setup
 | 
				
			||||||
  virtual void Setup() = 0;
 | 
					  virtual void Setup() = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  virtual void HandleButtonPress(uint64_t buttonMask) = 0;
 | 
					  virtual void HandleButtonPress(uint64_t buttonMask) = 0;
 | 
				
			||||||
 | 
					  virtual void HandleDoubleTap() {}
 | 
				
			||||||
 | 
					  virtual void HandleTilt() {}
 | 
				
			||||||
  virtual void DrawWatchFace(bool partialRefresh = false) = 0;
 | 
					  virtual void DrawWatchFace(bool partialRefresh = false) = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
protected:
 | 
					protected:
 | 
				
			||||||
  static void DisplayBusyCallback(const void *);
 | 
					  static void DisplayBusyCallback(const void *);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -17,9 +17,19 @@ void WatchyRTC::config(String datetime) { // String datetime format is YYYY:MM:D
 | 
				
			||||||
void WatchyRTC::clearAlarm() {
 | 
					void WatchyRTC::clearAlarm() {
 | 
				
			||||||
  int nextAlarmMinute = 0;
 | 
					  int nextAlarmMinute = 0;
 | 
				
			||||||
  rtc_pcf.clearAlarm(); // resets the alarm flag in the RTC
 | 
					  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
 | 
					  int second = rtc_pcf.getSecond();
 | 
				
			||||||
  rtc_pcf.setAlarm(nextAlarmMinute, 99, 99, 99);
 | 
					  int minute = rtc_pcf.getMinute();
 | 
				
			||||||
 | 
					  int hour = rtc_pcf.getHour();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  minute += UPDATE_INTERVAL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if (minute >= 60) {
 | 
				
			||||||
 | 
					    hour += minute / 60;
 | 
				
			||||||
 | 
					    minute = minute % 60;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  rtc_pcf.setAlarm(minute, hour, 99, 99);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void WatchyRTC::read(tmElements_t & tm, int offsetInSeconds)
 | 
					void WatchyRTC::read(tmElements_t & tm, int offsetInSeconds)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -28,4 +28,7 @@
 | 
				
			||||||
#define WIFI_PASS "<pass>"
 | 
					#define WIFI_PASS "<pass>"
 | 
				
			||||||
#define TZ_OFFSET 3600 * 3
 | 
					#define TZ_OFFSET 3600 * 3
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define NTP_SERVER "pool.ntp.org"
 | 
					#define NTP_SERVER "pool.ntp.org"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define UPDATE_INTERVAL 1
 | 
				
			||||||
 | 
					#define WAKE_ON_ACCEL_EVENTS false
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue