From 92165c914a104a7f1f853dc872b518376cb40f7f Mon Sep 17 00:00:00 2001 From: zhangzhen Date: Mon, 1 Jun 2026 15:51:12 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E9=98=9F=E5=88=97=E5=92=8C?= =?UTF-8?q?=E5=90=AF=E5=8A=A8=E9=87=8D=E8=BF=9E?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 3 +++ pages/start.vue | 65 +++++++++++++++++++++---------------------------- utils/cmd.js | 44 +++++++++++++++++++++++++++++++-- 3 files changed, 73 insertions(+), 39 deletions(-) diff --git a/.gitignore b/.gitignore index 49910bb..a99ea95 100644 --- a/.gitignore +++ b/.gitignore @@ -8,3 +8,6 @@ data/ .vscode/launch.json unpackage/ pnpm-lock.yaml +.vscode/ +.hbuilderx/ +.codegraph/ \ No newline at end of file diff --git a/pages/start.vue b/pages/start.vue index 1f18d4a..071cb51 100644 --- a/pages/start.vue +++ b/pages/start.vue @@ -129,9 +129,6 @@ export default { this.addLog('手动关门错误', error) } }) - - // 启动左门循环定时器 - // this.startLeftDoorCycle() }, onShow() { @@ -189,10 +186,9 @@ export default { try { this.startRS485() this.startRS232() - // 启动心跳检测 - // this.startHeartbeat() + } catch (e) { - // console.log(e) + uni.showToast({ title: '初始化串口失败', icon: 'error' @@ -376,13 +372,23 @@ export default { clearInterval(this.timer) this.readData() + // 启动心跳检测 + this.startHeartbeat() + // 串口打开成功后,重置重连计数器和时间戳 - // this.reconnectCount = 0 - // this.last485DataTime = Date.now() + this.reconnectCount = 0 + this.last485DataTime = Date.now() // 记录通信恢复日志 // this.addLog('485通信', '通信已恢复(重连成功)') - } + } else { + // 确保心跳是关闭的 + this.stopHeartbeatIfNeeded() + uni.showToast({ + title: '485打开失败', + icon: 'error' + }) + } }, async startRS232() { // 获取本地串口存储端口 @@ -413,6 +419,8 @@ export default { } }, stopRS485() { + // 停止心跳检测 + this.stopHeartbeatIfNeeded() this.addLog('485通信', '串口关闭') this.RS485.stopReadPortData() this.RS485.close() @@ -430,7 +438,6 @@ export default { clearInterval(this.heartbeatTimer) this.heartbeatTimer = null } - // 记录日志 this.addLog('485通信', '心跳检测已启动') @@ -439,6 +446,17 @@ export default { this.check485Heartbeat() }, 10000) }, + // 停止心跳检测(安全方法,如果没运行也不会报错) + stopHeartbeatIfNeeded() { + if (!this.heartbeatTimer) { + // 心跳未运行 + return + } + + clearInterval(this.heartbeatTimer) + this.heartbeatTimer = null + this.addLog('485通信', '心跳检测已停止') + }, // 检测485数据心跳,如果超时则触发重连 check485Heartbeat() { @@ -507,12 +525,6 @@ export default { // 5. 重新启动RS485通信 this.startRS485() - // 6. 延迟后重新启动心跳检测(等待RS485初始化完成) - await delay(3000) - this.startHeartbeat() - - this.addLog('485通信', '监听已重置(第' + this.reconnectCount + '次)') - } catch (error) { this.addLog('485通信错误', error.message || '重置失败') @@ -966,27 +978,6 @@ export default { } } }, - - /** - * 左门循环开关(调试用,独立定时器) - * 每5秒切换一次左门状态 - */ - startLeftDoorCycle() { - clearInterval(this.leftDoorCycleTimer) - let isOpen = false - this.leftDoorCycleTimer = setInterval(async () => { - try { - if (isOpen) { - cmd.LeftDoor(false) - } else { - cmd.LeftDoor(true) - } - isOpen = !isOpen - } catch (error) { - this.addLog('左门循环错误', error.message || error) - } - }, 5000) - }, } } diff --git a/utils/cmd.js b/utils/cmd.js index d854cd4..f109941 100644 --- a/utils/cmd.js +++ b/utils/cmd.js @@ -25,13 +25,50 @@ const PRIORITY = { const rs485Queue = [] let isRS485Sending = false const RS485_SEND_DELAY = 200 // 每条指令间隔200ms,确保总线空闲 +const MAX_QUEUE_SIZE = 3 // 队列最大长度 /** * 将任务按优先级插入队列 - * 高优先级(0)插入到队列前面低优先级任务之前 - * 低优先级(1)追加到队列末尾 + * 规则: + * 1. 队列最大长度为3 + * 2. 重复指令(相同cmd)不入队,直接丢弃 + * 3. 队列满时,高优先级任务挤掉低优先级任务,否则踢掉最老的(队首) */ const enqueueTask = (task) => { + // 规则1: 去重 - 已存在相同cmd的任务则丢弃 + const isDuplicate = rs485Queue.some(t => t.cmd === task.cmd) + if (isDuplicate) { + console.warn('[RS485队列] 丢弃重复任务:', task.cmd) + return false + } + + // 规则2: 队列满了,先腾位置 + if (rs485Queue.length >= MAX_QUEUE_SIZE) { + if (task.priority === PRIORITY.HIGH) { + // 高优先级:优先挤掉队列中最后一个低优先级任务 + let lastLowIndex = -1 + for (let i = rs485Queue.length - 1; i >= 0; i--) { + if (rs485Queue[i].priority === PRIORITY.LOW) { + lastLowIndex = i + break + } + } + if (lastLowIndex !== -1) { + console.warn('[RS485队列] 高优挤掉低优:', rs485Queue[lastLowIndex].cmd) + rs485Queue.splice(lastLowIndex, 1) + } else { + // 没有低优先级可挤,踢掉队首最老的 + console.warn('[RS485队列] 满,踢掉队首:', rs485Queue[0].cmd) + rs485Queue.shift() + } + } else { + // 低优先级:直接踢掉队首最老的 + console.warn('[RS485队列] 满,踢掉队首:', rs485Queue[0].cmd) + rs485Queue.shift() + } + } + + // 规则3: 按优先级插入 if (task.priority === PRIORITY.HIGH) { let insertIndex = rs485Queue.findIndex(t => t.priority === PRIORITY.LOW) if (insertIndex === -1) { @@ -42,6 +79,9 @@ const enqueueTask = (task) => { } else { rs485Queue.push(task) } + + console.log(`[RS485队列] 入队成功, 长度:${rs485Queue.length}, cmd:${task.cmd}`) + return true } const processRS485Queue = async () => {