有没有办法查看蓝牙 SPP 扫描仪是否进入睡眠状态?

Is there a way to see if a bluetooth SPP scanner gone sleep?

我必须从蓝牙 SPP 扫描器中获取条码。我可以打开 com 端口并捕获所有扫描,但是 2 分钟后扫描仪进入休眠状态。当扫描仪醒来时,它不再连接,但 com 端口仍然打开。我需要一种方法来查明扫描仪是否仍处于连接状态,或者是否进入休眠状态,并且 close/re-open 扫描仪再次唤醒时的 com 端口。

我在 win10 中将扫描仪与电脑配对,这会创建一个输入 com 端口 (com4)。我可以打开那个端口并收听消息。 问题是,扫描仪只使用一种方式通信,似乎它没有发送任何东西说 "i disconnect now",它只是进入睡眠状态并断开连接。 有什么办法可以看到扫描仪仍然连接着,或者进入睡眠状态,或者有什么可以连接的吗? 扫描仪是WASP WWS550i。

        _serialPort = New SerialPort(PortName, BaudRate, Parity.None, 8, StopBits.One)
        _serialPort.PortName = PortName
        _serialPort.Parity = Parity.None
        _serialPort.DataBits = 8
        _serialPort.BaudRate = BaudRate
        _serialPort.StopBits = StopBits.One

        AddHandler _serialPort.DataReceived, AddressOf sp_DataReceived

        _serialPort.Open()

Private Sub sp_DataReceived(ByVal sender As Object, ByVal e As SerialDataReceivedEventArgs)
    _LastDataReceived = _serialPort.ReadLine()
End Sub

我在使用 Pos 平板电脑扫描仪时遇到了完全相同的问题。 ASP.CORE 3 名工作人员服务

我通过唤醒后重新打开串口解决了这个问题。 此外,如果我尝试重新打开端口,端口会显示 端口不可用 因为端口未正确关闭(处置)。


我的解决方案

我写了 1 秒的检查程序来检查端口是否仍然打开。如果不是,则在先前的串行端口实例上调用 close(),然后重新打开端口。

现在可以唤醒后扫描了

public class Worker : BackgroundService
    {
        private static SerialPort SERIAL_PORT;

        // constructor DI

        protected override async Task ExecuteAsync(CancellationToken stoppingToken)
        {

        }

        public override Task StartAsync(CancellationToken cancellationToken)
        {
            // create serial port connection
            _logger.LogInformation($"-- open serial port {PORT_NAME}");

            SERIAL_PORT = SerialPortFactory.Create(PORT_NAME);
            SERIAL_PORT.Open();

            _logger.LogInformation($"-- serial port {PORT_NAME} opened");

            Task.Run(() => Checker(_logger)); // run port checker on another thread

            return base.StartAsync(cancellationToken);
        }

        public override Task StopAsync(CancellationToken cancellationToken)
        {
            SERIAL_PORT.Close();
            return base.StopAsync(cancellationToken);
        }

        public static void Checker(ILogger<Worker> _logger)
        {
            for (;;)
            {
                _logger.LogInformation("Sleep for 1 second!");
                Thread.Sleep(1000);
                try
                {
                    _logger.LogInformation(SERIAL_PORT.IsOpen.ToString());
                    if(!SERIAL_PORT.IsOpen)
                    {
                        SERIAL_PORT.Close();
                        Thread.Sleep(100); // is not necessary but ...

                        SERIAL_PORT = SerialPortFactory.Create(PORT_NAME);
                        SERIAL_PORT.Open();

                        _logger.LogInformation($"-- serial port {PORT_NAME} opened");
                    }
                } catch(Exception e)
                {
                    _logger.LogError(e.Message);
                }
            }
        }
    }

SerialPortFactory - 只是我对来自 MS doc

的新 SerialPort 的简单包装器 class