zoukankan      html  css  js  c++  java
  • js获取电子秤串口数据

    需求描述:需要在web端用js获取电子秤的重量。(由于erp限制的原因只能通过js获取,不能修改html,不能引用jquery)

    实现目标:电子秤面板上的数据实时反映在我们公司内部erp系统界面上。

    通常实现步骤:

    首先要从web端获取串口数据需要用到activex(由于我们目前这个需求只需要考虑在IE浏览器下的正常运行)

    网上关于对这个控件的调用一般是这样写的

    <object classid="clsid:648A5600-2C6E-101B-82B6-000000000014" id="MSComm1" codebase="MSCOMM32.OCX"
        type="application/x-oleobject" style="left: 54px; top: 14px">
        <param name="CommPort" value="4">
        <!--设置并返回通讯端口号。-->
        <param name="DTREnable" value="1">
        <param name="Handshaking" value="0">
        <param name="InBufferSize" value="1024">
        <param name="InputLen" value="0">
        <param name="NullDiscard" value="0">
        <param name="OutBufferSize" value="512">
        <param name="ParityReplace" value="?">
        <param name="RThreshold" value="1">
        <param name="RTSEnable" value="1">
        <param name="SThreshold" value="2">
        <param name="EOFEnable" value="0">
        <param name="InputMode" value="0">
        <!--comInputModeText 0 (缺省) 通过 Input 属性以文本方式取回数据。comInputModeBinary 1  通过 Input 属性以二进制方式检取回数据。-->
        <param name="DataBits" value="8">
        <param name="StopBits" value="1">
        <param name="BaudRate" value="38400">
        <param name="Settings" value="38400,N,8,1">
    </object>

     而由于前面所说的我们erp的限制,我无法修改html文件,因此无法在html文件中添加对MSCOMM32.dll的引用。因此我是用如下方法实现的:

    //创建MSComm对象
    function uf_GetSerPortData()
    {
        try
        {
            MSComm1 = new ActiveXObject("MSCOMMLib.MSComm.1");
            if ((typeof (MSComm1) == "undefined") || (MSComm1 == null))
            {
                alert("创建MSComm1对象失败!");
            }
            else
            {
                //绑定事件
                fn();
            }
        }
        catch (err)
        {
            alert(err.description);
        }
    }
    
    var fn=function(){
        function MSComm1::OnComm() {
            MSComm1_OnComm();
        }
    }

    在这里有几个地方需要解释一下:

    1. 打开端口的时候提示创建对象失败

      如果后面设置MSComm1的PortOpen提示失败时,就需要添加对MScomm控件的注册。具体的注册方法在如下链接里面有详细说明:http://jingyan.baidu.com/article/375c8e19a2953b25f2a22986.html

      需要注意的是链接中给出的是32位系统的解决方案,对于64位系统路径可能有所不同。需要用户根据自己的系统情况进行修改。

    2. 绑定控件的事件:
      我目前所使用的电子秤有两种输出模式,一种是连续输出打印的一种是在屏幕上按键打印输出的。现在我们讨论在连续输出模式下的问题。由于是连续输出因此我们需要对电子秤的输出做一个事件绑定,并且通过一个回调函数来实现获取重量数据后在erp中进行对应的数据展示。一般我们可以通过诸如下面的代码来实现事件绑定
    <script   language="javascript"   for="window"   event="onload">
    
      ......
    
    </script>

    但是由于无法修改html代码,仅仅只能修改js代码的限制,我们现在无法通过这种方式实现事件绑定。(我也想过通过js动态在html中插入这段引用,但实际结果并没有触发事件,不知道是由于加载顺序的原因,还是erp本身对于这块的安全限制)因此我们只能另寻他法.在这里就用到了下面的代码了

    function uf_GetSerPortData()
    {
        try
        {
            MSComm1 = new ActiveXObject("MSCOMMLib.MSComm.1");
            if ((typeof (MSComm1) == "undefined") || (MSComm1 == null))
            {
                alert("创建MSComm1对象失败!");
            }
            else
            {
                //绑定事件
                fn();
            }
        }
        catch (err)
        {
            alert(err.description);
        }
    }
    
    var fn=function(){
        function MSComm1::OnComm() {
            MSComm1_OnComm();
        }
    }

    对于 function MSComm1::OnComm() 这种写法,我之前从没见过,后来是在一篇博文上面看到的,试了下发现真的可以实现,事件绑定。这样就完成了在js中进行事件绑定了。后面的回调函数显示重量数值就很简单了。

    其中   new ActiveXObject("MSCOMMLib.MSComm.1"); 引号中的是activex控件的ProgID,在注册表中classid所对应下的项中可以找到。也就是创建控件的时候起的名字。

    下面贴上实现的完整代码(直接从实现demo当中抠出来的,关于数值显示的地方代码丑陋大家略过就行。但肯定是可以实现需求的,已经测试过)

    //创建MSComm对象
    function uf_GetSerPortData()
    {
        try
        {
            MSComm1 = new ActiveXObject("MSCOMMLib.MSComm.1");
            if ((typeof (MSComm1) == "undefined") || (MSComm1 == null))
            {
                alert("创建MSComm1对象失败!");
            }
            else
            {
                //绑定事件
                fn();
            }
        }
        catch (err)
        {
            alert(err.description);
        }
    }
    
    var fn=function(){
        function MSComm1::OnComm() {
            MSComm1_OnComm();
        }
    }
    
    //事件响应
    function   MSComm1_OnComm()
    {
        switch(MSComm1.CommEvent)
        {
            case 1:{ window.alert("Send OK!"); break;}  //发送事件
            case 2: { Receive();break;} //接收事件
            default: alert("Event Raised!"+MSComm1.CommEvent);;
        }
    }
    
    
    
    function OperatePort()
    {
        if(MSComm1.PortOpen==true)
        {
            try{MSComm1.PortOpen=false;
                SKButton1.value="打开串口";
            }catch(ex)
            {alert(ex.message);}
        }
        else{
            try{ MSComm1.PortOpen=true;
                MSComm1.InBufferCount = 0;
                SKButton1.value="关闭串口";
            }catch(ex)
            {alert(ex.message);}
        }
    }
    
    function ConfigPort()
    {
        var comport="";
        var boundRate="";
        var jiaoyanwei="";
        var shujuwei="";
        var tingzhiwei="";
        comport=SKDBcombobox1.value;
        boundRate=SKDBcombobox2.value;
        jiaoyanwei=SKDBcombobox3.value;
        shujuwei=SKDBedit5.value;
        tingzhiwei=SKDBedit6.value;
    
        if(MSComm1.PortOpen==false)
        {
            try{
                /*
                    MSComm1.CommPort=comport;
                    MSComm1.Settings=boundRate+","+jiaoyanwei+","+shujuwei+","+tingzhiwei;
                    MSComm1.OutBufferCount =0;           //清空发送缓冲区
                    MSComm1.InBufferCount = 0;           //滑空接收缓冲区
                 */
                MSComm1.CommPort="4";
                switch(SKDBcombobox1.value)
                {
                    case "COM1":
                        MSComm1.CommPort="1";
                        break;
                    case "COM2":
                        MSComm1.CommPort = "2";
                        break;
                    case "COM3":
                        MSComm1.CommPort = "3";
                        break;
                }
                
                MSComm1.Settings="9600"+
                                     ","+"n"+
                                     ","+"8"+
                                     ","+"1";
                MSComm1.OutBufferCount =0;           //清空发送缓冲区
                MSComm1.InBufferCount = 0;           //滑空接收缓冲区
                MSComm1.RThreshold=1;                    //接收一个字节就触发omcom事件
    
    
                alert("已配置串口COM"+MSComm1.CommPort+"
     参数:"+MSComm1.Settings);
            }catch(ex){alert(ex.message);}
        }
        else{ alert("请先关闭串口后再设置!");}
    }
    var tmpWeight = "";
    
    //接收数据
    function Receive()
    {
        //alert("InBufferCount::"+MSComm1.InBufferCount);
        var inputvalue = MSComm1.Input;
    
    
        if (inputvalue.indexOf('g') >= 0) {
            return;
        }
        // alert(inputvalue);
    
        tmpWeight+=inputvalue.replace('-', '');
    
        if(tmpWeight.length>16)
        {
            if(tmpWeight.indexOf('000'))
            {
                var weight=trim(tmpWeight.substr(5,5));
                if(weight.indexOf('0')==0)
                {
                    weight=weight.replace("0","0.")
                }
                SKDBedit7.value=weight;
                tmpWeight="";
            }
    
        }
    
    
    
        //alert("InBufferCount::"+MSComm1.InBufferCount);
    }
    /*
    var weight;
    var myArray=new Array();
    function GetWeight()
    {
    
    }
    */
    function serPortInit()
    {
        SKDBcombobox1.value="COM4";
        SKDBcombobox2.value="9600";
        SKDBcombobox3.value="无NONE";
        SKDBedit5.value="8";
        SKDBedit6.value="1";
    
        //初始化创建MSComm1对象
        uf_GetSerPortData();
    }
    
    
    
    function trim(str){ //删除左右两端的空格
        return str.replace(/(^s*)|(s*$)/g, "");
    }
    function ltrim(str){ //删除左边的空格
        return str.replace(/(^s*)/g,"");
    }
    function rtrim(str){ //删除右边的空格
        return str.replace(/(s*$)/g,"");
    }
  • 相关阅读:
    2018-9-4-Roslyn-通过-nuget-统一管理信息
    2018-9-4-Roslyn-通过-nuget-统一管理信息
    省赛前最后一次总结
    省赛前最后一次总结
    POJ 1845-Sumdiv(厉害了这个题)
    POJ 1845-Sumdiv(厉害了这个题)
    DP背包(一)
    DP背包(一)
    训练记录
    训练记录
  • 原文地址:https://www.cnblogs.com/falcon-fei/p/4323661.html
Copyright © 2011-2022 走看看