Node.js和serialport;回调方法?

时间:2013-07-31 13:03:50

标签: javascript node.js callback node-serialport

我正在尝试列出所有串行端口,并选择以/dev/cu.usbmodem开头的端口名称。对于背景;它是一个连接到RaspberryPi运行节点的arduino。 Raspberry Pi习惯在每次重新启动时重命名端口。

到目前为止,我有这个:

com.list(function (err, ports) {
  ports.forEach(function(port) {
    var arduinoPort = port.comName;
if (arduinoPort.substring(0, 16) == "/dev/cu.usbmodem") {
      var SERIALPORT_ID = arduinoPort;
    }
  });
});

这需要很长时间才能使下一个语句失败,因为尚未声明SERIALPORT_ID变量;

var serialPort = new com.SerialPort(SERIALPORT_ID, {
  baudrate: 57600,
  parser: com.parsers.readline('\r\n')
});

什么回调或结构化技术会使第二个语句在执行之前等待第一个语句声明变量?

3 个答案:

答案 0 :(得分:2)

以下功能假设在结果端口中只有一个串口。我将ports.forEach更改为标准for循环。我相信这个循环中正在进行的工作是同步的。我认为forEach是同步的,但我知道(var i = 0; ....)是同步的,如果我们只有一个正确的'端口',那么我们希望能够跳过其他结果的循环。如果我对“只有一个好端口”的假设不正确,那么这个逻辑很容易改变。

function getSerialPort(callback) {
    'use strict';

    com.list(function (err, ports) {

        for (var i = 0; i < ports.length; i++) {//ports.forEach works too, but I know this is sync, and that's what we want in this case so we can break out of the loop when we find the right port
            var port = ports[i];
            var arduinoPort = port.comName;

            if (arduinoPort.substring(0, 16) === "/dev/cu.usbmodem") {

                var serialPort = new com.SerialPort(arduinoPort, {
                    baudrate: 57600,
                    parser: com.parsers.readline('\r\n')
                });

                callback(serialPort);
                return;//I'm not sure what return does in a ports.forEach situation, so I changed it to a standard for loop, so that we know that this is breaking us out of it.
            }
        }
    });
}

getSerialPort(function (serialPort) {
    'use strict';
    console.log('Serial Port: ' + serialPort);
});

答案 1 :(得分:1)

  

Raspberry Pi习惯每次都重命名端口   重新启动。

那么,你也可以为你正在使用的USB硬件创建一些udev规则,这样arduino将始终映射到同一个串口。假设你正在运行debian ......

vim /etc/udev/rules.d/98-usb-serial.rules

SUBSYSTEM=="tty", ATTRS{idVendor}=="2341", ATTRS{idProduct}=="0044", ATTRS{serial}=="64935343733351F072D0", SYMLINK+="arduinoUno"
SUBSYSTEM=="tty", ATTRS{idVendor}=="2341", ATTRS{idProduct}=="0043", ATTRS{serial}=="7523230313535121B0E1", SYMLINK+="arduinoMega"

要查找usb设备的供应商ID,产品ID和序列号,请使用:

dmesg
lsusb

拔下相关设备,重新插入,并将其映射到:

/dev/arduinoUno
/dev/arduinoMega

答案 2 :(得分:1)

或者您可以这样做以寻找合适的端口并自动连接! 它在OS X和Ubuntu上运行得很好,我还没有在Raspi上测试它,但你明白了。 感谢ChrisCM的“for”:)

var myPort;

function getSerialPort(callback) {

    com.list(function (err, ports) {

        for (var i = 0; i < ports.length; i++) {//ports.forEach works too, but I know this is sync, and that's what we want in this case so we can break out of the loop when we find the right port
            var port = ports[i];

                if(port.pnpId.indexOf("duino") != -1 || port.manufacturer.indexOf("duino") != -1 || port.comName.indexOf('moti') != -1){ // it look for "duino" somewhere
                    myPort = new SerialPort(port.comName,{
                    baudrate: 115200,
                    parser: serialport.parsers.readline("\r\n"),
                });

                callback(serialPort);
                return;//I'm not sure what return does in a ports.forEach situation, so I changed it to a standard for loop, so that we know that this is breaking us out of it.
            }
        }
    });
}

getSerialPort(function (myPort) {
    console.log('Serial Port: ' + myPort);
});

您还可以使用以下方法输出所有端口规格:

console.log("pnpId: " + port.pnpId);
console.log("manufacturer: " + port.manufacturer);
console.log("comName: " + port.comName);
console.log("serialNumber: " + port.serialNumber);
console.log("vendorId: " + port.vendorId);
console.log("productId: " + port.productId);

找到可用于自动连接的模式。

希望它有所帮助!