翻腕亮屏算法
整体逻辑
具体的代码详见user_RunModeTask.c
中的StopEnterTask
, 在进入睡眠后, 由于RTC定时唤醒, 程序从HAL_PWR_EnterSTOPMode(PWR_MAINREGULATOR_ON,PWR_STOPENTRY_WFI);
停止状态, 重新苏醒,继续运行后面的代码。
注释your wakeup operations
后面的代码,就是MPU检测的相关算法,如果使能的话,则判断是否MPU处于水平状态,同时对比上一次状态,如果从非水平装换到水平状态,则表示翻腕动作,即可退出sleep,否则再次进入sleep。
/****************** operations before sleep ***************/
sleep:
// ...
// ...
/**********************************************************/
/********************* enter sleep mode *******************/
vTaskSuspendAll();
//Disnable Watch Dog
WDOG_Disnable();
//systick int
CLEAR_BIT(SysTick->CTRL, SysTick_CTRL_TICKINT_Msk);
//enter stop mode
HAL_PWR_EnterSTOPMode(PWR_MAINREGULATOR_ON,PWR_STOPENTRY_WFI);
//here is the sleep period
/**********************************************************/
/********************* quit sleep mode ********************/
//resume run mode and reset the sysclk
SET_BIT(SysTick->CTRL, SysTick_CTRL_TICKINT_Msk);
HAL_SYSTICK_Config(SystemCoreClock / (1000U / uwTickFreq));
SystemClock_Config();
WDOG_Feed();
xTaskResumeAll();
/**********************************************************/
/****************** your wakeup operations ****************/
// MPU Check
if(HWInterface.IMU.wrist_is_enabled)
{
uint8_t hor;
hor = MPU_isHorizontal();
if(hor && HWInterface.IMU.wrist_state == WRIST_DOWN)
{
HWInterface.IMU.wrist_state = WRIST_UP;
Wrist_Flag = 1;
//resume, go on
}
else if(!hor && HWInterface.IMU.wrist_state == WRIST_UP)
{
HWInterface.IMU.wrist_state = WRIST_DOWN;
IdleTimerCount = 0;
goto sleep;
}
}
// ...
/**********************************************************/
如何判断水平
函数MPU_isHorizontal()
, 是直接判断roll
和pitch
角来判断的, 这两个角度是根据MPU6050的accelerater加速度计获得, 为什么不直接用Gyroscope陀螺仪呢, 是因为低功耗的考虑, 根据手册Gyroscope比较耗电。
// 获取角度
void MPU_Get_Angles(float * roll,float * pitch)
{
short ax,ay,az;
MPU_Get_Accelerometer(&ax,&ay,&az);
*pitch = -atanf(ax/sqrtf(ay*ay+az*az));
*roll = atanf((float)ay/(float)az);
}
// 简单判断是否水平
uint8_t MPU_isHorizontal(void)
{
float roll,pitch;
MPU_Get_Angles(&roll,&pitch);
if(roll<=0.50 && roll>=-0.50 && pitch<=0.50 && pitch>=-0.50)
{return 1;}
return 0;
}
同时, 测试手表时,也测了睡眠时谁的功耗较大,结果是MPU6050占了大头,因为要检测步数等。