[项目]基于FreeRTOS的STM32四轴飞行器: 十.检测遥控器

发布于:2025-03-23 ⋅ 阅读:(43) ⋅ 点赞:(0)

基于FreeRTOS的STM32四轴飞行器: 十.检测遥控器

一.检测遥控器连接逻辑

判断是否进入定高模式:
在这里插入图片描述
根据返回值判断遥控器的连接情况
在这里插入图片描述
实现检测函数:
在这里插入图片描述
因为该函数在通信任务中调度6ms一次,可以使用cnt进行计时,判断是否失联:
开头初始化 cnt 为200可以防止一启动没有连接显示连接成功的问题。

/**
 * @description: 用来检测遥控器的连接情况
 *  连接成功:
 *      只要收到一条数据,就算连接成功
 *  失联:
 *      如果连续 1.2s 没有收到数据,表示失联
 * @param {Com_Status} isReceiveData 是否收到遥控器数据
 * @return {*}  是否连接成功
 */
Com_Status App_Communication_CheckConnection(Com_Status isReceiveData)
{                             /* 记录连续收不到数据的次数 */
    static uint8_t cnt = 200; /* 初始化为200可以防止一启动时候,没有连接成功显示连接成功问题*/
    /* 1. 如果收到数据,表示连接成功 */
    if(isReceiveData == Com_OK)
    {
        cnt = 0;
        return Com_OK;
    }

    /* 2. 表示没有收到数据: 计时, 连续200次(1.2s) */
    cnt++;
    if(cnt >= 200)
    {
        cnt = 200; /* 避免溢出 */
        return Com_FAIL;
    }

    return Com_OK;
}

二.遥控器的解锁情况

创建一个状态机进行状态转换。


/**
 * @description: 遥控器的解锁
 *  把油门拉到最高,持续1s,然后再拉到最低,持续1s, 解锁成功.
 *
 *   自由状态
 *       在此状态, 如果油门拉到最高(>=960), 进入  最大值附近 状态
 *   最大值附近
 *       如果油门持续时间超过1s ,离开最大值状态
 *       如果在这里持续时间不到1s, 退回到 自由状态
 *   离开最大值
 *       如果出现油门 <=20, 进入最小值附近
 *   最小值附近
 *       如果持续时间大于1s, 进入解锁状态
 *       如果持续时间不到1s, 进入自由状态
 *   解锁
 *
 *
 *
 *
 * @param {Com_Status} isRemoteConnected 是否连接成功
 * @return {*} 是否解锁成功 Com_OK 解锁成功  其他 解锁失败
 */
Com_Status App_Communication_RemoteUnlock(Com_Status isRemoteConnected)
{
    /* 油门在最大值和最小值附近的持续时间 */
    static uint8_t thrMaxDuration = 0;
    static uint8_t thrMinDuration = 0;
    /* 定义油门的状态 */
    static Com_RemoteStatus remoteStatus = THR_FREE;

    /* 1. 如果失联状态, 直接解锁失败 */
    if(isRemoteConnected != Com_OK)
    {
        remoteStatus         = THR_FREE;
        joyStick.isFixHeight = 0;
        isFixHeight          = Com_FAIL;
        return Com_FAIL;
    }

    switch(remoteStatus)
    {
        case THR_FREE:
        {
            /* 在自由状态, 最大值和最小值附近持续时间从0计数 */
            thrMaxDuration = 0;
            thrMinDuration = 0;
            if(joyStick.THR >= 960)
            {
                remoteStatus = THR_MAX;
            }
            break;
        }
        case THR_MAX:
        {
            if(joyStick.THR >= 960)
            {
                /* 判断持续时间 */
                thrMaxDuration++;
                if(thrMaxDuration >= 200)
                {
                    remoteStatus = THR_MAX_LEAVE;
                }
            }
            else
            {
                /* 证明在最大值附近没有坚持1.2s */
                remoteStatus = THR_FREE; /* 回到自由状态 */
            }
            break;
        }
        case THR_MAX_LEAVE:
        {
            if(joyStick.THR <= 20)
            {
                remoteStatus = THR_MIN;
            }
            break;
        }
        case THR_MIN:
        {
            if(joyStick.THR <= 20)
            {
                thrMinDuration++;
                if(thrMinDuration >= 200)
                {
                    remoteStatus = THR_UNLOCK;
                }
            }
            else
            {
                remoteStatus = THR_FREE;
            }
            break;
        }
        case THR_UNLOCK:
        {
            /* 如果解锁状态下,油门长时间(1min) <=20, 马上锁定 */
            static uint32_t lowDuration = 0;
            if(joyStick.THR <= 20)
            {
                lowDuration++;
                if(lowDuration >= 200 * 50)
                {
                    remoteStatus = THR_FREE;
                    lowDuration  = 0;
                }
            }
            else
            {
                lowDuration = 0;
            }

            /* 解锁成功, 直接返回成功 */
            return Com_OK;
        }

        default:
            break;
    }

    joyStick.isFixHeight = 0;
    isFixHeight          = Com_FAIL;
    /* 默认返回解锁失败 */
    return Com_FAIL;
}

三.遥控器控制飞机运转

创建飞机飞行的函数。

/**
 * @description: 让飞机工作(飞行)
 * @param {Com_Status} isRemoteUnlock
 * @return {*}
 */
void App_Flight_Work(Com_Status isRemoteUnlock)
{
    if (isRemoteUnlock != Com_OK || joyStick.THR <= 30)
    {
        motorLeftTop.speed =
            motorLeftBottom.speed =
                motorRightTop.speed =
                    motorRightBottom.speed = 0;
    }

    Inf_Motor_AllMotorsWork();
}

解决遥控器开机直接解锁的bug:
如果失联将状态变为FREE
在这里插入图片描述