完整指南)
ESP-BLE-UART Vibe Indicator 信号灯控制协议 v1JSONL完整指南【免费下载链接】esp-iot-solutionEspressif IoT Library. IoT Device Drivers, Documentations and Solutions.项目地址: https://gitcode.com/GitHub_Trending/es/esp-iot-solutionble_uart_vibe_indicator是 esp-iot-solution 仓库中面向vibe coding场景的 ESP-IDF 设备端示例开发板通过 ESP-BLE-UART 暴露一组或多组红 / 黄 / 绿信号灯上位机用换行分隔的 JSONJSONL下发query/control命令固件解析后驱动 GPIO 实现灭灯、亮灯、慢闪与快闪。本文以该示例的协议规范文档 json_format.md 为主体完整梳理 Signal Light Control Protocol v1 的报文信封、命令格式、错误码与源码级实现并给出基于 ESP-BLE-UART Bridge 的主机侧实测命令与预期结果帮助你快速接入自己的自动化脚本或 AI 编程工作流。一、协议总览基于 ESP-BLE-UART 的 JSONL 通道Signal Light Control Protocol v1 是一个极简的请求—响应协议运行在 ESP-BLE-UARTNUS / GATT透传通道之上线格式为Newline-delimited JSONJSONL每条请求必须以换行符\n结尾固件在ble_jsonl.c中按\n切分行见 ble_jsonl.c每条请求必须携带非空id字段设备收到一行完整请求后始终通过 TX characteristic 回发一行响应send_json_line统一在报文末尾补\n后经ble_uart_tx发送见 ble_jsonl.c一次典型会话为建立 BLE 连接 → 查询indicator_count→ 发送controlpayload可含一条或多条灯控命令。固件内部将light_id0 / 1 / 2 分别映射到每个指示灯组channel的红 / 黄 / 绿 GPIO该映射在 indicator.h 与 indicator.c 中实现gpio_for_light_id()按light_id从s_gpio_map[channel]中取出对应 GPIO 号。二、信封Envelope结构所有交互都包裹在统一的信封结构中方向与格式如下方向格式主机 → 设备{v:1,id:req-id,op:command,data:{...}}设备 → 主机成功{v:1,id:req-id,ok:true,data:{...}}设备 → 主机失败{v:1,id:req-id,ok:false,error:code,data:{...}}各字段说明字段说明v协议版本必须为1id非空请求 id。为空或缺失 → 返回id_not_specifiedop必须为commanddata命令负载对象从源码看信封校验逻辑集中在 ble_jsonl.c 的envelope_valid()v必须是数值且等于BLE_JSONL_PROTOCOL_VERSION宏定义为 1、op与id必须是非空字符串、data必须是对象任一条件不满足即判定信封非法。校验失败后固件会优先复用已解析出的id回发bad_request若连id都为空或缺失则回发id_not_specified见 ble_jsonl.c 的handle_line()。light_action枚举值含义0灭灯Off1亮灯On2慢闪约 1 Hz半周期由CONFIG_VIBE_INDICATOR_SLOW_BLINK_HALF_MS决定3快闪约 3 Hz半周期由CONFIG_VIBE_INDICATOR_FAST_BLINK_HALF_MS决定该枚举在 indicator.h 定义为indicator_light_action_tINDICATOR_LIGHT_ACTION_OFF 0、ON 1、SLOW_BLINK 2、FAST_BLINK 3与协议数值一一对应。三、查询指示灯数量Query indicator count请求{v:1,id:req-001,op:command,data:{cmd:query,type:indicator_count}}成功响应data{count:3}count直接取自 Kconfig 编译期配置CONFIG_VIBE_INDICATOR_CHANNEL_COUNT由 indicator.c 的indicator_get_channel_count()返回默认值为 3见 Kconfig.projbuild取值范围 1–8。源码中的分发路径handle_command()识别cmd query后交给handle_query_indicator_count()该函数进一步校验type必须为字符串且等于indicator_count否则返回unsupported_commandunknown query type见 ble_jsonl.c。这一“子命令 子类型”的二次校验是协议健壮性的关键设计。四、控制灯具Control lamps请求——payload携带一条或多条灯控命令{v:1,id:req-002,op:command,data:{cmd:control,payload:[{indicator_id:0,light_id:0,light_action:0},{indicator_id:1,light_id:2,light_action:2}]}}字段说明字段类型说明cmdstringcontrolpayloadarray非空灯控命令列表payload[].indicator_idint组 id取值范围0 .. count - 1payload[].light_idint0/1/2payload[].light_actionint0..3关键行为所有条目先整体校验全部通过后才执行任何 GPIO 变更即“先验证后执行”的原子性语义。成功时设备回显请求中的整个payload{v:1,id:req-002,ok:true,data:{payload:[{indicator_id:0,light_id:0,light_action:0},{indicator_id:1,light_id:2,light_action:2}]}}源码实现细节见 ble_jsonl.c先检查payload是否为非空数组否则返回invalid_parameterpayload must be a non-empty array单个请求的 payload 条目数上限为BLE_JSONL_MAX_PAYLOAD_ITEMS宏定义为 32超限返回invalid_parameterpayload too many items第一轮循环对每个条目调用parse_control_item()做字段存在性与取值范围校验任一失败立即返回invalid_parameter并附带具体message不修改任何灯状态第二轮循环才真正逐个调用indicator_set_light()应用 GPIO 输出并用cJSON_Duplicate深拷贝原始 payload 作为data.payload回显。indicator_set_light()在 indicator.c 中会先通过indicator_validate_light()复核防越界然后加互斥锁更新灯状态并立即调用apply_light_locked()刷新对应 GPIO 电平。五、错误码Error codes协议级错误error触发时机bad_json该行不是合法 JSONbad_request信封字段缺失或非法id_not_specifiedid为空或缺失unknown_opop不是command应用级错误error触发时机unsupported_commanddata.cmd未知或查询type未知invalid_parameterpayload非法或数值越界应用级错误响应可能携带data.message说明具体原因{v:1,id:req-002,ok:false,error:invalid_parameter,data:{message:light_id out of range, expected 0-2}}协议级错误在源码中的对应bad_json由cJSON_ParseWithLength失败触发见 ble_jsonl.cunknown_op在op ! command时触发ble_jsonl.c。应用级校验消息来自 indicator.c 的indicator_validate_light()真实字符串包括indicator_count is 0indicator_id out of rangelight_id out of range, expected 0-2unsupported light_action, expected 0-3payload item must be an objectpayload item missing indicator_id, light_id, or light_action前两条校验对应 ble_jsonl.c 中parse_control_item()的返回逻辑。协议文档中的light_id out of range, expected 0-2与源码完全一致可作为自动化测试的精确断言依据。六、接收端的 JSONL 解析实现理解协议行为还需要了解固件如何把 BLE 收到的字节流切分成行并排队处理见 ble_jsonl.cble_jsonl_rx_feed()是ble_uart_on_rx回调入口在 app_main.c 注册把原始 RX 数据按BLE_JSONL_RX_CHUNK_MAX512 字节分块送入深度为 8 的队列队列满时丢弃剩余数据并打印告警独立 worker 任务jsonl_worker_task栈 6144 字节、优先级 5从队列取块交给rx_feed()逐字节切行以\n为行终止符\r被忽略兼容 CRLF单行上限BLE_JSONL_RX_LINE_MAX2048 字节超长则丢弃该行并标记溢出、直到下一个\n才恢复协议 JSON 嵌套约 4 层示例的 sdkconfig.defaults 将CONFIG_CJSON_NESTING_LIMIT设为 32以降低 worker 任务上的解析/打印栈占用。这些约束意味着主机侧必须保证每条协议报文以\n结尾、单行不超过 2048 字节且不要向一个请求中塞入超过 32 条灯控命令。七、配置项与协议的对应关系协议中的count、闪烁频率直接挂钩 Kconfig 配置Kconfig.projbuild配置项默认值取值范围说明VIBE_INDICATOR_CHANNEL_COUNT31–8独立 R/Y/G 灯组数量即query indicator_count返回的countVIBE_INDICATOR_SLOW_BLINK_HALF_MS500 ms50–5000light_action2慢闪的 GPIO 翻转间隔约 1 HzVIBE_INDICATOR_FAST_BLINK_HALF_MS167 ms20–2000light_action3快闪的 GPIO 翻转间隔约 3 Hz同时决定共享闪烁定时器的 tick 周期VIBE_INDICATOR_DEVICE_NAME_PREFIXVibe-Indicator—广播名prefix-XXXXXXXX 为蓝牙 MAC 末两字节VIBE_INDICATOR_CHx_GPIO_{R,Y,G}-1-1–54各组红/黄/绿 GPIO-1表示未连接协议仍工作灯珠不动作闪烁的实现细节blink_timer_cb()以快闪半周期为 tick 创建周期定时器esp_timer见 indicator.c快闪灯每个 tick 翻转一次相位慢闪灯则按slow_blink_divisor() ceil(慢闪半周期 / 快闪半周期)分频翻转。只有存在闪烁中的灯时才刷新 GPIO节省中断开销。八、主机侧实测通过 ESP-BLE-UART Bridge 联调固件之外还需要在 PC 上运行 ESP-BLE-UART Bridge 的daemon它维持 BLE 连接、订阅通知把 JSON 命令经 GATT 转发给设备并回传响应。首次使用先安装依赖cd $IDF_PATH . ./export.sh python -m pip install -r tools/ble/ble_uart_bridge/requirements.txt将DEVICE_ID替换为list-devices或串口 monitor 日志中打印的 BLE 地址设备广播名形如Vibe-Indicator-XXXXcd $IDF_PATH/tools/ble/ble_uart_bridge python main.py connection-check DEVICE_ID python main.py daemon DEVICE_ID # 查询组数 python main.py daemon-send --op command \ --json {cmd:query,type:indicator_count} --timeout 5 # 控制单路灯 python main.py daemon-send --op command \ --json {cmd:control,payload:[{indicator_id:0,light_id:0,light_action:2}]} \ --timeout 5 # 批量控制 python main.py daemon-send --op command \ --json {cmd:control,payload:[{indicator_id:0,light_id:0,light_action:1},{indicator_id:0,light_id:1,light_action:0}]} \ --timeout 5预期结果步骤预期查询indicator_countok: truedata.count与 Kconfig 配置一致control单条ok: truedata.payload回显请求control批量所有条目生效回显payload与请求一致非法light_idok: falseerror: invalid_parameterdata.message有说明空idok: falseerror: id_not_specified九、工程结构与进一步阅读文件说明app_main.cNVS、indicator 与 JSONL 初始化BLE UART 安装/打开ble_jsonl.cJSONL 信封校验、query/control分发indicator.c单灯 GPIO 驱动、慢闪/快闪定时器Kconfig.projbuild组数、GPIO 映射、闪烁周期、设备名前缀json_format.md协议参考本文依据README.md / README_cn.md构建烧录、硬件接线与联调说明构建烧录可参考 README当前 IDF 版本中主要 bring-up 目标为 ESP32-H4 与 ESP32-H21preview 目标idf.py子命令需保留--preview参数BLE 以encrypted false运行便于调试灯珠要产生可见输出必须先通过idf.py menuconfig为所用开发板配置各组 GPIO默认-1表示未连接。把本协议接入脚本或 vibe coding 工作流时只需遵循“请求以\n结尾、带非空id、先query后control”三条规则即可把编码或任务进度映射为实时的红 / 黄 / 绿灯语反馈。【免费下载链接】esp-iot-solutionEspressif IoT Library. IoT Device Drivers, Documentations and Solutions.项目地址: https://gitcode.com/GitHub_Trending/es/esp-iot-solution创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考