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+"\n 參數:"+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,"");
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM