JS和COM口通信

    • 前言
    • COM口简介
    • Windows的通信控件MSComm
    • 控件的开发
    • JS页面端的调用

前言

最近需要实现一个需求:在浏览器上调用COM口进行打印输出和接收打印后的回调信息,可是在网上找了很多代码,不是抄来抄去,就是没法调用,所以就自己用VB6.0实现了一个控件。

COM口简介

计算机和外设连接需要有输入输出接口,常用的有串口和并口,而COM口就是就是串口来的。台式机后面的那个九针梯形的接口就是COM口。可以在Windows 的DOS界面输入如下命令查看COM口的状态:

mode com1

COM1口的状态信息
JS和COM口通信_第1张图片

当COM口被占用的时候会提示 设备 COM 当前不可用

Windows的通信控件MSComm

MSComm 控件通过串行端口传输和接收数据,为应用程序提供串行通讯功能。在VC、VB、Delphi等语言中均可使用。我的话是使用MSCOMM32.OCX控件,开发语言是用VB,开发工具使用的VB6.0。

MSComm控件的详细介绍可以看这里,主要看几个重要的属性和两种通讯方式。


  • CommPort

设置需要通讯的端口号
例如:MSComm1.commPort = 3,表示需要和com3端口进行通信


  • Settings

以字符串的形式设置并返回波特率、奇偶校验、数据位、停止位。
例如: MSComm1.Settings = “9600,n,8,1”,表示波特率9600,无校验,8位数据位,停止位为1


  • InputMode

设置出入的数据类型,0为字符串,1位二进制
例如:MSComm1.InputMode = 1,表示 接收二进制类型数据


  • PortOpen

设置并返回通讯端口的状态。可以打开和关闭端口。
打开端口:portOpen = true;关闭端口:portOpen = false;


  • Input

从接收缓冲区返回和删除字符。COM口返回的数据从这里获取到。数据类型为byte数组类型。
例如:buf = MSComm1.Input,表示从缓冲区获取COM返回的数据。


  • Output

向传输缓冲区写数据。注意传入的类型为byte数组。
例如:MSComm1.output = hexData,表示把数据传给COM口

处理通讯的方式有两种:一种为事件驱动方式,一种是查询方式。驱动方式是回调的方式获取返回的数据,而查询方式是轮询的方法获取返回的数据。

控件的开发

我这里使用的是VB6.0来开发。整体的思路是JS调用控件提供的接口,传入字符串,然后控件把字符串处理成byte数组的形式hexData,再把数组传给MSComm.output。然后写一个响应事件,接受回调的数据,提供给JS当做回调接口,这样就把数据传到页面上了。形成一个完整的通信。

明确了思路,马上开始动手实现。

首先在VB6.0下新建工程,弹出的框中选中ActiveX控件。然后把MSCOMM32.OCX控件拖入工具箱中,会出现一个类似于电话的黄色图标,然后双击图标添加。

接下来就是编码实现了。

数据输入接口:

'提供给JS调用的接口,数据从这里传进来
Public Function inputMsg(ByVal vNewValue As String)
    Dim inputStr As String
    inputStr = vNewValue

    Dim inputArray() As String, i As Integer, inputArrLen As Integer, temp As String, hexData() As Byte
    inputArray = Split(inputStr, " ")
    inputArrLen = UBound(inputArray) - LBound(inputArray) + 1
    ReDim hexData(inputArrLen)
    For i = LBound(inputArray) To UBound(inputArray)
       temp = inputArray(i)
       hexData(i) = CByte("&H" & temp)
    Next
    MSComm1.output = hexData
End Function

MSComm控件的回调接口,获取到MSComm返回的数据后,需要注意这里返回的数据是byte数组,需要转义成你自己定义好的格式,回调出去给外部。我这里是转义成16进制的字符串。具体的协议需要和开发com口的伙伴商量好。

Private Sub MSComm1_OnComm()
    Dim buf$
    Select Case MSComm1.CommEvent
        '通过取代底下每一个 case 表达式来处理每个事件与错误
        Case comEvCD ' CD 线的状态发生变化 Case comEvCTS ' CTS 线的状态发生变化
        Case comEvDSR ' DSR 线的状态发生变化
        Case comEvReceive
            buf = MSComm1.Input '将缓冲区内的数据读入 buf 变量中,主要是这里,取到保存的数据
        Case comEvSend

    End Select
    RaiseEvent onOutput(buffChange(buf))'触发事件,提供回调方法给外部
