基于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。