目录

项目基于FreeRTOS的STM32四轴飞行器-八.遥控器摇杆

[项目]基于FreeRTOS的STM32四轴飞行器: 八.遥控器摇杆

下面摇杆初始化时,启动了ADC-DMA进行了采集,已经开始转换直接将数据通过DMA存入buff数组中:

static uint16_t buff[4] = {0};
/**
 * @description: 摇杆初始化
 * @return {*}
 */
void Inf_JoyStickAndKey_Init(void)
{
    debug_printfln("摇杆和按键数据的初始化 开始");
    /* 1. ADC校准 */
    HAL_ADCEx_Calibration_Start(&hadc1);

    /* 2. 启动ADC转换 */
    HAL_ADC_Start_DMA(&hadc1, (uint32_t *)buff, 4);
    debug_printfln("摇杆和按键数据的初始化 结束");
}

扫描摇杆数据时,直接从缓冲区中扫描就行了:

注意取数据要根据配置的Rank。

https://i-blog.csdnimg.cn/direct/1ba7f7499cfa4fe38d7d585f05f62fd8.png

定义摇杆数据:

com_config.h使用int16防止数据突变。

typedef struct
{
    int16_t THR; /* 油门 */
    int16_t PIT; /* 俯仰 */
    int16_t ROL; /* 横滚 */
    int16_t YAW; /* 偏航 */

    uint8_t isPowerDown; /* 是否关机: 1:关机 0:不关机 */
    uint8_t isFixHeight; /* 是否翻转定高的状态 */
} JoyStick_Struct;

扫描摇杆数据:

/**
* @description: 扫描摇杆数据
* @return {*}
*/
void Inf_JoyStickAndKey_JoyStickScan(void)
{
    joyStick.THR = buff[0];
    joyStick.YAW = buff[1];
    joyStick.PIT = buff[2];
    joyStick.ROL = buff[3];
}

创建摇杆处理任务:

先定义一些任务参数。

/* 4. 摇杆处理任务 */
void joyStickTask(void *args);
#define JOY_STICK_TASK_NAME "joy_stick_task"
#define JOY_STICK_TASK_STACK 256
#define JOY_STICK_TASK_PRIORITY 7
TaskHandle_t joyStickTaskHandle;
#define JOY_STICK_EXEC_CYCLE 4

/* 4. 摇杆处理任务 */
xTaskCreate(joyStickTask,
            JOY_STICK_TASK_NAME,
            JOY_STICK_TASK_STACK,
            NULL,
            JOY_STICK_TASK_PRIORITY,
            &joyStickTaskHandle);

测试打印摇杆数据:

https://i-blog.csdnimg.cn/direct/d2da554ece7746d5b96e9b80969a6880.png

/* 4. 摇杆处理 */
void joyStickTask(void *args)
{
    vTaskDelay(500);
    debug_printfln("摇杆处理任务开始调度");
    uint32_t preTime = xTaskGetTickCount();
    while(1)
    {
        Inf_JoyStickAndKey_JoyStickScan();
        Com_Config_PrintJoyStick("a");
        vTaskDelayUntil(&preTime, JOY_STICK_EXEC_CYCLE);
    }
}

观察打印数据全部为0:

因为要先启动ADC采集数据。

https://i-blog.csdnimg.cn/direct/0f63653f4bf747c3a31186a3d6f2ee7e.png

在启动任务前启动处理模块:

https://i-blog.csdnimg.cn/direct/b715615b975f47a396d6c8bcecfe01c4.png

https://i-blog.csdnimg.cn/direct/09b182481d474a48a5c2b0e0ab6f17e6.png

这时可以打印数据:

观察发现数据有一些极性相反。

https://i-blog.csdnimg.cn/direct/cf2feab1ca2f4e07bd4a77c4adcb4cf1.png

摇杆 极性和范围的处理

处理摇杆数据范围 0-4095转换为0-1000

/**
 * @description: 处理摇杆数据的极性和范围
 * @return {*}
 */
static void App_DataProcess_JoyStickPolarityAndRange(void)
{
    /* 1. 处理极性   [4095, 0]  => [0, 1000]
          (4095 -  [4095, 0]) / 4.095
          (4095 -  [4095, 0]) / (4095 / 1000)
          (4095 -  [4095, 0]) * 1000 / 4095
          1000 - [4095, 0] * 1000 / 4095

     */
    joyStick.THR = 1000 - joyStick.THR * 1000 / 4095;
    joyStick.ROL = 1000 - joyStick.ROL * 1000 / 4095;
    joyStick.PIT = 1000 - joyStick.PIT * 1000 / 4095;
    joyStick.YAW = 1000 - joyStick.YAW * 1000 / 4095;
}

