From 562881cc6c16629de35972f9797ac3bb3ba9fa66 Mon Sep 17 00:00:00 2001 From: zhangzhen Date: Mon, 1 Jun 2026 09:38:11 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E6=B6=88=E6=81=AF=E9=98=9F?= =?UTF-8?q?=E5=88=97=E5=8F=8A=E9=87=8D=E8=BF=9E?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- manifest.json | 4 +- pages/start.vue | 12 +++--- utils/cmd.js | 111 ++++++++++++++++++++++++++++++++++++++++++------ 3 files changed, 106 insertions(+), 21 deletions(-) diff --git a/manifest.json b/manifest.json index e8ebc65..4da148d 100644 --- a/manifest.json +++ b/manifest.json @@ -2,8 +2,8 @@ "name" : "endoscope", "appid" : "__UNI__5A0A7D6", "description" : "", - "versionName" : "1.2.4", - "versionCode" : 113, + "versionName" : "1.2.5", + "versionCode" : 114, "transformPx" : false, /* 5+App特有相关 */ "app-plus" : { diff --git a/pages/start.vue b/pages/start.vue index 9bd6d6a..1f18d4a 100644 --- a/pages/start.vue +++ b/pages/start.vue @@ -190,7 +190,7 @@ export default { this.startRS485() this.startRS232() // 启动心跳检测 - this.startHeartbeat() + // this.startHeartbeat() } catch (e) { // console.log(e) uni.showToast({ @@ -377,11 +377,11 @@ export default { this.readData() // 串口打开成功后,重置重连计数器和时间戳 - this.reconnectCount = 0 - this.last485DataTime = Date.now() + // this.reconnectCount = 0 + // this.last485DataTime = Date.now() // 记录通信恢复日志 - this.addLog('485通信', '通信已恢复(重连成功)') + // this.addLog('485通信', '通信已恢复(重连成功)') } }, async startRS232() { @@ -526,9 +526,9 @@ export default { readData() { this.timer = setInterval(async () => { - cmd.getTemp() + await cmd.getTemp() await delay(1000) - cmd.getPressure() + await cmd.getPressure() }, 5000) }, async handle485HexData(hex) { diff --git a/utils/cmd.js b/utils/cmd.js index 3d62b46..d854cd4 100644 --- a/utils/cmd.js +++ b/utils/cmd.js @@ -16,8 +16,94 @@ // let RS232 = getApp().globalData.RS232 import store from '@/store/index.js' +// ========== RS485 优先级消息队列 START ========== +const PRIORITY = { + HIGH: 0, // 用户操作(开门/关门/控制指令) + LOW: 1, // 定时轮询(getTemp/getPressure) +} + +const rs485Queue = [] +let isRS485Sending = false +const RS485_SEND_DELAY = 200 // 每条指令间隔200ms,确保总线空闲 + +/** + * 将任务按优先级插入队列 + * 高优先级(0)插入到队列前面低优先级任务之前 + * 低优先级(1)追加到队列末尾 + */ +const enqueueTask = (task) => { + if (task.priority === PRIORITY.HIGH) { + let insertIndex = rs485Queue.findIndex(t => t.priority === PRIORITY.LOW) + if (insertIndex === -1) { + rs485Queue.push(task) + } else { + rs485Queue.splice(insertIndex, 0, task) + } + } else { + rs485Queue.push(task) + } +} + +const processRS485Queue = async () => { + if (isRS485Sending || rs485Queue.length === 0) { + return + } + isRS485Sending = true + const task = rs485Queue.shift() + try { + let RS485 = getApp().globalData.RS485 + if (!RS485) { + throw new Error('RS485 not initialized') + } + const result = RS485.sendDataString(task.cmd) + if (result && typeof result.then === 'function') { + await result + } + // 发送后延迟,确保总线空闲再发下一条 + await new Promise(r => setTimeout(r, RS485_SEND_DELAY)) + task.resolve() + } catch (error) { + console.error('RS485 send error:', error) + task.reject(error) + } finally { + isRS485Sending = false + processRS485Queue() + } +} + +/** + * 发送RS485指令(带优先级) + * @param {string} cmd - 十六进制指令字符串 + * @param {number} priority - 优先级,默认HIGH + * @returns {Promise} + */ +const enqueueRS485Send = (cmd, priority = PRIORITY.HIGH) => { + return new Promise((resolve, reject) => { + enqueueTask({ cmd, priority, resolve, reject }) + processRS485Queue() + }) +} + +/** + * 清空队列(重连时调用,拒绝所有待发送请求) + */ +const clearRS485Queue = () => { + while (rs485Queue.length > 0) { + const task = rs485Queue.shift() + task.reject(new Error('RS485队列已清空(重连中)')) + } +} + +/** + * 获取当前队列长度(调试用) + */ +const getRS485QueueSize = () => { + return rs485Queue.length +} +// ========== RS485 优先级消息队列 END ========== + export default { - // 开左门指令 (通过RS485站号03) + // 开左门指令 (通过RS485站号03) - 高优先级 // 中盛4路数字IO模块,功能码06(写单个保持寄存器) LeftDoor: async (status) => { // 左门开门: 03 06 00 00 00 01 49 E8 @@ -26,12 +112,10 @@ export default { store.state.relay.leftDoor = status // door状态 = leftDoor OR rightDoor (任一门打开则door为true) store.state.relay.door = store.state.relay.leftDoor || store.state.relay.rightDoor - let RS485 = getApp().globalData.RS485 - await RS485.sendDataString(cmd) - + await enqueueRS485Send(cmd, PRIORITY.HIGH) }, - // 开右门指令 (通过RS485站号03) + // 开右门指令 (通过RS485站号03) - 高优先级 // 中盛4路数字IO模块,功能码06(写单个保持寄存器) RightDoor: async (status) => { // 右门开门: 03 06 00 01 00 01 18 28 @@ -40,8 +124,7 @@ export default { store.state.relay.rightDoor = status // door状态 = leftDoor OR rightDoor (任一门打开则door为true) store.state.relay.door = store.state.relay.leftDoor || store.state.relay.rightDoor - let RS485 = getApp().globalData.RS485 - await RS485.sendDataString(cmd) + await enqueueRS485Send(cmd, PRIORITY.HIGH) }, // 开门关门控制 01 @@ -84,20 +167,22 @@ export default { let RS232 = getApp().globalData.RS232 await RS232.sendDataString(cmd); }, - // 获取温湿度 + // 获取温湿度(通过RS485站号02)- 低优先级 getTemp: () => { - let RS485 = getApp().globalData.RS485 let cmd = '020300000002C438'; - RS485.sendDataString(cmd); + return enqueueRS485Send(cmd, PRIORITY.LOW) }, - // 获取压差指令 + // 获取压差指令(通过RS485站号01)- 低优先级 getPressure: () => { - let RS485 = getApp().globalData.RS485 let cmd = '01030001000295CB' - RS485.sendDataString(cmd); + return enqueueRS485Send(cmd, PRIORITY.LOW) }, + // 导出队列管理方法 + clearRS485Queue, + getRS485QueueSize, + // 解析门卡数据,返回卡号 parse232dData: (hexString) => { // IC卡 20 01 00 08 04 00 00 00 0e 26 fe ab 8f 03