记一次web端读取串口数据(扫码枪)

本文讲述了作者在开发过程中如何使用WebSerialAPI解决通过条形码扫描枪获取数据的需求,包括遇到的问题、解决方案(如UTF-8编码转换)、测试过程和不同工具间的编码差异。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

原因

说到要写这串口内容的博客原因,当然是有需求开发才会去接触这一方面的内容。

需求

系统上需要使用到条形码扫描枪,根据已获得的条形码,通过扫描枪获取条形码的内容,再进而触发下一个功能逻辑。

方案

遇到问题,肯定是先百度(毕竟这一方面的功能开发我是头一次),所以兜兜转转…最终确定使用Web Serial API

Web Serial API为网站提供了一种使用JavaScript对串行设备进行读写的方法。串行设备可以通过用户系统上的串行端口连接,也可以通过模拟串行端口的可移动USB和蓝牙设备连接。

这里是我找到的参考文档:
链接1
链接2
确定好要使用哪一个方案后,就要写例子来验证一下这个API是否可行。

步骤说明

要验证API,我这里先写了一个HTML文件做简单实现。
test2.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>串口调试</title>
</head>
<body>
<button onclick="serial()">启动串口调试</button>
<h2>hamon</h2>
</body>
</html>
<script type="text/javascript">
    async function serial(){
        // 浏览器支持serial
        if ('serial' in navigator) {
            console.log('当前浏览器支持serial')

            const port = await navigator.serial.requestPort()
            await port.open({ baudRate: 9600})
            console.log("port的内容是:", port);
            const reader = port.readable.getReader();

            try{
                while(true){
                    const {value,done} = await reader.read();
                    if (done) {
                        reader.releaseLock();
                        break;
                    }
                    console.log("测试value的内容是", value);
                }
            }catch (error) {
                console.error(error)
            }finally {
                reader.releaseLock();
                console.log('允许稍后关闭串口。');
                await readableStreamClosed.catch(() => { /* Ignore the error */ });
                await port.close();
            }
        }
    }
</script>

测试代码写完了,那要创造什么环境进行验证呢?
因为我们当时还没有拿到设备,所以说先是本地虚拟出串口进行测试。

创建一对虚拟串口:

在这里插入图片描述

串口是一个双向通信接口,允许字节发送和接收数据。上述的COM1和COM2就相当于传输线的两端。

有了串口,就要构建一发一收,web端当然是用来接收数据的,还有一端用来发数据。
这里我们使用串口调试助手,这个工具是在微软store里面直接下载的(免费的)。

在这里插入图片描述
打开串口调试助手,连接虚拟串口的另一端

在这里插入图片描述
回到web项目这里,运行test2.html文件

在这里插入图片描述
根据弹出窗口显示,浏览器可以获取到我们虚拟出来的两个串口,然后我们浏览器连接COM1,串口调试助手连接COM2,并发送一串数据:

在这里插入图片描述
点击发送后,回到浏览器端,F12打开调试窗口:
在这里插入图片描述
可以看到接收到COM2传过来的值,但是不是我们想要的效果,这是因为:

SerialPort对象的readable和writable属性返回一个ReadableStream和一个WritableStream。这些将用于从串行设备接收数据并将数据发送到串行设备。两者都使用Uint8Array实例进行数据传输。

所以我们还需要将传过来的Uint8Array数组进行转换。
在test2.html中加上一个方法:

function Uint8ArrayToString(serialData){
        var out, i, len, c;
        var char2, char3;

        out = "";
        len = serialData.length;
        i = 0;
        while(i < len) {
            c = serialData[i++];
            switch(c >> 4)
            {
                case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7:
                // 0xxxxxxx
                out += String.fromCharCode(c);
                break;
                case 12: case 13:
                // 110x xxxx   10xx xxxx
                char2 = serialData[i++];
                out += String.fromCharCode(((c & 0x1F) << 6) | (char2 & 0x3F));
                break;
                case 14:
                    // 1110 xxxx  10xx xxxx  10xx xxxx
                    char2 = serialData[i++];
                    char3 = serialData[i++];
                    out += String.fromCharCode(((c & 0x0F) << 12) |
                        ((char2 & 0x3F) << 6) |
                        ((char3 & 0x3F) << 0));
                    break;
            }
        }
        return out;
    }

这时候我们再发送一次数据,看看效果:

在这里插入图片描述
可以看到传过来的数据已经拿到了,而且通过转码得到我们想要的效果,所以这个方案是可行的。


后续补充

你以为到这里就结束了?没错,最开始我也是这样认为的。
但是后面换一个串口调试工具的时候,发送的数据却出现了中文乱码!!

就是在用Commix的时候,也是同样的字符串:

在这里插入图片描述
但是得到的效果是不一样的

在这里插入图片描述
中文部分出现了乱码。

后来查明了是commix这个软件支持HEX和ASC编码方式,但是之前那个是用UTF-8的编码方式,而且拿到物理设备后,中文也是出现了乱码,而且和commix这个工具出现的乱码一模一样


出现这种问题,当然要找出原因和解决的方法,然后就在网上找了很多种编码转换的方法,Java的和js的,都试过了,还是不生效;甚至是转十六进制也不行。

不过最后还是找到了一个解决的方法:
在tes2.html中的while循环体内加入

let utf8decoder = new TextDecoder('GBK');
let u8arr = new Uint8Array(value);
var code  = utf8decoder.decode(u8arr);
console.log('value的值是:', code);

然后再用Commix这个工具进行验证

在这里插入图片描述
发现乱码的问题解决了。

注意

后来发现,虽然刚开始知道是编码不对,以为设备和Commix工具一样,都是用ASC去编码,但是并不是这样,我们拿到设备的编码方式是GBK,所以很多种转码方式都不合适。


代码分享

上述的例子只是用html来做简单验证而已,实际的功能代码是用vue来写的。后面我会把我写了html例子、vue格式和用到的调试串口工具安装包整合在一起。可以点击链接获取。


2022-04-24
资源包已经整理出来了,可点击上面的链接进行下载。

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

是哈猿啊

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值