Skip to content

Commit bef3e70

Browse files
committed
Merge branch 'ShakeWake' of https://github.com/geekbozu/InfiniTime into geekbozu-ShakeWake
# Conflicts: # src/CMakeLists.txt # src/displayapp/Apps.h # src/displayapp/DisplayApp.cpp # src/displayapp/screens/settings/Settings.cpp
2 parents b8b54f4 + e82469b commit bef3e70

12 files changed

Lines changed: 262 additions & 26 deletions

File tree

src/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -448,6 +448,7 @@ list(APPEND SOURCE_FILES
448448
displayapp/screens/settings/SettingSetDate.cpp
449449
displayapp/screens/settings/SettingSetTime.cpp
450450
displayapp/screens/settings/SettingChimes.cpp
451+
displayapp/screens/settings/SettingShakeThreshold.cpp
451452

452453
## Watch faces
453454
displayapp/icons/bg_clock.c

src/components/motion/MotionController.cpp

Lines changed: 26 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
#include "components/motion/MotionController.h"
2-
2+
#include "os/os_cputime.h"
33
using namespace Pinetime::Controllers;
44

55
void MotionController::Update(int16_t x, int16_t y, int16_t z, uint32_t nbSteps) {
66
if (this->nbSteps != nbSteps && service != nullptr) {
77
service->OnNewStepCountValue(nbSteps);
88
}
99

10-
if(service != nullptr && (this->x != x || this->y != y || this->z != z)) {
10+
if (service != nullptr && (this->x != x || this->y != y || this->z != z)) {
1111
service->OnNewMotionValues(x, y, z);
1212
}
1313

@@ -21,7 +21,7 @@ void MotionController::Update(int16_t x, int16_t y, int16_t z, uint32_t nbSteps)
2121
}
2222
}
2323

24-
bool MotionController::ShouldWakeUp(bool isSleeping) {
24+
bool MotionController::Should_RaiseWake(bool isSleeping) {
2525
if ((x + 335) <= 670 && z < 0) {
2626
if (not isSleeping) {
2727
if (y <= 0) {
@@ -43,6 +43,29 @@ bool MotionController::ShouldWakeUp(bool isSleeping) {
4343
}
4444
return false;
4545
}
46+
47+
bool MotionController::Should_ShakeWake(uint16_t thresh) {
48+
bool wake = false;
49+
auto diff = xTaskGetTickCount() - lastShakeTime;
50+
lastShakeTime = xTaskGetTickCount();
51+
/* Currently Polling at 10hz, If this ever goes faster scalar and EMA might need adjusting */
52+
int32_t speed = std::abs(z + (y / 2) + (x / 4) - lastYForShake - lastZForShake) / diff * 100;
53+
//(.2 * speed) + ((1 - .2) * accumulatedspeed);
54+
// implemented without floats as .25Alpha
55+
accumulatedspeed = (speed / 5) + ((accumulatedspeed / 5) * 4);
56+
57+
if (accumulatedspeed > thresh) {
58+
wake = true;
59+
}
60+
lastXForShake = x / 4;
61+
lastYForShake = y / 2;
62+
lastZForShake = z;
63+
return wake;
64+
}
65+
int32_t MotionController::currentShakeSpeed() {
66+
return accumulatedspeed;
67+
}
68+
4669
void MotionController::IsSensorOk(bool isOk) {
4770
isSensorOk = isOk;
4871
}

src/components/motion/MotionController.h

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,10 @@ namespace Pinetime {
3535
uint32_t GetTripSteps() const {
3636
return currentTripSteps;
3737
}
38-
bool ShouldWakeUp(bool isSleeping);
3938

39+
bool Should_ShakeWake(uint16_t thresh);
40+
bool Should_RaiseWake(bool isSleeping);
41+
int32_t currentShakeSpeed();
4042
void IsSensorOk(bool isOk);
4143
bool IsSensorOk() const {
4244
return isSensorOk;
@@ -59,6 +61,12 @@ namespace Pinetime {
5961
bool isSensorOk = false;
6062
DeviceTypes deviceType = DeviceTypes::Unknown;
6163
Pinetime::Controllers::MotionService* service = nullptr;
64+
65+
int16_t lastXForShake = 0;
66+
int16_t lastYForShake = 0;
67+
int16_t lastZForShake = 0;
68+
int32_t accumulatedspeed = 0;
69+
uint32_t lastShakeTime = 0;
6270
};
6371
}
6472
}

src/components/settings/Settings.h

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ namespace Pinetime {
1616
SingleTap = 0,
1717
DoubleTap = 1,
1818
RaiseWrist = 2,
19+
Shake = 3,
1920
};
2021
enum class Colors : uint8_t {
2122
White, Silver, Gray, Black, Red, Maroon, Yellow, Olive, Lime, Green, Cyan, Teal, Blue, Navy, Magenta, Purple, Orange
@@ -119,10 +120,23 @@ namespace Pinetime {
119120
}
120121
settings.screenTimeOut = timeout;
121122
};
123+
122124
uint32_t GetScreenTimeOut() const {
123125
return settings.screenTimeOut;
124126
};
125127

128+
void SetShakeThreshold(uint16_t thresh){
129+
if(settings.shakeWakeThreshold != thresh){
130+
settings.shakeWakeThreshold = thresh;
131+
settingsChanged = true;
132+
}
133+
134+
}
135+
136+
int16_t GetShakeThreshold() const{
137+
return settings.shakeWakeThreshold;
138+
}
139+
126140
void setWakeUpMode(WakeUpMode wakeUp, bool enabled) {
127141
if (enabled != isWakeUpModeOn(wakeUp)) {
128142
settingsChanged = true;
@@ -137,13 +151,13 @@ namespace Pinetime {
137151
case WakeUpMode::DoubleTap:
138152
settings.wakeUpMode.set(static_cast<size_t>(WakeUpMode::SingleTap), false);
139153
break;
140-
case WakeUpMode::RaiseWrist:
154+
default:
141155
break;
142156
}
143157
}
144158
};
145159

146-
std::bitset<3> getWakeUpModes() const {
160+
std::bitset<4> getWakeUpModes() const {
147161
return settings.wakeUpMode;
148162
}
149163

@@ -187,8 +201,8 @@ namespace Pinetime {
187201

188202
PineTimeStyle PTS;
189203

190-
std::bitset<3> wakeUpMode {0};
191-
204+
std::bitset<4> wakeUpMode {0};
205+
uint16_t shakeWakeThreshold = 150;
192206
Controllers::BrightnessController::Levels brightLevel = Controllers::BrightnessController::Levels::Medium;
193207
};
194208

src/displayapp/Apps.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,8 @@ namespace Pinetime {
3737
SettingSetDate,
3838
SettingSetTime,
3939
SettingChimes,
40-
Error,
40+
SettingShakeThreshold,
41+
Error
4142
};
4243
}
4344
}

src/displayapp/DisplayApp.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@
4848
#include "displayapp/screens/settings/SettingSetDate.h"
4949
#include "displayapp/screens/settings/SettingSetTime.h"
5050
#include "displayapp/screens/settings/SettingChimes.h"
51+
#include "displayapp/screens/settings/SettingShakeThreshold.h"
5152

5253
#include "libs/lv_conf.h"
5354

@@ -423,6 +424,10 @@ void DisplayApp::LoadApp(Apps app, DisplayApp::FullRefreshDirections direction)
423424
currentScreen = std::make_unique<Screens::SettingChimes>(this, settingsController);
424425
ReturnApp(Apps::Settings, FullRefreshDirections::Down, TouchEvents::SwipeDown);
425426
break;
427+
case Apps::SettingShakeThreshold:
428+
currentScreen = std::make_unique<Screens::SettingShakeThreshold>(this, settingsController,motionController,*systemTask);
429+
ReturnApp(Apps::Settings, FullRefreshDirections::Down, TouchEvents::SwipeDown);
430+
break;
426431
case Apps::BatteryInfo:
427432
currentScreen = std::make_unique<Screens::BatteryInfo>(this, batteryController);
428433
ReturnApp(Apps::Settings, FullRefreshDirections::Down, TouchEvents::SwipeDown);
Lines changed: 137 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,137 @@
1+
#include "SettingShakeThreshold.h"
2+
#include <lvgl/lvgl.h>
3+
#include "displayapp/DisplayApp.h"
4+
#include "displayapp/screens/Screen.h"
5+
#include "displayapp/screens/Symbols.h"
6+
7+
using namespace Pinetime::Applications::Screens;
8+
9+
namespace {
10+
void event_handler(lv_obj_t* obj, lv_event_t event) {
11+
SettingShakeThreshold* screen = static_cast<SettingShakeThreshold*>(obj->user_data);
12+
screen->UpdateSelected(obj, event);
13+
}
14+
}
15+
16+
SettingShakeThreshold::SettingShakeThreshold(DisplayApp* app,
17+
Controllers::Settings& settingsController,
18+
Controllers::MotionController& motionController,
19+
System::SystemTask& systemTask)
20+
: Screen(app), settingsController {settingsController}, motionController {motionController}, systemTask {systemTask} {
21+
22+
lv_obj_t* title = lv_label_create(lv_scr_act(), nullptr);
23+
lv_label_set_text_static(title, "Wake Sensitivity");
24+
lv_label_set_align(title, LV_LABEL_ALIGN_CENTER);
25+
lv_obj_align(title, lv_scr_act(), LV_ALIGN_IN_TOP_MID, 0, 0);
26+
27+
positionArc = lv_arc_create(lv_scr_act(), nullptr);
28+
positionArc->user_data = this;
29+
30+
lv_obj_set_event_cb(positionArc, event_handler);
31+
lv_arc_set_bg_angles(positionArc, 180, 360);
32+
lv_arc_set_range(positionArc, 0, 4095);
33+
lv_arc_set_adjustable(positionArc, true);
34+
lv_obj_set_width(positionArc, lv_obj_get_width(lv_scr_act()) - 10);
35+
lv_obj_set_height(positionArc, 240);
36+
lv_obj_align(positionArc, title, LV_ALIGN_OUT_BOTTOM_MID, 0, 0);
37+
38+
animArc = lv_arc_create(positionArc, positionArc);
39+
lv_arc_set_adjustable(animArc, false);
40+
lv_obj_set_width(animArc, lv_obj_get_width(positionArc));
41+
lv_obj_set_height(animArc, lv_obj_get_height(positionArc));
42+
lv_obj_align_mid(animArc, positionArc, LV_ALIGN_CENTER, 0, 0);
43+
lv_obj_set_style_local_line_opa(animArc, LV_ARC_PART_BG, LV_STATE_DEFAULT, 0);
44+
lv_obj_set_style_local_line_opa(animArc, LV_ARC_PART_INDIC, LV_STATE_DEFAULT, LV_OPA_70);
45+
lv_obj_set_style_local_line_opa(animArc, LV_ARC_PART_KNOB, LV_STATE_DEFAULT, LV_OPA_0);
46+
lv_obj_set_style_local_line_color(animArc, LV_ARC_PART_INDIC, LV_STATE_DEFAULT, LV_COLOR_RED);
47+
lv_obj_set_style_local_bg_color(animArc, LV_ARC_PART_BG, LV_STATE_CHECKED, LV_COLOR_TRANSP);
48+
49+
animArc->user_data = this;
50+
lv_obj_set_click(animArc, false);
51+
52+
calButton = lv_btn_create(lv_scr_act(), nullptr);
53+
calButton->user_data = this;
54+
lv_obj_set_event_cb(calButton, event_handler);
55+
lv_obj_set_height(calButton, 80);
56+
lv_obj_set_width(calButton, 200);
57+
lv_obj_align(calButton, lv_scr_act(), LV_ALIGN_IN_BOTTOM_MID, 0, 0);
58+
lv_btn_set_checkable(calButton, true);
59+
calLabel = lv_label_create(calButton, NULL);
60+
lv_label_set_text(calLabel, "Calibrate");
61+
62+
lv_arc_set_value(positionArc, settingsController.GetShakeThreshold());
63+
64+
vDecay = xTaskGetTickCount();
65+
calibrating = false;
66+
EnableForCal = false;
67+
if(!settingsController.isWakeUpModeOn(Pinetime::Controllers::Settings::WakeUpMode::Shake)){
68+
EnableForCal = true;
69+
settingsController.setWakeUpMode(Pinetime::Controllers::Settings::WakeUpMode::Shake,true);
70+
}
71+
refreshTask = lv_task_create(RefreshTaskCallback, LV_DISP_DEF_REFR_PERIOD, LV_TASK_PRIO_MID, this);
72+
}
73+
74+
SettingShakeThreshold::~SettingShakeThreshold() {
75+
settingsController.SetShakeThreshold(lv_arc_get_value(positionArc));
76+
77+
if(EnableForCal){
78+
settingsController.setWakeUpMode(Pinetime::Controllers::Settings::WakeUpMode::Shake,false);
79+
EnableForCal = false;
80+
}
81+
lv_task_del(refreshTask);
82+
settingsController.SaveSettings();
83+
lv_obj_clean(lv_scr_act());
84+
}
85+
86+
void SettingShakeThreshold::Refresh() {
87+
88+
if (calibrating == 1) {
89+
if (xTaskGetTickCount() - vCalTime > pdMS_TO_TICKS(2000)) {
90+
vCalTime = xTaskGetTickCount();
91+
calibrating = 2;
92+
lv_obj_set_style_local_bg_color(calButton, LV_BTN_PART_MAIN, LV_STATE_CHECKED, LV_COLOR_RED);
93+
lv_obj_set_style_local_bg_color(calButton, LV_BTN_PART_MAIN, LV_STATE_CHECKED, LV_COLOR_RED);
94+
lv_label_set_text(calLabel, "Shake!!");
95+
}
96+
}
97+
if (calibrating == 2) {
98+
99+
if ((motionController.currentShakeSpeed() - 300) > lv_arc_get_value(positionArc)) {
100+
lv_arc_set_value(positionArc, (int16_t) motionController.currentShakeSpeed() - 300);
101+
}
102+
if (xTaskGetTickCount() - vCalTime > pdMS_TO_TICKS(7500)) {
103+
lv_btn_set_state(calButton, LV_STATE_DEFAULT);
104+
lv_event_send(calButton, LV_EVENT_VALUE_CHANGED, NULL);
105+
}
106+
}
107+
if (motionController.currentShakeSpeed() - 300 > lv_arc_get_value(animArc)) {
108+
lv_arc_set_value(animArc, (uint16_t) motionController.currentShakeSpeed() - 300);
109+
vDecay = xTaskGetTickCount();
110+
} else if ((xTaskGetTickCount() - vDecay) > pdMS_TO_TICKS(1500)) {
111+
lv_arc_set_value(animArc, lv_arc_get_value(animArc) - 25);
112+
}
113+
}
114+
115+
void SettingShakeThreshold::UpdateSelected(lv_obj_t* object, lv_event_t event) {
116+
117+
switch (event) {
118+
case LV_EVENT_VALUE_CHANGED: {
119+
if (object == calButton) {
120+
if (lv_btn_get_state(calButton) == LV_BTN_STATE_CHECKED_RELEASED && calibrating == 0) {
121+
lv_arc_set_value(positionArc, 0);
122+
calibrating = 1;
123+
vCalTime = xTaskGetTickCount();
124+
lv_label_set_text(calLabel, "Ready!");
125+
lv_obj_set_click(positionArc, false);
126+
lv_obj_set_style_local_bg_color(calButton, LV_BTN_PART_MAIN, LV_STATE_CHECKED, LV_COLOR_GREEN);
127+
lv_obj_set_style_local_bg_color(calButton, LV_BTN_PART_MAIN, LV_STATE_CHECKED, LV_COLOR_GREEN);
128+
} else if (lv_btn_get_state(calButton) == LV_BTN_STATE_RELEASED) {
129+
calibrating = 0;
130+
lv_obj_set_click(positionArc, true);
131+
lv_label_set_text(calLabel, "Calibrate");
132+
}
133+
break;
134+
}
135+
}
136+
}
137+
}
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
#pragma once
2+
3+
#include <cstdint>
4+
#include <lvgl/lvgl.h>
5+
#include "components/settings/Settings.h"
6+
#include "displayapp/screens/Screen.h"
7+
#include <components/motion/MotionController.h>
8+
namespace Pinetime {
9+
10+
namespace Applications {
11+
namespace Screens {
12+
13+
class SettingShakeThreshold : public Screen {
14+
public:
15+
SettingShakeThreshold(DisplayApp* app,
16+
Pinetime::Controllers::Settings& settingsController,
17+
Controllers::MotionController& motionController,
18+
System::SystemTask& systemTask);
19+
20+
~SettingShakeThreshold() override;
21+
void Refresh() override;
22+
void UpdateSelected(lv_obj_t* object, lv_event_t event);
23+
24+
private:
25+
Controllers::Settings& settingsController;
26+
Controllers::MotionController& motionController;
27+
System::SystemTask& systemTask;
28+
uint8_t calibrating;
29+
bool EnableForCal;
30+
uint32_t vDecay,vCalTime;
31+
lv_obj_t *positionArc, *animArc,*calButton, *calLabel;
32+
lv_task_t* refreshTask;
33+
};
34+
}
35+
}
36+
}

src/displayapp/screens/settings/SettingWakeUp.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,14 @@ SettingWakeUp::SettingWakeUp(Pinetime::Applications::DisplayApp* app, Pinetime::
6565
lv_checkbox_set_checked(cbOption[optionsTotal], true);
6666
}
6767
optionsTotal++;
68+
cbOption[optionsTotal] = lv_checkbox_create(container1, nullptr);
69+
lv_checkbox_set_text_static(cbOption[optionsTotal], " Shake Wake");
70+
cbOption[optionsTotal]->user_data = this;
71+
lv_obj_set_event_cb(cbOption[optionsTotal], event_handler);
72+
if (settingsController.isWakeUpModeOn(Pinetime::Controllers::Settings::WakeUpMode::Shake)) {
73+
lv_checkbox_set_checked(cbOption[optionsTotal], true);
74+
}
75+
optionsTotal++;
6876
}
6977

7078
SettingWakeUp::~SettingWakeUp() {

src/displayapp/screens/settings/SettingWakeUp.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ namespace Pinetime {
2020
private:
2121
Controllers::Settings& settingsController;
2222
uint8_t optionsTotal;
23-
lv_obj_t* cbOption[4];
23+
lv_obj_t* cbOption[5];
2424
// When UpdateSelected is called, it uses lv_checkbox_set_checked,
2525
// which can cause extra events to be fired,
2626
// which might trigger UpdateSelected again, causing a loop.

0 commit comments

Comments
 (0)