0

我正在尝试列出所有串行端口并选择以 /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')
});

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

4

3 回答 3

2

下面的函数假设在您的结果端口中,只有一个串行端口。我将您的 ports.forEach 更改为标准 for 循环。我相信这个循环中正在进行的工作是同步的。我认为 forEach 是同步的,但我知道 for(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);
});
于 2013-07-31T13:30:35.773 回答
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);

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

希望能帮助到你!

于 2013-08-21T14:35:41.913 回答
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
于 2013-08-15T15:35:04.987 回答