Search code examples
node.jsserial-portnode-serialport

Node-SerialPort Issue w/ Multiple Writes


When I pass an array with 1 element everything works great, when I pass one with two (max for our use case) I get the following error:

There's no write queue for that file descriptor (after write)!

Here is my code:

exports.triggerPhysical = function(state, alerts) {

console.dir("IN PHYSICAL");
console.dir(alerts);

  SerialPort.list(function(err, ports) {

      var port = {};

      for(var i = 0; i < ports.length; i++) {
        try {
          if(typeof ports[i].manufacturer != 'undefined' && ports[i].manufacturer.includes("Numato")) {
            port = ports[i];
          }
        } catch(err) {
          console.dir(err);
        }
      }

      var numato = new SerialPort(port.comName, {baudrate : 19200}, function(err) {
        if(err) {
          return console.dir(err);
        }

        console.dir('calling write');       

        for(var j = 0; j < alerts.length; j++) {
            numato.write('relay ' + state + ' ' + alerts[j].index + '\r', function(err) {
              if(err) {
                console.dir('error writing');
                console.dir(err);
              }
              console.dir('serial message written');              
          });           
        }

      numato.close();

      return true;

    });
  });
}

First write works great, second one fails. I am guessing there is an obvious solution but I am not finding it. Any insight would be much appreciated.


Solution

  • I ended up doing two things to resolve this issue. First I upgraded to version 5.x of the node-serialport library.

    Second, I changed my code to the following:

    exports.triggerPhysical = function(state, alerts) {
    
        var port = new SerialPort('/dev/ttyACM0');
    
        port.on("open", function() {
            alerts.forEach(function(alert, idx) {
                str = 'relay ' + state + ' ' + alert.index + '\r';
                port.write(str, function(err, results) {
                    if(err) {
                        console.dir("err writing");
                        console.dir(err);
                    } else {
                        console.dir(results);
                    }
                });
            });     
        })
    
        port.drain(writeDone);      
    
    
        function writeDone() {
            console.dir("In writeDone");
            port.close();
        }
    }
    

    I am now able to do consecutive writes without causing any errors and the port doesn't end up in a weird locked state.