修复一下问题:

A用户绑定IPC和门夹弹力绳,分享给B用户;
A用户先进入门夹弹力绳页面,已唤醒玩具,B用户再进入页面
A用户退出页面下发休眠指令,B用户操作玩具,未提示操作成功/失败
This commit is contained in:
2026-09-10 11:43:33 +08:00
parent 026d6d5da7
commit 5875d2a339
5 changed files with 155 additions and 45 deletions
+40 -9
View File
@@ -2,8 +2,8 @@
* @file app_function.c * @file app_function.c
* @brief 设备功能开关 + 自动玩法 + 手动点动 + 按键动作实现 * @brief 设备功能开关 + 自动玩法 + 手动点动 + 按键动作实现
* @author cyWu <1917507415@qq.com> * @author cyWu <1917507415@qq.com>
* @date 2026.08.26 * @date 2026.09.10
* @version V1.1.0 * @version V1.2.0
* @history * @history
* - V1.0.0, 2026.08.25, cyWu, 首次发布,实现 DP0 开关、自动玩法、手动点动与按键动作 * - V1.0.0, 2026.08.25, cyWu, 首次发布,实现 DP0 开关、自动玩法、手动点动与按键动作
* - V1.1.0, 2026.08.26, cyWu, 切模式闪灯改到 function_play_mode_apply 统一 * - V1.1.0, 2026.08.26, cyWu, 切模式闪灯改到 function_play_mode_apply 统一
@@ -11,6 +11,8 @@
* 启动也补上闪灯;DP2 停转(cmd=3)改边沿触发, * 启动也补上闪灯;DP2 停转(cmd=3)改边沿触发,
* 避免残留的 03 一直把刚启动的自动模式打断; * 避免残留的 03 一直把刚启动的自动模式打断;
* 自动模式新增单次最长运行时长,到点回待机 * 自动模式新增单次最长运行时长,到点回待机
* - V1.2.0, 2026.09.10, cyWu, 软关后 APP 下发其它控制指令也可唤醒,
* 唤醒后本拍继续执行该指令(玩法/点动)
******************************************************************************/ ******************************************************************************/
#include "app_function.h" #include "app_function.h"
@@ -39,11 +41,13 @@ typedef struct {
uint16_t hand_ms; uint16_t hand_ms;
volatile uint8_t hand_write_pending; /**< DP2 刚写入(03 停转要靠事件) */ volatile uint8_t hand_write_pending; /**< DP2 刚写入(03 停转要靠事件) */
volatile uint8_t hand_write_cmd; volatile uint8_t hand_write_cmd;
volatile uint8_t app_cmd_wake; /**< 软关后收到其它 APP 控制 DP */
} AppFunctionCtx_t; } AppFunctionCtx_t;
static AppFunctionCtx_t s_func; static AppFunctionCtx_t s_func;
static void function_hand_stop(void); static void function_hand_stop(void);
static void function_app_power_on(const char *reason);
static void function_play_mode_apply(uint8_t mode); static void function_play_mode_apply(uint8_t mode);
static void function_play_mode_poll(void); static void function_play_mode_poll(void);
static void function_play_mode_timeout(uint16_t dt); static void function_play_mode_timeout(uint16_t dt);
@@ -70,18 +74,45 @@ void app_function_dp_hand_write(uint8_t cmd)
s_func.hand_write_pending = 1; s_func.hand_write_pending = 1;
} }
/**
* @brief APP 下发了非关机控制 DP,软关时下一拍唤醒
* @return 无
*/
void app_function_on_app_cmd(void)
{
s_func.app_cmd_wake = 1;
}
/**
* @brief APP 侧开机:功能开、同步 DP0、挂开机绿灯
* @param reason 日志原因(英文)
* @return 无
*/
static void function_app_power_on(const char *reason)
{
s_func.app_power = 1;
gDevData.power = 1;
app_led_hint_power_on();
log_info("%s\n", reason);
}
/** /**
* @brief 跟随 APP 下发的 DP0/DP1,并处理 DP2 手动点动 * @brief 跟随 APP 下发的 DP0/DP1,并处理 DP2 手动点动
* @return 无 * @return 无
*/ */
void app_function_poll(void) void app_function_poll(void)
{ {
/* DP0:APP 下发开关。充电中 / 正在关机时不跟,避免和 USB 软关抢状态 */ uint8_t cmd_wake = s_func.app_cmd_wake;
s_func.app_cmd_wake = 0;
/* DP0:APP 下发开关。充电中 / 正在关机时不跟,避免和 USB 软关抢状态。
* 已软关时,后续其它控制 DP 也当开机,本拍接着跑玩法/点动。 */
if (!app_power_usb_online() && !app_power_poweroff_pending()) { if (!app_power_usb_online() && !app_power_poweroff_pending()) {
if (gDevData.power && !s_func.app_power) { if (!s_func.app_power && cmd_wake) {
s_func.app_power = 1; function_app_power_on("APP cmd wake from soft off");
app_led_hint_power_on(); } else if (gDevData.power && !s_func.app_power) {
log_info("APP power on\n"); function_app_power_on("APP power on");
} else if (!gDevData.power && s_func.app_power) { } else if (!gDevData.power && s_func.app_power) {
app_function_soft_off(); app_function_soft_off();
} }
@@ -133,7 +164,7 @@ void app_function_stop_all(void)
} }
/** /**
* @brief 软关:电机停、DP0=0,等 APP/短按再开。不断 BLE * @brief 软关:电机停、DP0=0,等 APP 开机/其它指令/短按再开。不断 BLE
* @return 无 * @return 无
*/ */
void app_function_soft_off(void) void app_function_soft_off(void)
@@ -145,7 +176,7 @@ void app_function_soft_off(void)
gDevData.play_mode = 0; gDevData.play_mode = 0;
app_mode_stop(); app_mode_stop();
function_hand_stop(); function_hand_stop();
log_info("soft off, wait APP power on\n"); log_info("soft off, wait APP cmd or key\n");
} }
/** /**
+11 -3
View File
@@ -2,10 +2,11 @@
* @file app_function.h * @file app_function.h
* @brief 设备功能开关(DP0)+ 自动玩法(DP1)+ 手动点动(DP2)+ 按键动作 * @brief 设备功能开关(DP0)+ 自动玩法(DP1)+ 手动点动(DP2)+ 按键动作
* @author cyWu <1917507415@qq.com> * @author cyWu <1917507415@qq.com>
* @date 2026.08.25 * @date 2026.09.10
* @version V1.0.0 * @version V1.2.0
* @history * @history
* - V1.0.0, 2026.08.25, cyWu, 首次发布,实现 DP0 开关、自动玩法、手动点动与按键动作 * - V1.0.0, 2026.08.25, cyWu, 首次发布,实现 DP0 开关、自动玩法、手动点动与按键动作
* - V1.2.0, 2026.09.10, cyWu, 软关后 APP 下发其它控制 DP 也可唤醒功能
* *
* @note 本模块决定“电机现在该不该转、转哪种”,会读 app_power/app_pair 的 * @note 本模块决定“电机现在该不该转、转哪种”,会读 app_power/app_pair 的
* 状态作为阻塞条件(充电中/深睡中/配对中都不能转),也会触发 * 状态作为阻塞条件(充电中/深睡中/配对中都不能转),也会触发
@@ -30,6 +31,13 @@ void app_function_init(void);
*/ */
void app_function_dp_hand_write(uint8_t cmd); void app_function_dp_hand_write(uint8_t cmd);
/**
* @brief APP 下发了非关机控制 DP(玩法/点动等),软关时下一拍唤醒功能
* @note 与关机 DP 同一帧到达时不要调用,避免关完立刻被同包其它 DP 拉开
* @return 无
*/
void app_function_on_app_cmd(void);
/** /**
* @brief 跟随 APP 下发的 DP0/DP1,并处理 DP2 手动点动,每个业务 tick 调用一次 * @brief 跟随 APP 下发的 DP0/DP1,并处理 DP2 手动点动,每个业务 tick 调用一次
* @return 无 * @return 无
@@ -50,7 +58,7 @@ void app_function_tick_1ms(uint16_t dt);
void app_function_stop_all(void); void app_function_stop_all(void);
/** /**
* @brief 软关:电机停、DP0=0,等 APP/短按再开(USB 拔出 / APP 关时用) * @brief 软关:电机停、DP0=0,等 APP 开机/其它指令/短按再开(USB 拔出 / APP 关时用)
* @return 无 * @return 无
*/ */
void app_function_soft_off(void); void app_function_soft_off(void);
+19
View File
@@ -69,6 +69,9 @@ void userHandle(void)
* ════════════════════════════════════════════════════════════════ */ * ════════════════════════════════════════════════════════════════ */
int8_t jbEventProcess(jb_event_info_t *info, jb_data_point_t *ctrl) int8_t jbEventProcess(jb_event_info_t *info, jb_data_point_t *ctrl)
{ {
uint8_t other_cmd = 0;
uint8_t got_power_off = 0;
if (!info || !ctrl) if (!info || !ctrl)
{ {
return -1; return -1;
@@ -89,6 +92,7 @@ int8_t jbEventProcess(jb_event_info_t *info, jb_data_point_t *ctrl)
else else
{ {
gDevData.power = 0; gDevData.power = 0;
got_power_off = 1;
// TODO: 关 — 执行动作 // TODO: 关 — 执行动作
} }
break; break;
@@ -96,6 +100,7 @@ int8_t jbEventProcess(jb_event_info_t *info, jb_data_point_t *ctrl)
/* ── DP1 自动模式 (enum) ── */ /* ── DP1 自动模式 (enum) ── */
case DP_ID_PLAY_MODE: case DP_ID_PLAY_MODE:
gDevData.play_mode = ctrl->play_mode; gDevData.play_mode = ctrl->play_mode;
other_cmd = 1;
switch (ctrl->play_mode) switch (ctrl->play_mode)
{ {
case PLAY_MODE_0: /* 停止复位 */ case PLAY_MODE_0: /* 停止复位 */
@@ -127,6 +132,7 @@ int8_t jbEventProcess(jb_event_info_t *info, jb_data_point_t *ctrl)
/* ── DP2 手动模式 (raw) ── */ /* ── DP2 手动模式 (raw) ── */
case DP_ID_HAND_MODE: case DP_ID_HAND_MODE:
memcpy(gDevData.hand_mode, ctrl->hand_mode, 2); memcpy(gDevData.hand_mode, ctrl->hand_mode, 2);
other_cmd = 1;
/* 薄适配:通知业务层;03=停,00=空闲 */ /* 薄适配:通知业务层;03=停,00=空闲 */
{ {
extern void usr_dp_hand_write(uint8_t cmd); extern void usr_dp_hand_write(uint8_t cmd);
@@ -136,6 +142,7 @@ int8_t jbEventProcess(jb_event_info_t *info, jb_data_point_t *ctrl)
/* ── DP3 绳索校准 (bool) ── */ /* ── DP3 绳索校准 (bool) ── */
case DP_ID_CALIBRATION: case DP_ID_CALIBRATION:
other_cmd = 1;
if (ctrl->calibration) if (ctrl->calibration)
{ {
gDevData.calibration = 1; gDevData.calibration = 1;
@@ -151,30 +158,35 @@ int8_t jbEventProcess(jb_event_info_t *info, jb_data_point_t *ctrl)
/* ── DP4 绳索圈数 (uint8) ── */ /* ── DP4 绳索圈数 (uint8) ── */
case DP_ID_NUMBERTURNS: case DP_ID_NUMBERTURNS:
gDevData.numberturns = ctrl->numberturns; gDevData.numberturns = ctrl->numberturns;
other_cmd = 1;
// TODO: 根据 ctrl->numberturns 执行动作 // TODO: 根据 ctrl->numberturns 执行动作
break; break;
/* ── DP8 勿扰模式开关 (raw) ── */ /* ── DP8 勿扰模式开关 (raw) ── */
case DP_ID_NO_DISTURB_ENABLE: case DP_ID_NO_DISTURB_ENABLE:
memcpy(gDevData.no_disturb_enable, ctrl->no_disturb_enable, 13); memcpy(gDevData.no_disturb_enable, ctrl->no_disturb_enable, 13);
other_cmd = 1;
// TODO: 根据 gDevData.no_disturb_enable 执行动作 (长度 13 字节) // TODO: 根据 gDevData.no_disturb_enable 执行动作 (长度 13 字节)
break; break;
/* ── DP9 预留DP1 (uint32) ── */ /* ── DP9 预留DP1 (uint32) ── */
case DP_ID_RESERVA_DP1: case DP_ID_RESERVA_DP1:
gDevData.reserva_dp1 = ctrl->reserva_dp1; gDevData.reserva_dp1 = ctrl->reserva_dp1;
other_cmd = 1;
// TODO: 根据 ctrl->reserva_dp1 执行动作 // TODO: 根据 ctrl->reserva_dp1 执行动作
break; break;
/* ── DP10 预留DP2 (uint32) ── */ /* ── DP10 预留DP2 (uint32) ── */
case DP_ID_RESERVA_DP2: case DP_ID_RESERVA_DP2:
gDevData.reserva_dp2 = ctrl->reserva_dp2; gDevData.reserva_dp2 = ctrl->reserva_dp2;
other_cmd = 1;
// TODO: 根据 ctrl->reserva_dp2 执行动作 // TODO: 根据 ctrl->reserva_dp2 执行动作
break; break;
/* ── DP11 预留DP3 (uint32) ── */ /* ── DP11 预留DP3 (uint32) ── */
case DP_ID_RESERVA_DP3: case DP_ID_RESERVA_DP3:
gDevData.reserva_dp3 = ctrl->reserva_dp3; gDevData.reserva_dp3 = ctrl->reserva_dp3;
other_cmd = 1;
// TODO: 根据 ctrl->reserva_dp3 执行动作 // TODO: 根据 ctrl->reserva_dp3 执行动作
break; break;
@@ -182,6 +194,13 @@ int8_t jbEventProcess(jb_event_info_t *info, jb_data_point_t *ctrl)
break; break;
} }
} }
/* 软关后其它控制 DP 可唤醒;与关机 DP 同帧则关机优先,避免关完立刻被拉开 */
if (other_cmd && !got_power_off)
{
extern void usr_dp_app_cmd(void);
usr_dp_app_cmd();
}
return 0; return 0;
} }
+9
View File
@@ -306,6 +306,15 @@ void usr_dp_hand_write(uint8_t cmd)
app_function_dp_hand_write(cmd); app_function_dp_hand_write(cmd);
} }
/**
* @brief APP 下发了非关机控制 DPjb_product 薄适配)
* @return 无
*/
void usr_dp_app_cmd(void)
{
app_function_on_app_cmd();
}
/** /**
* @brief BLE 收到见宝载荷,送入协议环形缓冲 * @brief BLE 收到见宝载荷,送入协议环形缓冲
* @param data 载荷指针 * @param data 载荷指针
+76 -33
View File
@@ -1,11 +1,12 @@
# 门夹弹力绳 需求文档(V1.1 # 门夹弹力绳 需求文档(V1.3
| 项目 | 内容 | | 项目 | 内容 |
| --- | --- | | --- | --- |
| 产品名称 | 门夹弹力绳(智能逗宠玩具) | | 产品名称 | 门夹弹力绳(智能逗宠玩具) |
| 型号 | PICBC2 / CBC2 | | 型号 | PICBC2 / CBC2 |
| 主控 | 杰理 AC7016C | | 主控 | 杰理 AC7016C |
| 日期 | 2026-08-25 | | 日期 | 2026-09-10 |
| 修订 | V1.3:App 软关后,再下发其它控制指令也可退出关机 |
--- ---
@@ -13,26 +14,39 @@
门夹弹力绳是一款智能逗宠玩具。设备夹在门板上,内部电机带动弹力绳收放,让绳端玩具按不同"玩法"动起来逗宠物玩。支持手机 App 通过远程控制,也支持按键本地操作。 门夹弹力绳是一款智能逗宠玩具。设备夹在门板上,内部电机带动弹力绳收放,让绳端玩具按不同"玩法"动起来逗宠物玩。支持手机 App 通过远程控制,也支持按键本地操作。
硬件:红绿双指示灯(低电平亮)+ 单按键(低电平按下)。
--- ---
## 2. 核心功能 ## 2. 核心功能
### 2.1 开关机 ### 2.1 开关机
| 操作 | 行为 | | 操作 | 行为 | 灯效 |
| --- | --- | | --- | --- | --- |
| 深睡状态下按 3 秒 | 开机 | | 刚上电没按按键、也没插充电线 | 保持深睡,不误开机 | 灭 |
| 深睡状态下按 5 秒 | 开机并进入配对模式 | | 插着充电线时上电 | 自动开机,跳过按键判定 | 进正常灯效 |
| 开机状态下按 3 秒 | 关机(深睡省电) | | 深睡状态下按**3 秒** 后松手 | 开机 | 满 3 秒时绿灯常亮 |
| 插着充电线时上电 | 自动开机,不用按键 | | 深睡状态下按住 **5 秒** 后松手 | 开机并进入配对(清配对信息) | 满 5 秒切成绿灯快闪 |
| 刚上电没按按键 | 保持深睡,不误开机 | | 深睡状态下按住 **12 秒** | 开机并进入 OTA(不等松手) | 随后红绿交替闪 |
| 深睡状态下电量过低(约 ≤5%)且未充电 | 拒绝开机,红闪 5 下后继续深睡 | 红 200ms 亮/灭 ×5 |
| 开机状态下按住 **3 秒** | 关机(深睡省电) | 立刻灭灯 |
- 深睡状态下,按按键(3 秒/5 秒)或插充电线均可唤醒开机。 补充说明:
- 深睡唤醒:按按键(3 秒开机 / 5 秒配对 / 12 秒 OTA)或插充电线均可开机。
- 满 5 秒只是「武装配对 + 快闪提示」,真正提交配对在 **松手** 那一刻。如果继续按到 12 秒,改道进 OTA,不再进配对。
- 开机判定时如果手还按着,会锁住按键,松开后才认短按/长按,避免刚开机立刻关机。
### 2.2 开关(App 控制) ### 2.2 开关(App 控制)
- App 可开/关设备功能;关闭后电机停转,蓝牙不断开,可随时再开。 - App 可开/关设备功能;关闭后电机停转,蓝牙不断开,可随时再开。
- 功能关闭后,以下操作都会退出软关并恢复功能:
- App 下发开机 DP
- App 再下发其它控制指令(自动玩法、手动点动等),并按该指令继续执行
- 短按按键:只唤醒功能,**不切玩法**
- 拔掉充电线会自动进入低功耗状态(电机停转、LED 关闭、蓝牙保持连接)。 - 拔掉充电线会自动进入低功耗状态(电机停转、LED 关闭、蓝牙保持连接)。
- 充电中、正在深睡关机:其它指令不会把功能拉开。
### 2.3 自动玩法(6 种,App 或按键选择) ### 2.3 自动玩法(6 种,App 或按键选择)
@@ -48,46 +62,74 @@
- 玩法会循环播放,直到切换或停止。 - 玩法会循环播放,直到切换或停止。
- 运行中可随时切换到其他玩法或停止。 - 运行中可随时切换到其他玩法或停止。
- 单次最长运行 **10 分钟**,到点自动停转回待机(保护性超时,不闪灯,避免误以为被按到)。
- 充电中、配对中、正在深睡关机:不允许跑自动玩法,强制回到停转。
- 功能关闭时若 App 下发玩法/点动:先退出软关,再按该指令执行。
### 2.4 手动控制(App 控制) ### 2.4 手动控制(App 控制)
- App 可手动点动:控制电机**收绳**或**放绳**,松手/点停止后电机停止。 - App 可手动点动:控制电机**收绳**或**放绳**,松手/点停止后电机停止。
- 手动控制进行中,自动玩法暂停。 - 手动控制进行中,自动玩法暂停。
- 从自动/空闲切到手动时,绿灯闪两下提示。
- 手动点动进行中,短按按键无效,避免打断收放绳。
- 选中自动玩法会先停手动,再进入自动模式。
### 2.5 按键控制 ### 2.5 按键控制
| 操作 | 行为 | 开机后只有一颗按键,短按/长按含义如下:
| --- | --- |
| 短按(<1 秒) | 切换玩法:停 → 玩法1 → 玩法2 → … → 玩法6 → 停,循环 | | 操作 | 条件 | 行为 |
| 长按 3 秒 | 关机 | | --- | --- | --- |
| 充电中 / 配对中 | 按键无效 | | 短按(松开且未到 3 秒) | 功能开、空闲 | 切换玩法:停 → 玩法1 → … → 玩法6 → 停,循环;绿灯闪两下 |
| 短按 | 功能已关(App 软关 / 拔充电线后) | 只唤醒功能,不切玩法;挂待机绿灯 |
| 短按 | 手动点动进行中 | 无效 |
| 长按 3 秒 | 功能开 | 关机进深睡 |
| 短按 / 长按 | 充电中 / 配对中 / 正在关机 | 无效 |
### 2.6 电量与充电 ### 2.6 电量与充电
- 电量按电压换算:满电 4.2V = 100%3.2V = 0%,电量自动上报 App 显示。 - 电量按电压换算:满电 4.12V = 100%3.2V = 0%,电量自动上报 App 显示。充电内阻压降下,充满基准按 4.2V 计。
- **低电量**(电池电压低于 **3.7V**):App 上报警告,指示灯红灯慢闪;持续 1 分钟未充电则自动关机保护电池 - **低电量**(电池电压低于 **3.7V**):App 上报警告,指示灯红灯慢闪。只提示、不关机;电压回升超过 3.75V 后退出低电
- **电量极低**(低于 3.2V):直接自动关机 - **空电关机**(显示电量 ≤ **5%**):立刻停电机,红灯闪 5 下后自动关机保护电池。充电中不判定
- **插入充电线**:电机立即停止、进入充电状态,只有红灯常亮,表示充电中,充满转绿灯常亮;充电期间不执行玩法,按键无效 - **开机电量过低**(未充电且裸电压约 ≤ 3.25V,对应约 5%):拒绝开机,红闪 5 下后继续深睡
- **充电中拔掉充电线**:设备自动进入低功耗状态(电机停转、LED关闭、蓝牙保持连接),需按短按按键或 App 重新开启后才能使用 - 开机后约 3 秒内不因低电/空电关机,避免上电瞬间误判
- 电池:锂电池,USB 5V 充电,充满自动转灯 - **插入充电线**:电机立即停止、进入充电状态,红灯常亮表示充电,充满转绿灯常亮;充电期间不执行玩法,按键无效。功能关掉时充电灯仍继续亮
- **充电中拔掉充电线**:设备自动进入低功耗状态(电机停转、LED 关闭、蓝牙保持连接),需短按按键或 App 重新开启后才能使用。
- 电池:锂电池,USB 5V 充电,充满自动转灯;硬件判定充满后电量强制收尾到 100%。
### 2.7 指示灯 ### 2.7 指示灯
| 状态 | 灯效 | 红绿双灯,通道独立,可以同时亮。充电灯和功能开关无关。
| --- | --- |
| 正常待机 | 绿灯常亮 | | 状态 | 灯效 | 节奏 |
| 充电中 | 红灯常亮 | | --- | --- | --- |
| 充满 | 绿灯常亮 | | 正常待机(功能开、没充电) | 绿灯常亮 | 一直亮 |
| 低电量 | 红灯慢闪 | | 充电中 | 红灯常亮 | 一直亮 |
| 配对中 | 绿灯快闪 | | 充满 | 绿灯常亮 | 一直亮 |
| 配对成功 | 绿灯常亮 3 秒 | | 低电量(功能开、没接电) | 红灯慢闪 | 亮 200ms / 周期 2s |
| 配对失败 | 红绿交替闪 3 秒 | | 配对 | 绿灯快闪 | 100ms 亮 / 100ms 灭 |
| 按键切玩法 | 绿灯闪两下 | | 配对成功 | 绿灯常亮 3 秒 | 一次性 |
| 配对失败 | 红绿交替 3 秒 | 200ms 半周期 |
| 切玩法 / 切手动 | 绿灯闪两下 | 150ms 灭 + 150ms 亮 ×2 |
| OTA | 红绿交替,独占全部灯 | 200ms 半周期,一直闪到升级结束/复位 |
| 运行中空电关机 | 关绿灯,红灯闪 5 下再掉电 | 200ms 亮/灭 ×5 |
| 开机电量过低被拒 | 红灯闪 5 下后继续深睡 | 同上 |
优先级(高的盖住低的):
1. OTA / 空电关机红闪 / 切模式绿闪
2. 配对快闪、配对成功、配对失败
3. 充电红 / 充满绿 / 低电红闪
4. 待机绿灯(最低)
OTA 和空电关机会清掉其它灯,只跑自己那一种。功能关掉时,待机/配对/切模式/低电灯会清掉,**充电灯保留**。
### 2.8 配对 ### 2.8 配对
- 首次使用:深睡状态长按 5 秒开机并进入配对,App 扫码连接即可。 - 首次使用:深睡状态长按 5 秒后松手,开机并进入配对,App 扫码连接即可。
- 配对窗口 120:期间连接成功绿灯 3 秒;超时未连接保持开机,可重新配对。 - 按满 5 秒绿灯先切到配对快闪;若继续按到 12 秒则改道 OTA,不再提交配对。
- 配对窗口 120 秒:期间连接成功绿灯常亮 3 秒;超时未连接红绿交替 3 秒,之后保持开机,可重新配对。
- 配对期间不跑玩法、按键无效。
- App 可解绑设备,解绑后设备清除配对信息,重新配对即可再次使用。 - App 可解绑设备,解绑后设备清除配对信息,重新配对即可再次使用。
### 2.9 时间同步 ### 2.9 时间同步
@@ -97,6 +139,7 @@
### 2.10 固件升级(OTA ### 2.10 固件升级(OTA
- 支持 App 远程升级固件,升级协议已打通。 - 支持 App 远程升级固件,升级协议已打通。
- 本地入口:深睡状态按住 12 秒,开机并进入 OTA 广播,红绿交替闪。
- 当前版本:固件 V1.0.0、硬件 V1.0.0。 - 当前版本:固件 V1.0.0、硬件 V1.0.0。
- 实际升级流程(写入芯片、校验、版本判断)待开发。 - 实际升级流程(写入芯片、校验、版本判断)待开发。