2013-07-01 103 views
1

我正在使用用於nodejs的串行端口模塊,並且需要能夠打開,寫入和讀取可變數量的串行端口。node.js多個串行端口

所以我在做什麼,是先創建一個串口實例的數組對象,然後在一個循環處理它們:

var serialport = require("serialport"); 
var SerialPort = serialport.SerialPort; // localize object constructor 
var devs = ["/dev/tty.SerialPort","/dev/tty.HHW-SPP-1800-2-DevB"]; 
var ports = []; 
for (var i = 0; i < devs.length; i++) { 
    console.log(devs[i]); 
    var port = new SerialPort(devs[i],{ baudrate:9600, parser: serialport.parsers.readline("\n") }); 
    ports.push(port); 


} 

然後我有定期調用另一個函數來讀取/寫入港口:

function minute(){ 
    for (var i = 0; i < ports.length; i++) { 
     console.log(i); 
     ports[i].on("open", function (path) { 
      console.log('opened'); 

      ports[i].write("Helo World\n", function(err,res) { 
       if(err) console.log('err ' + err); 
       console.log('results ' + res); 
      });   

      ports[i].on("data", function (data) { 
       console.log("here: "+data); 
      }); 
     }); 


    } 
} 

的問題是分()函數執行時,但它不試圖打開或讀/寫的端口。

我在做什麼錯?有沒有更好的方式來做到這一點?

+0

您不應該需要輪詢端口。 Nodejs使用事件。你應該可以在你的上面的初始化循環中設置'ports [i] .on'處理程序。 – Alan

回答

2

在這裏玩有一些誤解。

首先,您不需要定期輪詢您的端口。 Nodejs使用一個事件循環(或多或少)來處理IO,並且會爲你進行輪詢。因此,您只需爲每個端口設置一次open事件的回調。在你的代碼中,看起來你每次調用minute()時都會讀取回調函數。這沒有必要。

其次,JavaScript沒有變量的塊範圍。相反,您無意中創建了一個閉包,並且您的代碼出錯了。在此以下塊:

for (var i = 0; i < ports.length; i++) { 
    ports[i].on("open", function (path) { 
     ports[i].write("Helo World\n", function(err,res) { 
      if(err) console.log('err ' + err); 
      console.log('results ' + res); 
     });   

     ports[i].on("data", function (data) { 
      console.log("here: "+data); 
     }); 
    }); 
} 

當調用您的ports.on回調的iports[i].writeports[i].on("data")值不是i值時回調的設置,因爲你期望。相反,因爲您創建了一個閉包,所以i的值不會被綁定(設置),直到回調爲執行。在這個例子中,你的回調的每個人,i將被設置爲ports.length,這對i

最後的評估值我已經創建了一個plunkr that illustrates the problem with your for loop

解決此問題的一種方法是使用匿名方法,並將值i綁定到新的局部變量。在下面的代碼中,(function(index){})(i);立即執行,並將值index綁定到適當的值i

ports[i].on("open", function (path) { 
    (function(index) { 
    ports[index].write("Helo World\n", function(err,res) { 
     if(err) console.log('err ' + err); 
     console.log('results ' + res); 
    });   

    ports[index].on("data", function (data) { 
     console.log("here: "+data); 
    }); 
})(i); 
}); 

您也可以將該方法拉出到單獨的函數中。 setupHandlers()立即執行,並綁定到正確的端口。

for (var i = 0; i < ports.length; i++) { 
    setupHandlers(ports[i]); 
} 

function setupHandlers(port) { 
    port.on("open", function (path) { 
    ports.write("Helo World\n", function(err,res) { 
     if(err) console.log('err ' + err); 
     console.log('results ' + res); 
    });   

    ports.on("data", function (data) { 
     console.log("here: "+data); 
    }); 
    }); 
}