web前端读取串口数据

来自扫码枪应用适配的经验及扩展。

查了好多资料,发现实现思路不外乎以下几种:

1.使用服务端开发语言开发一个读取串口数据的本地服务模块,并实现websocket长连接支持,前端开启长连接到该服务,根据推送的数据进行操作。
2.针对IE浏览器,可以采用ActiveX插件读取串口数据,根据插件的API进行开发。
3.对于chrome浏览器,可以使用Chrome.serial实现

这几种方式本质区别不大,只是浏览器兼容方面有区别。第一种方式是兼容性最好的,但增加了一个本地服务模块的开发,所以开发成本较高。第二种ActiveX插件对IE浏览器兼容最好。第三种同样需要自己开发一个chrome app来调用chrome.serial接口。

由于项目要求使用IE浏览器,下面只对IE浏览器下使用ActiveX插件读取串口数据的步骤进行详述。
在这里采用的是微软开发的mscomm32.ocx.
1.下载插件并复制 MSCOMM32.OCX 到 C:\WINDOWS\SysWOW64 (如果是32位系统就是 C:\WINDOWS\SysWOW32 )
2.依次运行下面命令(以管理员身份运行,注意根据系统32位和64位更改命令中的路径):

regsvr32 /u C:\WINDOWS\SysWOW64\MSCOMM32.OCX
regsvr32 /i C:\WINDOWS\SysWOW64\MSCOMM32.OCX
regsvr32 C:\WINDOWS\SysWOW64\MSCOMM32.OCX
Reg add"HKEY_CLASSES_ROOT\Licenses\4250E830-6AC2-11cf-8ADB-00AA00C00905" /v “” /d “kjljvjjjoquqmjjjvpqqkqmqykypoqjquoun” /f

3.设置IE浏览器的ActiveX插件的安全控制,将之都设为启用或提示状态。

以上配置完成,可以用下面的代码尝试是否安装成功