End Sub

VB的完整代码如下:

Public Event onOutput(value As String)'定义一个事件,用于回调处理


Private Sub MSComm1_OnComm()
    Dim buf$
    Select Case MSComm1.CommEvent
        '通过取代底下每一个 case 表达式来处理每个事件与错误
        Case comEvCD ' CD 线的状态发生变化 Case comEvCTS ' CTS 线的状态发生变化
        Case comEvDSR ' DSR 线的状态发生变化
        Case comEvReceive
            buf = MSComm1.Input '将缓冲区内的数据读入 buf 变量中
        Case comEvSend

    End Select
    RaiseEvent onOutput(buffChange(buf))'触发事件,提供回调方法给外部
End Sub
Function buffChange(buf$) As String
    Dim byteReceive() As Byte, i As Integer, output As String
    byteReceive() = buf
    For i = LBound(byteReceive) To UBound(byteReceive)
        output = output & " " & Hex(byteReceive(i))
    Next
    buffChange = Trim(output)
End Function

Private Sub MSComm_Print_Initialize()

End Sub


Public Function inputMsg(ByVal vNewValue As String)
    Dim inputStr As String
    inputStr = vNewValue

    Dim inputArray() As String, i As Integer, inputArrLen As Integer, temp As String, hexData() As Byte
    inputArray = Split(inputStr, " ")
    inputArrLen = UBound(inputArray) - LBound(inputArray) + 1
    ReDim hexData(inputArrLen)
    For i = LBound(inputArray) To UBound(inputArray)
       temp = inputArray(i)
       hexData(i) = CByte("&H" & temp)
    Next
    MSComm1.output = hexData
End Function



Public Property Let commPort(vNewValue As Integer)
    MSComm1.commPort = vNewValue   ' 设置通信端口号为 COM3
End Property


Public Function openCom()
    MSComm1.Settings = "9600,n,8,1"   '设置串口  参数
    MSComm1.InputMode = 1   ' 接收二进制类型数据
    MSComm1.RThreshold = 1 '接收缓冲区每收到一个字符都会使 MSComm 控件触发 OnComm 事件
    MSComm1.PortOpen = True    ' 打开通信端口
End Function

Public Sub clossCom()
    MSComm1.PortOpen = False
End Sub

完成后就可以用VB6.0生成控件:MSComm_Print.ocx

JS页面端的调用

新生成的控件需要注册,注册成功后,就可以调用了。

打开DOS窗口,输入

Regsvr32 控件所在的文件夹\xxx.ocx

如果弹出成功注册的弹窗,就说明成功了。如果提示说缺少dll文件的话,那么就需要下载相关的dll文件放到当前控件的文件夹下。检测的工具可以用这个depends,把控件拖进去就可以知道缺少多少依赖库,然后逐个下载下来,放到和要注册的控件相同的目录下面就OK啦。

先在HTML页面上嵌入OBJECT对象

<OBJECT id="MSComm_Print" 
    name="MSComm_Print" classid="clsid:自动生成的ID" 
    type="application/x-oleobject" width="0" height="0">
    OBJECT>

这里的classid获取很简单,在VB6.0开发好控件后,直接点击运行,会在浏览器弹出一个网页,查看网页的源码就可以看到classid了,也可以直接把源码拷出来,在上面进行开发。

调用:

<script type="text/javascript">
    MSComm_Print.commPort = 3;
    MSComm_Print.openCom();
    var data = "AA AA AA AA AA";//我这里的数据格式是16进制字符串,每两位以空格分开
    MSComm_Print.inputMsg(data);
script>

回调,需要注意的是FOR= 后面字符串需要和OBJECT声明的ID的值要一致,而EVENT里面的方法和控件的事件函数是一致的。

<SCRIPT LANGUAGE=javascript FOR=MSComm_Print EVENT="onOutput(value)">
    alert(value);
SCRIPT>

整体的过程就是这样,由于是ActiveX控件,所以只能在IE浏览器上实现,而且还需要设置浏览器的安全级别。

你可能感兴趣的:(JavaScript,VB控件开发,MSComm,mscomm控件串口编程实例)