You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Ubuntu 22.04下Golang如何主动检查串口条码扫描器连接状态?

串口条码扫描器连接状态主动检查方案(Golang + go-serial)

问题背景

我正在Ubuntu 22.04机器上开发一个通过串口读取条码扫描器数据的解决方案。当前使用Honeywell 1911i扫描器(RS232接口,后续计划支持其他扫描器),并采用go-serial库读取串口数据。目前仅通过等待一段时间内是否有扫描数据传入来判断连接状态,但这种方式无法满足需求,希望在不依赖扫描动作的前提下主动检查扫描器是否正确连接、串口数据传输是否正常。

解决方案

1. 检查串口端口的存在性与权限

先确认目标串口设备(比如/dev/ttyUSB0或/dev/ttyS0)是否存在,同时验证进程是否拥有读写权限,避免把权限问题误判为设备未连接:

import "os"

func checkPortValid(port string) bool {
    // 检查设备文件是否存在
    _, err := os.Stat(port)
    if err != nil {
        return false
    }
    // 尝试以读写方式打开,验证权限
    file, err := os.OpenFile(port, os.O_RDWR, 0666)
    if err != nil {
        return false
    }
    defer file.Close()
    return true
}

2. 利用RS232硬件握手信号检测设备在线

Honeywell 1911i支持硬件握手,通过读取DSR(数据准备就绪)信号可判断扫描器是否通电就绪,用go-serial的GetModemStatus()方法即可获取状态位:

import "github.com/bugst/go-serial/v2"

func checkHandshakeStatus(port string) bool {
    // 配置需与扫描器参数匹配,Honeywell 1911i默认一般为9600波特率、8数据位、无校验、1停止位
    portConfig := &serial.Mode{
        BaudRate: 9600,
        DataBits: 8,
        Parity:   serial.NoParity,
        StopBits: serial.OneStopBit,
    }
    dev, err := serial.Open(port, portConfig)
    if err != nil {
        return false
    }
    defer dev.Close()

    status, err := dev.GetModemStatus()
    if err != nil {
        return false
    }
    // DSR信号有效说明设备已准备好通信
    return status&serial.DSR != 0
}

3. 发送设备专属查询指令验证通信链路

Honeywell扫描器支持标准串口指令,比如发送ENQ(ASCII 0x05),正常连接时会返回ACK(ASCII 0x06),通过这个交互可确认通信链路正常:

import "time"

func checkCommandResponse(port string) bool {
    portConfig := &serial.Mode{
        BaudRate: 9600,
        DataBits: 8,
        Parity:   serial.NoParity,
        StopBits: serial.OneStopBit,
    }
    dev, err := serial.Open(port, portConfig)
    if err != nil {
        return false
    }
    defer dev.Close()

    // 发送查询指令ENQ
    _, err = dev.Write([]byte{0x05})
    if err != nil {
        return false
    }

    // 设置500ms超时读取响应
    dev.SetReadTimeout(500 * time.Millisecond)
    buf := make([]byte, 1)
    n, err := dev.Read(buf)
    // 确认读取到1字节且为ACK响应
    if err != nil || n != 1 || buf[0] != 0x06 {
        return false
    }
    return true
}

4. 组合所有检查步骤

将上述三个步骤串联,形成完整的主动检测逻辑:

func isScannerConnected(port string) bool {
    if !checkPortValid(port) {
        return false
    }
    if !checkHandshakeStatus(port) {
        return false
    }
    if !checkCommandResponse(port) {
        return false
    }
    return true
}

内容的提问来源于stack exchange,提问作者Matt B.

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.20 20:55:12