需求场景 项目中难免有桌面设备接入的情况,比如扫码枪、RFID扫码器等情况。方案 1。中间件方案 做一个在客户端微型http服务或者websoket服务,JavaScript调用这个服务与串口通讯。优点兼容浏览器,缺点这个服务得兼容操作系统,这种方案落地过。 2。浏览器插件方案 做一个浏览器插件,JavaScript基于插件与串口通讯。优点是你只需要搞定浏览器即可,缺点是可能需要兼容多种浏览器,这种方案没试过,理论上是可行的。 3。Chrome浏览器读取方案 通过Chrome浏览器的API直接读取串口数据,有点就是没有额外的工作,缺点就是只有Chrome浏览器能用,这种方案落地过。串口基础知识 串行接口简称为串口,也叫串行通信,这是一个统称,采用串行通信的接口都叫作串口,串口是一个硬件接口。工作模式单工:在任何时候都只能从A传输到B,就和在麦克风输出到扩音器的场景类似半双工:同时只能A传输的B或者B传输的C,跟对讲机的场景差不多吧全双工:在任何时候A和B都能互相传输数据,跟打电话场景类似。相关参数 (1)波特率 串口通信时的速率。常见的有9600、14400、115200等等,这个说的就是bps,重点关注。 (2)数据位 这是衡量通信中实际数据位的参数。当计算机发送一个信息包,实际的数据不会是8位的,标准的值是5、7和8位。如何设置取决于你想传送的信息。比如,标准的ASCII码是0127(7位)。扩展的ASCII码是0255(8位)。 (3)停止位 用于表示单个数据包的最后一位。典型的值为1、1。5或2位。停止位不仅表示传输的结束,并且提供计算机校正时钟同步的机会。停止位的位数越多,不同时钟同步的容错程度越大,但同时数据传输率也越慢。 (4)校验位 在串口通信中一种简单的检错方式。有三种检错方式:偶(E)、奇(O)、无(N)。VenderID和ProductID 即厂家标识和产品标识,USB设备驱动的硬件接口需要识别VenderID和ProductID,各个平台的查看方式大家自己查询一下,也可以使用API查询ChromeAPI介绍判断浏览器是否支持串口if(serialinnavigator){TheWebSerialAPIissupported。}根据usbVendorId和usbProductId过滤串口constfilters〔{usbVendorId:0x2341,usbProductId:0x0043},〕;PromptusertoselectanArduinoUnodevice。constportawaitnavigator。serial。requestPort({filters});打开关闭串口这个参数是波特率awaitport。open({baudRate:9600});awaitport。close(); 读取和写入数据constreaderport。readable。getReader();Listentodatacomingfromtheserialdevice。while(true){const{value,done}awaitreader。read();if(done){Allowtheserialporttobeclosedlater。reader。releaseLock();break;}valueisaUint8Array。console。log(value);}onstwriterport。writable。getWriter();constdatanewUint8Array(〔104,101,108,108,111〕);helloawaitwriter。write(data);Allowtheserialporttobeclosedlater。writer。releaseLock();示例asyncfunctiongetCOMData(){if(!serialinnavigator){console。error(该浏览器不支持串口)return;}这个地方换成自己设备constfilters〔{usbVendorId:0x1a86,usbProductId:0x7521},〕;letportawaitnavigator。serial。requestPort({filters});awaitport。open({baudRate:9600});验证分割符号letcheckRN(value){if(value2){return1;}for(leti1;ivalue。length;i){if(value〔i1〕0x0Dvalue〔i〕0x0A){returni;}}return1;}constreaderport。readable。getReader();lettempArray〔〕;letreadctrue;setTimeout((){readcfalse;},5000);这里是流读取,一定要根据协议解决分包和黏包的问题while(truereadc){const{value,done}awaitreader。read();if(done){Allowtheserialporttobeclosedlater。reader。releaseLock();break;}letncheckRN(value);if(n1){tempArray〔。。。tempArray,。。。value〕}else{letfullArray〔。。。tempArray,。。。value。slice(0,n)〕tempArray〔。。。value。slice(n1,value。length)〕;letstrString。fromCharCode(。。。fullArray)console。log(解析后的数:,str)}}reader。releaseLock();awaitport。close();returnundefined;} API参考地址:https:web。devserialcloseport