BetaFlight模块设计之十九:摄像头按键控制模拟任务分析
基于BetaFlight开源代码框架简介的框架设计,逐步分析内部模块功能设计。
1. 模拟任务
描述:主要通过摄像头OSD控制引线,使用PWM的方式模拟电压,从而触发摄像头内部配置菜单。
注:模拟按键触发,主要通过OSD菜单(processRcStickPositions)或者Telemetry MSP协议(mspProcessInCommand)进行处理。
├──> 初始化
│ ├──> [v]硬件初始化cameraControlInit
│ └──> [v]业务初始化pgResetFn_cameraControlConfig
├──> 任务
│ ├──> [x]实时任务
│ ├──> [x]事件任务
│ └──> [v]时间任务[TASK_CAMCTRL] = DEFINE_TASK("CAMCTRL", NULL, NULL, taskCameraControl, TASK_PERIOD_HZ(5), TASK_PRIORITY_LOW),
├──> 驱动
│ ├──> [x]查询
│ └──> [x]中断
└──> 接口
└──> void cameraControlKeyPress(cameraControlKey_e key, uint32_t holdDurationMs)
2. 模拟原理
逻辑就是通过PWM占空比来模拟不同的电压输出来模拟摄像头原有控制板功能逻辑。
从技术实现角度和代码层面分析,摄像头模拟控制存在以下三种方式:
- CAMERA_CONTROL_MODE_HARDWARE_PWM // 硬件PWM方式采用占空比模拟按键
- CAMERA_CONTROL_MODE_SOFTWARE_PWM // STM32 F1 F3 F4支持软件模拟PWM;STM32 F7 H7 G4不支持
- CAMERA_CONTROL_MODE_DAC // 尚未实现(4.3版本)
3. RC按键对应关系
这里给出了RC遥控器按键操作对应RC stick位置和摄像头菜单模拟控制板的按键关系,详见:processRcStickPositions
#ifdef USE_CAMERA_CONTROL
if (rcSticks == THR_CE + YAW_HI + PIT_CE + ROL_CE) {
cameraControlKeyPress(CAMERA_CONTROL_KEY_ENTER, 0);
repeatAfter(3 * STICK_DELAY_MS);
} else if (rcSticks == THR_CE + YAW_CE + PIT_CE + ROL_LO) {
cameraControlKeyPress(CAMERA_CONTROL_KEY_LEFT, 0);
repeatAfter(3 * STICK_DELAY_MS);
} else if (rcSticks == THR_CE + YAW_CE + PIT_HI + ROL_CE) {
cameraControlKeyPress(CAMERA_CONTROL_KEY_UP, 0);
repeatAfter(3 * STICK_DELAY_MS);
} else if (rcSticks == THR_CE + YAW_CE + PIT_CE + ROL_HI) {
cameraControlKeyPress(CAMERA_CONTROL_KEY_RIGHT, 0);
repeatAfter(3 * STICK_DELAY_MS);
} else if (rcSticks == THR_CE + YAW_CE + PIT_LO + ROL_CE) {
cameraControlKeyPress(CAMERA_CONTROL_KEY_DOWN, 0);
repeatAfter(3 * STICK_DELAY_MS);
} else if (rcSticks == THR_LO + YAW_CE + PIT_HI + ROL_CE) {
cameraControlKeyPress(CAMERA_CONTROL_KEY_UP, 2000);
}
#endif
4. 模拟方式分析
按键模拟通常来说,大致有几个动作,而这个摄像头控制按键模拟比较简单,有些是不需要的:
- 【MUST】push (action)
- 【MUST】release (action)
- 【NO NEED】click = push + hold(a short period) + release
- 【NO NEED】double click
- 【NO NEED】long push = push + hold(a long period)
4.1 taskCameraControl
主任务确保只有在未解锁的情况下才可以模拟。
taskCameraControl
├──> <ARMING_FLAG(ARMED)>
│ └──> return
└──> cameraControlProcess
4.2 cameraControlProcess
这里主要为了模拟一个按键释放的过程。
cameraControlProcess
└──> <endTimeMillis && currentTimeUs >= 1000 * endTimeMillis>
├──> <CAMERA_CONTROL_MODE_HARDWARE_PWM == cameraControlConfig()->mode>
│ └──> *cameraControlRuntime.channel.ccr = cameraControlRuntime.period; //周期到了恢复默认电平,模拟释放按键
├──> <CAMERA_CONTROL_MODE_SOFTWARE_PWM == cameraControlConfig()->mode>
│ └──> ;
└──> endTimeMillis = 0;
4.3 cameraControlKeyPress
cameraControlKeyPress是通过PWM或者高低电平占空比来调整分压的电压值,从而模拟实际电阻按键分压板的效果。
注:当前代码尚未实现DAC来实现分压板电压模拟。
cameraControlKeyPress
├──> <!cameraControlRuntime.enabled>
│ └──> return;
├──> <key >= CAMERA_CONTROL_KEYS_COUNT>
│ └──> return;
├──> <defined(CAMERA_CONTROL_HARDWARE_PWM_AVAILABLE) || defined(CAMERA_CONTROL_SOFTWARE_PWM_AVAILABLE)>
│ └──> const float dutyCycle = calculatePWMDutyCycle(key);
├──> <else>
│ └──> (void) holdDurationMs;
├──> <USE_OSD>
│ └──> resumeRefreshAt = 0; // Force OSD timeout so we are alone on the display.
├──> <CAMERA_CONTROL_MODE_HARDWARE_PWM == cameraControlConfig()->mode><CAMERA_CONTROL_HARDWARE_PWM_AVAILABLE> //硬件PWM
│ ├──> *cameraControlRuntime.channel.ccr = lrintf(dutyCycle * cameraControlRuntime.period);
│ └──> endTimeMillis = millis() + cameraControlConfig()->keyDelayMs + holdDurationMs;
├──> <CAMERA_CONTROL_MODE_SOFTWARE_PWM == cameraControlConfig()->mode><CAMERA_CONTROL_SOFTWARE_PWM_AVAILABLE> //软件IO模拟
│ └──> [通过IO软件延时等待控制IO高低电平来模拟按键]
└──> <CAMERA_CONTROL_MODE_DAC == cameraControlConfig()->mode> //尚未完成
└──> [@todo not yet implemented]
5. 总结
从目前设计角度来看,涉及很多方面,导致这一功能并不好用。
- 飞控设计(IO管脚选择)
- 摄像头设计(内阻,基准电压等)
鉴于上述设计问题都牵涉到硬件的差异性,软件上提供了较多参数来进行配置适配。且各个厂家提供的售后以及支持力度情况都不一。
注:如果非要使用这个的话,请参考官方文档FPV-Camera-Control-(Joystick-Emulation)。
- 大体步骤(常规摄像头),如下:
- resource camera_control PIN
- set camera_control_mode = hardware_pwm
- set camera_control_ref_voltage = 330
- set camera_control_key_delay = 180
- set camera_control_internal_resistance = 470
-
需要飞控厂家回答的问题:
- PIN多少???
- 支持hardware_pwm/software_pwm/DAC(代码尚不支持)
-
需要摄像头厂家回答的问题:
- 摄像头的的OSD引脚在悬空状态时的电压多少mV???
- 摄像头内部电阻,470即47K ???