node.js 多个串口

标签 node.js

我正在使用 Nodejs 的 SerialPorts 模块,并且需要能够打开、写入和读取可变数量的串行端口。

所以我要做的是首先为serialPort实例创建一个数组对象,然后在循环中处理它们:

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);
            });
        });


    }
}

问题是 分钟() 函数执行,但它不会尝试打开或读/写端口。

我做错了什么?有没有更好的方法来做到这一点?

最佳答案

这里存在一些误解。

首先,您不需要定期轮询端口。 Nodejs 使用事件循环(或多或少)来处理 IO,并将为您进行轮询。因此,您需要做的就是设置 open 的回调。事件,每个端口一次。在您的代码中,看起来您每次都在读取回调 minute()正在被调用。那是没有必要的。

其次,JavaScript 没有变量的 block 作用域。相反,您无意中创建了一个闭包,并且您的代码有错误。在以下 block 中:

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 的值在执行回调之前,不会绑定(bind)(设置)。在此示例中,您的每个回调 i将被设置为ports.length ,这是 i 的最后评估值

我创建了一个 plunkr that illustrates the problem with your for loop .

解决此问题的一种方法是使用匿名方法,并绑定(bind)值 i到一个新的局部变量。在下面的代码中,(function(index){})(i);立即执行,并绑定(bind)值 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()立即执行,并绑定(bind)到正确的端口。

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);
     });
  });
}

关于node.js 多个串口,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17415231/

相关文章:

javascript - Mongoose 具有 JSON 数据,其值作为属性名称

javascript - Telegram 机器人不在群组中回复消息,而是在个人聊天中回复相同的消息

node.js - au run - 应用程序包中不包含 js 文件

javascript - 在 Node 中转译 TypeScript 的最快方法

node.js - 合并两个字典 : perl "hashrefslice" syntax in javascript?

node.js - Ubuntu + Node + curl : (52) Empty reply from server

javascript - 火存储 : Query by item in array of document

node.js - 设置 Firebase 本地模拟器云功能环境配置值

javascript - 在 findAndCountAll Sequelize 中重命名 "rows"

node.js - 如何防止 mongodb 支持的分布式 Nodejs Web 服务器架构中的竞争条件