翻腕亮屏算法

整体逻辑

具体的代码详见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(), 是直接判断rollpitch角来判断的, 这两个角度是根据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占了大头,因为要检测步数等。

Copyright © 油炸鸡开源硬件 | 渝ICP备2024035140号 | all right reserved,powered by Gitbook更新时间: 2024-11-12 16:26:31

results matching ""

    No results matching ""