处理摇杆数据:

/**
 * @description: 处理摇杆数据
 * @return {*}
 */
void App_DataProcess_JoyStickDataProcess(void)
{
    /* 1. 扫描摇杆 */
    Inf_JoyStickAndKey_JoyStickScan();
    /* 2. 极性和范围处理 */
    App_DataProcess_JoyStickPolarityAndRange();
	
	Com_Config_PrintJoyStick("2");

}

观察发现该数据在默认情况下会有 误差值 ,需要进行 校准

https://i-blog.csdnimg.cn/direct/997d5eb6f742418b979bda7156136f1b.png

摇杆数据校准:

想办法 求出数据偏移量长按按键 减去偏移量进行校准。

在Config.c中定义存储摇杆偏移量的结构体:

https://i-blog.csdnimg.cn/direct/30fa72d5161b4b7594a4fbd86fc72a25.png

计算偏移量:

/**
 * @description: 计算摇杆的偏移量
 * @return {*}
 */
static void App_DataProcess_JoyStickCaclBias(void)
{
    joyStickBias.THR = 0;
    joyStickBias.ROL = 0;
    joyStickBias.YAW = 0;
    joyStickBias.PIT = 0;

    for(uint8_t i = 0; i < 100; i++)
    {
        Inf_JoyStickAndKey_JoyStickScan();
        App_DataProcess_JoyStickPolarityAndRange();
        joyStickBias.THR += (joyStick.THR - 0);   /* 0值校准 */
        joyStickBias.PIT += (joyStick.PIT - 500); /* 中值校准 */
        joyStickBias.YAW += (joyStick.YAW - 500);
        joyStickBias.ROL += (joyStick.ROL - 500);
        vTaskDelay(10);
    }

    joyStickBias.THR /= 100;
    joyStickBias.PIT /= 100;
    joyStickBias.ROL /= 100;
    joyStickBias.YAW /= 100;
    // Com_Config_PrintJoyStickBias("bias 2");
}

校准:

/**
 * @description: 对摇杆数据做校准
 * @return {*}
 */
static void App_DataProcess_JoystickWithBias(void)
{
    /* 叠加偏移量 */
    joyStick.THR -= joyStickBias.THR;
    joyStick.PIT -= joyStickBias.PIT;
    joyStick.ROL -= joyStickBias.ROL;
    joyStick.YAW -= joyStickBias.YAW;

    /* 对校准后的数据做限幅处理 */
    joyStick.THR = LIMIT(joyStick.THR, 0, 1000);
    joyStick.PIT = LIMIT(joyStick.PIT, 0, 1000);
    joyStick.ROL = LIMIT(joyStick.ROL, 0, 1000);
    joyStick.YAW = LIMIT(joyStick.YAW, 0, 1000);
}

在打印数据时出现BUG,数值不正确:

https://i-blog.csdnimg.cn/direct/f1e40a29dbb24371b406e2ca347ae3d9.png

原因是扫描摇杆值后未对极性和范围处理,数值错误。

https://i-blog.csdnimg.cn/direct/d6a5915b7eb14524a6c64974f5efadf2.png

解决:

在执行完扫描后执行极性和范围处理函数,之后再计算偏移量。

https://i-blog.csdnimg.cn/direct/b8a4c2cfb4b04c12b8f1cd905ff196e7.png

在按键处理时,将该函数放在临界区中可以避免在长按时,任务调度到摇杆扫描:

https://i-blog.csdnimg.cn/direct/b33f62f0bcd74936aee453c9db8e1f9d.png

https://i-blog.csdnimg.cn/direct/26b252ed4cc74f31a8e0dc88ce8303e9.png

https://i-blog.csdnimg.cn/direct/959f64d49d3e4774be1c122e6f34590d.png

在摇杆结构体中添加isPowerDown和isFixHeight:

https://i-blog.csdnimg.cn/direct/0adfb353599648948bf9cbd7935f109f.png

在按键处理函数中 继续添加关机和定高功能:

https://i-blog.csdnimg.cn/direct/06048b4ece234e12baf129f6e0644736.png

继续 添加微调按钮:

保持飞行稳定不偏,将需要微调的数据直接加到偏移量中,之后减去偏移量可以达到效果。

https://i-blog.csdnimg.cn/direct/ea23f4e4da9c400095e2af65a415ddbc.png