<!DOCTYPE html>
<html>

	<head>
		<title>JavaScript串口测试</title>
		<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />

		<script ID=clientEventHandlersJS LANGUAGE=javascript>
			function MSComm1_OnComm() {
				switch(MSComm1.CommEvent) {
					case 1:
						{
							window.alert("Send OK!");
							break;
						} //发送事件
					case 2:
						{
							Receive();
							break;
						} //接收事件
					default:
						alert("Event Raised!" + MSComm1.CommEvent);;
				}
			}
		</script>

		<script LANGUAGE=javascript FOR=MSComm1 EVENT=OnComm>
			// MSComm1控件每遇到 OnComm 事件就调用 MSComm1_OnComm()函数
			MSComm1_OnComm()
		</script>

		<script language="JavaScript" type="text/JavaScript">

			String.prototype.Blength = function(){
				var arr = this.match(/[^\x00-\xff]/ig);
			return arr == null ? this.length : this.length + arr.length;
			}

			function OperatePort() {
				if(MSComm1.PortOpen == true) {
					try {
						MSComm1.PortOpen = false;
						document.getElementById("OperateButton").value = "打开串口";
					} catch(ex) {
						alert(ex.message);
					}
				} else {
					try {
						MSComm1.PortOpen = true;
						document.getElementById("OperateButton").value = "关闭串口";
					} catch(ex) {
						alert(ex.message);
					}
				}
			}
			
			function ConfigPort() {
				alert("串口状态:" + MSComm1.PortOpen);
				if(MSComm1.PortOpen == false) {
					try {
						MSComm1.CommPort = document.getElementById("ComName").value;
						alert(MSComm1.CommPort)
						MSComm1.Settings = document.getElementById("BaudRate").value.toString() + "," +
							document.getElementById("CheckBit").value.toString() + "," +
							document.getElementById("DataBits").value.toString() + "," +
							document.getElementById("StopBits").value.toString();
						MSComm1.OutBufferCount = 0; //清空发送缓冲区
						MSComm1.InBufferCount = 0; //滑空接收缓冲区 
						alert("已配置串口COM" + MSComm1.CommPort + "\n 参数:" + MSComm1.Settings);
					} catch(ex) {
						alert(ex.message);
					}
				} else {
					alert("请先关闭串口后再设置!");
				}
			}
			
			function Send() {
				//alert(document.getElementById("txtSend").value);
				var orgstr = document.getElementById("txtSend").value;
				var newstr = "";
				var hexflag = document.getElementById("isSendHex").checked;
				if(hexflag && orgstr != "") {
					if(orgstr.substr(0, 2) == "0x" || orgstr.substr(0, 2) == "0X") orgstr = orgstr.substring(2, orgstr.length);
					if(orgstr.length % 2 != 0) orgstr = "0" + orgstr;
					//alert(str2hex(orgstr));
					if((newstr = str2hex(orgstr)) == "") {
						alert("错误的16进制数");
						return false;
					}
				}
				try {
					MSComm1.Output = hexflag ? newstr : orgstr;	
					//alert(MSComm1.Output)
				} catch(ex) {
					alert(ex.message);
				}
			}
			
			function Receive() {
				//alert("InBufferCount::" + MSComm1.InBufferCount); // 缓冲区接收的字节
				document.getElementById("txtReceive").value += MSComm1.Input; //alert("InBufferCount::"+MSComm1.InBufferCount); 
			}
			
			function ClearReceived() {
				document.getElementById("txtReceive").innerText = "";
			}
			
			function str2hex(s) {
				var a, b, d;
				var hexStr = '';
				for(var i = 0; i <
					s.length; i++) {
					d = s.charCodeAt(i);
					a = d % 16;
					b = (d - a) / 16;
					hexStr += '%' + "0123456789ABCDEF".charAt(b) + "0123456789ABCDEF".charAt(a);
				}
				//alert(hexStr);
				return hexStr;
			}
			
			function charCode(v) {
				return String.fromCharCode(v);
			}
			
		</script>
	</head>

	<body>

		<form name="form1">

			<fieldset style="width:200px;height:250px;text-align:center;">
				<legend>配置串口</legend>
				<div style="float:left;width:200px">
					<br/>
					<span>串口号:</span>
					<select name="ComName" id="ComName" style="width:75px">
						<option value="1">COM1</option>
						<option value="2">COM2</option>
						<option value="7" selected>COM7</option>
						<option value="4">COM4</option>
						<option value="5">COM5</option>
						<option value="9">COM9</option>
					</select>
					<br/>
					<span>波特率:</span>
					<select name="BaudRate" id="BaudRate" style="width:75px">
						<option value="9600">9600</option>
						<option value="57600">57600</option>
						<option value="115200" selected>115200</option>
					</select>
					<br/>
		
					<span>校验位:</span>
					<select name="CheckBit" id="CheckBit" style="width:75px">
						<option value="N" selected>无NONE</option>
						<option value="O">奇ODD</option>
						<option value="E">偶EVEN</option>
					</select>
					<br/>
		
					<span>数据位:</span>
					<input type=text id="DataBits" name="DataBits" value=8 style="width:75px;height:20px">
					<br/>
		
					<span>停止位:</span>
					<input type=text id="StopBits" name="StopBits" value=1 style="width:75px;height:20px">
					<br/>
					<br/>
					<input type="button" id="ConfigButton" style="width:80px;height:30px;font-size:13px" name="ConfigButton" value="配置串口" onClick="ConfigPort()">
					<input type="button" id="OperateButton" style="width:80px;height:30px;font-size:13px" name="OperateButton" value="打开串口" onClick="OperatePort()">
				</div>
			</fieldset>
		
			<fieldset style="width:200px;height:250px;text-align:center;">
				<legend>发送区域</legend>
				<div style="float:left;">
					<textarea id="txtSend" name="txtSend" style="width:200px;height:160px"></textarea>
					<br/>
					<span><input id="isSendHex" name="isSendHex" type="checkbox"  />16进制</span>
					<input type="button" id="SendButton" style="width:100px;height:30px" name="SendButton" value="发送" onClick="Send()">
				</div>
			</fieldset>
		
			<fieldset style="width:200px;height:250px;text-align:center;">
				<legend>接收区域</legend>
				<div style="float:left;">
					<textarea id="txtReceive" READONLY=TRUE name="txtReceive" style="width:200px;height:160px"></textarea>
					<br/>
					<span><input id="isReceiveHex" name="isReceiveHex" type="checkbox" />16进制</span>
					<input type="button" id="ClearButton" style="width:100px;height:30px" name="ClearButton" value="清空" onClick="ClearReceived()">
				</div>
			</fieldset>
		
		</form>
		<OBJECT id=MSComm1 CLASSID="clsid:648A5600-2C6E-101B-82B6-000000000014" codebase="MSCOMM32.OCX" type="application/x-oleobject" style="LEFT:54px;TOP:14px">
		    <PARAM   NAME="CommPort"   VALUE="3"/> 
		    <PARAM   NAME="DataBits"   VALUE="8"/> 
		    <PARAM   NAME="StopBits"   VALUE="1"/> 
		    <PARAM   NAME="BaudRate"   VALUE="9600"/> 
		    <PARAM   NAME="Settings"   VALUE="9600,N,8,1"/>     
		 
		    <PARAM   NAME="RTSEnable"   VALUE="1"/> 
		    <PARAM   NAME="DTREnable"   VALUE="1"/> 
		    <PARAM   NAME="Handshaking"   VALUE="0"/> 
		    <PARAM   NAME="NullDiscard"   VALUE="0"/> 
		    <PARAM   NAME="ParityReplace"   VALUE="?"/>
		 
		    <PARAM   NAME="EOFEnable"   VALUE="0"/>       
		    <PARAM   NAME="InputMode"   VALUE="0"/>    
		    <PARAM   NAME="InBufferSize"   VALUE="1024"/>       
		    <PARAM   NAME="InputLen"   VALUE="0"/>     
		    <PARAM   NAME="OutBufferSize"   VALUE="512"/> 
		     
		    <PARAM   NAME="SThreshold"   VALUE="0"/> 
		    <PARAM   NAME="RThreshold"   VALUE="1"/> 
		 
		</OBJECT>
	</body>

</html>

  • 3
    点赞
  • 45
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值