Flipper Zero 延时摄影间隔拍摄器(Zeitraffer / Intervalometer)应用指南:硬件接线、按键操控与源码剖析
【免费下载链接】FlipperPlayground (and dump) of stuff I make or modify for the Flipper Zero项目地址: https://gitcode.com/GitHub_Trending/fl/Flipper
本篇技术指南以 Flipper Zero 开源仓库中收录的grnch/timelapse延时摄影应用(Zeitraffer / GPIO Intervalometer)为核心,完整介绍其在 Flipper Zero 上的按键操控逻辑、基于 EL817C 光耦的相机触发硬件搭建方案、配置文件格式,以及事件循环与 GPIO 脉冲触发的底层源码实现。读完本文后,你将能够独立完成该应用的硬件改装、接线与参数配置,并理解其定时拍照、无限连拍与 BULB 长曝等模式背后的工作原理。
应用概述:一个面向相机有线遥控的间隔拍摄器
timelapse(德语原名zeitraffer,意为"延时摄影")是一个基于 Flipper Zero 的简易延时摄影(intervalometer)应用,通过 Flipper Zero 的 GPIO 引脚驱动相机有线快门,实现间隔定时拍摄。该应用由开发者 Aurelius Rosenbaum 基于flipperzero-hello-world模板编写,适用于任何支持三触点有线遥控(快门 / 对焦 / 地)的相机,原作者最初即是为自己的 Sony DSLR A100 所制作。
在仓库中,该应用以外部应用(FAP)形式组织,其元数据声明于 application.fam:
appid:GPIO_Intervalometer,应用名称显示为[GPIO] Intervalometerapptype:FlipperAppType.EXTERNAL(作为.fap外部应用安装到 SD 卡)entry_point:zeitraffer_app(即 zeitraffer.c 中的主函数)requires:gui、input、notification、gpiofap_category:GPIO(安装后在应用菜单的 GPIO 分类下)stack_size:2 * 1024- 图标资源:
fap_icon="zeitraffer.png",fap_icon_assets="icons"
按键操控:短按、长按与连按三种输入模型
原文档给出的核心操控方式如下,全部映射到源码 zeitraffer.c 的输入事件处理中:
| 按键操作 | 功能 | 源码实现依据 |
|---|---|---|
| 上 / 下(短按) | 调整间隔时间(秒) | InputKeyUp/InputKeyDown,Time++/Time-- |
| 左 / 右(短按) | 调整拍摄帧数 | InputKeyLeft/InputKeyRight,Count++/Count-- |
| 长按方向键 | 以 ±10 的步长快速调整 | InputTypeRepeat分支,Time ± 10/Count ± 10 |
| OK(短按) | 开始 / 暂停拍摄 | InputTypeShort+InputKeyOk,启动/停止 1s 周期定时器 |
| OK(长按) | 循环切换屏幕背光:AUTO → ON → OFF | InputTypeLong+InputKeyOk,Backlight++到 2 后归 0 |
| 返回(短按) | 重置任务 | InputKeyBack,将已拍帧数WorkCount重置为Count |
| 返回(长按) | 退出应用(保存配置) | InputTypeLong+InputKeyBack,置空所有引脚后跳出主循环 |
两个重要的特殊约定(原文档明确说明,源码亦有对应实现):
- 帧数为 0 = 无限连拍模式(
Count == 0时置InfiniteShot = true,每拍一帧后WorkCount++使其持续下去); - 帧数为 -1 = BULB 长曝模式(
Count == -1时置Bulb = true,启动瞬间将快门相关引脚拉高并保持,曝光时长即设定的间隔秒数Time)。
此外,源码中还有两处隐藏的钳制逻辑:
- 间隔时间最小为 1 秒:
if(Time < 1) Time = 1;,防止误操作将间隔减到 0; - 帧数低于 -1 时自动复位为 0:
if(Count < -1) Count = 0;(注释解释了为何"网开一面":0 帧和 -1 帧都是特殊功能模式)。
运行中的按键锁定
当定时器处于运行状态时,除OK外的所有按键都会被忽略并伴随错误提示音。这在 zeitraffer.c 中体现为:每个方向键与返回键的处理器首先检查furi_timer_is_running(timer),若为真则直接发送sequence_error通知。这是为防止在长曝光或连拍过程中误触导致参数漂移而设计的保护机制。
启动 3 秒缓冲
每次开始拍摄时,都会先进入一个 3 秒倒计时(WorkTime = 3),给操作者留出"撤离"时间——这也是原作者在原文档中强调的"При запуске даётся три секунды на отскочить"(启动时给你三秒钟躲开)。倒计时期间蓝色 LED 会每秒闪烁提示。
硬件搭建:两只光耦驱动的相机快门
原文档列出了完整的硬件清单(README 的 "What you need" 一节),结合 gpio_item.c 中声明的 8 路 GPIO 引脚映射,可实现如下 DIY 接线:
所需元件
- 两只 EL817C 光耦——用于将 Flipper Zero 的 GPIO 输出与相机快门电路进行电气隔离,防止电平不匹配或共地干扰损坏设备;
- 1×3 排针(2.54mm 间距,公头)——用于插接到 Flipper Zero 的 GPIO 排座,或引出 Flipper 一侧的接线点;
- 若干导线;
- 热缩管(用于绝缘与固定焊点);
- 相机遥控接口/接头——需与你的相机型号匹配(三触点有线遥控标准),原作者建议自行寻找或自制匹配接头,并查阅对应相机的手册确认引脚定义。
接线原理
从源码触发逻辑可以推断实际驱动的 GPIO 通道。在 zeitraffer.c 中,拍照瞬间执行的代码为:
gpio_item_set_pin(4, true); gpio_item_set_pin(5, true); furi_delay_ms(400); // 相机对过短的脉冲反应不佳,故保持 400ms gpio_item_set_pin(4, false); gpio_item_set_pin(5, false);对照 gpio_item.c 的索引表,index 4对应1.6: PB2,index 5对应1.7: PC3。也就是说,该应用使用PB2 与 PC3 两个引脚并联驱动快门触发(对应应用启动时gpio_item_configure_all_pins(GpioModeOutputPushPull)将全部 8 路配置为推挽输出,但实际参与触发的是这两路)。
光耦一侧接 Flipper 的 PB2/PC3(经排针引出),另一侧接相机的三触点遥控接口。EL817C 内部为 LED + 光敏三极管结构:Flipper 拉高引脚时,光耦内部 LED 点亮,导通相机侧电路,等效于按下快门键;引脚拉低后释放。两只光耦分别对应快门与对焦信号(三触点遥控的典型定义),具体对应关系需以你的相机官方针脚资料为准。组装完成后用热缩管包覆焊接点,防止短路。
配置文件:参数持久化与格式说明
这是一个易被忽略但非常实用的功能:应用退出时会自动保存当前参数,下次启动时自动恢复,无需每次重新设置。这在 zeitraffer.c 中定义:
#define CONFIG_FILE_DIRECTORY_PATH "/ext/apps_data/intravelometer" #define CONFIG_FILE_PATH CONFIG_FILE_DIRECTORY_PATH "/intravelometer.conf"即配置文件保存在 SD 卡的/ext/apps_data/intravelometer/intravelometer.conf,采用 FlipperFormat 键值格式。启动时若文件存在则读取并播放成功提示音;读取失败则播放错误音。退出时写入以下内容(flipper_format_write_header_cstr(save, "Zeitraffer", 1)指定头与版本号):
| 配置键 | 含义 | 默认值 |
|---|---|---|
Time | 间隔时间(秒) | 10 |
Count | 拍摄帧数(0 = 无限,-1 = BULB) | 10 |
Backlight | 背光模式(0 = AUTO,1 = ON,2 = OFF) | 0 |
Delay | 启动缓冲延迟(秒) | 3 |
四个键均以 32 位整数(int32)读写,支持手工编辑该文件实现精细调参(例如把Delay改成更长的启动倒计时)。
源码工作机制:事件循环、定时触发与 GPIO 脉冲
事件驱动的 GUI 架构
应用采用 Flipper 标准的事件驱动模型:zeitraffer_app入口中创建容量为 8 的FuriMessageQueue事件队列,注册draw_callback与input_callback,随后通过gui_add_view_port(gui, view_port, GuiLayerFullscreen)以全屏层接入 GUI 服务;同时分配一个FuriTimerTypePeriodic周期定时器,回调向队列投递EventTypeTick事件。主循环furi_message_queue_get阻塞取事件,据此区分"按键事件"与"定时器心跳"两类处理。
每秒心跳与快门脉冲
定时器以1000ms周期启动(furi_timer_start(timer, 1000))。每次EventTypeTick时WorkTime--,倒计时归零则执行一次拍摄:
- 普通模式:将 PB2/PC3 拉高并保持400ms后释放(注释明确说明:过短的脉冲会导致相机反应不佳),随后
WorkCount--并复位WorkTime = Time,开始下一轮间隔计时; - BULB 模式:快门引脚在启动时拉高,tick 倒计时归零后
gpio_item_set_all_pins(false)全部释放,曝光时长恰好为设定的Time秒; - 每拍一帧屏幕立即刷新(
view_port_update),同时播放白色 LED 闪光通知(sequence_blink_white_100),未到拍摄时刻则闪烁蓝色 LED(sequence_blink_blue_100)。
结束判定与背光控制
当WorkCount < 1(拍摄任务完成或 BULB 曝光结束)时,应用自动停止定时器、全部引脚复位、播放音视频提示(sequence_audiovisual_alert),并将WorkTime复位为 3、WorkCount复位为 0,为下一轮任务做准备。背光则在每次心跳中依据Backlight值强制设置为常亮(sequence_display_backlight_on)、常灭(sequence_display_backlight_off)或交还系统自动控制(sequence_display_backlight_enforce_auto)。
屏幕布局
draw_callback绘制两行状态文本:第一行显示设定值(Set: N frames, M sec,BULB 时显示Set: BULB M sec,无限模式显示Set: infinite, M sec),第二行显示已执行进度(Left: N frames, M sec);底部左侧显示背光状态(AUTO/ON/OFF),并绘制方向键图标与F(帧数)、S(秒)标识;定时器运行时右上角显示加载动画图标。所有图标来自icons/目录与zeitraffer.png。
构建与安装
该应用作为标准外部应用(FAP)构建。可结合 application.fam 中的声明,在 Flipper Zero 官方固件 SDK 环境下,将grnch/timelapse目录加入外部应用列表后执行 FAP 编译,产物为zeitraffer.fap,复制到 SD 卡后在应用菜单的GPIO分类下即可找到 "Intervalometer" 并启动。
小结
timelapse是一个麻雀虽小五脏俱全的 Flipper Zero 外设应用范例:它同时示范了 FlipperFormat 配置持久化、FuriTimer 周期调度、消息队列事件分发、GPIO 推挽输出与通知系统联动等核心开发技巧,并提供了可实际投入使用的延时摄影能力。对摄影爱好者而言,参照本文的硬件清单与 GPIO 引脚映射即可完成改装;对开发者而言,zeitraffer.c 与 gpio_item.c 则是理解 Flipper 外部应用工程结构的理想参考。
【免费下载链接】FlipperPlayground (and dump) of stuff I make or modify for the Flipper Zero项目地址: https://gitcode.com/GitHub_Trending/fl/Flipper
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考