From 41acbf5af7dd5cc419b018ec4d23aa7cb72899f5 Mon Sep 17 00:00:00 2001 From: Dave Conway-Jones Date: Wed, 10 Apr 2019 09:57:16 +0100 Subject: [PATCH] Let Arduino node reconnect To close #532 --- hardware/Arduino/35-arduino.js | 234 +++++++++++++++++++-------------- hardware/Arduino/package.json | 2 +- 2 files changed, 133 insertions(+), 103 deletions(-) diff --git a/hardware/Arduino/35-arduino.js b/hardware/Arduino/35-arduino.js index 04c1f862..e036f899 100644 --- a/hardware/Arduino/35-arduino.js +++ b/hardware/Arduino/35-arduino.js @@ -10,26 +10,35 @@ module.exports = function(RED) { RED.nodes.createNode(this,n); this.device = n.device || null; var node = this; + var running = false; - node.board = new Board(node.device, function(e) { - //console.log("ERR",e); - if ((e !== undefined) && (e.toString().indexOf("cannot open") !== -1) ) { - node.error(RED._("arduino.errors.portnotfound",{device:node.device})); - } - else if (e === undefined) { - node.board.on('ready', function() { - node.log(RED._("arduino.status.connected",{device:node.board.sp.path})); - if (RED.settings.verbose) { - node.log(RED._("arduino.status.version",{version:node.board.firmware.name+"-"+node.board.version.major+"."+node.board.version.minor})); - } - }); - } - node.board.on('close', function() { - node.error(RED._("arduino.status.portclosed")); + var startup = function() { + node.board = new Board(node.device, function(e) { + if ((e !== undefined) && (e.toString().indexOf("cannot open") !== -1) ) { + node.error(RED._("arduino.errors.portnotfound",{device:node.device})); + } + else if (e === undefined) { + running = true; + node.board.once('ready', function() { + node.log(RED._("arduino.status.connected",{device:node.board.sp.path})); + if (RED.settings.verbose) { + node.log(RED._("arduino.status.version",{version:node.board.firmware.name+"-"+node.board.version.major+"."+node.board.version.minor})); + } + }); + node.board.once('close', function() { + node.error(RED._("arduino.status.portclosed")); + }); + node.board.once('disconnect', function() { + if (running) { setTimeout(function() { running = false; startup(); }, 5000); } + }); + } }); - }); + setTimeout(function() { if (!running) { startup(); } }, 5000); + }; + startup(); node.on('close', function(done) { + running = false; if (node.board) { try { node.board.transport.close(function() { @@ -53,59 +62,68 @@ module.exports = function(RED) { this.state = n.state; this.arduino = n.arduino; this.serverConfig = RED.nodes.getNode(this.arduino); + this.running = false; if (typeof this.serverConfig === "object") { - this.board = this.serverConfig.board; - var node = this; - node.oldval = ""; - node.status({fill:"red",shape:"ring",text:"node-red:common.status.connecting"}); - var doit = function() { - node.status({fill:"green",shape:"dot",text:"node-red:common.status.connected"}); - if (node.state === "ANALOG") { - node.board.pinMode(node.pin, 0x02); - node.board.analogRead(node.pin, function(v) { - if (v !== node.oldval) { - node.oldval = v; - node.send({payload:v, topic:"A"+node.pin}); - } + var startup = function() { + this.board = this.serverConfig.board; + var node = this; + node.oldval = ""; + node.status({fill:"grey",shape:"ring",text:"node-red:common.status.connecting"}); + var doit = function() { + node.running = true; + node.status({fill:"green",shape:"dot",text:"node-red:common.status.connected"}); + if (node.state === "ANALOG") { + node.board.pinMode(node.pin, 0x02); + node.board.analogRead(node.pin, function(v) { + if (v !== node.oldval) { + node.oldval = v; + node.send({payload:v, topic:"A"+node.pin}); + } + }); + } + if (node.state === "INPUT") { + node.board.pinMode(node.pin, 0x00); + node.board.digitalRead(node.pin, function(v) { + if (v !== node.oldval) { + node.oldval = v; + node.send({payload:v, topic:node.pin}); + } + }); + } + if (node.state === "PULLUP") { + node.board.pinMode(node.pin, 0x0B); + node.board.digitalRead(node.pin, function(v) { + if (v !== node.oldval) { + node.oldval = v; + node.send({payload:v, topic:node.pin}); + } + }); + } + if (node.state == "STRING") { + node.board.on('string', function(v) { + if (v !== node.oldval) { + node.oldval = v; + node.send({payload:v, topic:"string"}); + } + }); + } + node.board.once('disconnect', function() { + node.status({fill:"red",shape:"ring",text:"node-red:common.status.not-connected"}); + if (node.running) { setTimeout(function() { node.running = false; startup(); }, 5500); } }); } - if (node.state === "INPUT") { - node.board.pinMode(node.pin, 0x00); - node.board.digitalRead(node.pin, function(v) { - if (v !== node.oldval) { - node.oldval = v; - node.send({payload:v, topic:node.pin}); - } - }); - } - if (node.state === "PULLUP") { - node.board.pinMode(node.pin, 0x0B); - node.board.digitalRead(node.pin, function(v) { - if (v !== node.oldval) { - node.oldval = v; - node.send({payload:v, topic:node.pin}); - } - }); - } - if (node.state == "STRING") { - node.board.on('string', function(v) { - if (v !== node.oldval) { - node.oldval = v; - node.send({payload:v, topic:"string"}); - } - }); - } - // node.board.on('close', function() { - // node.board.removeAllListeners(); - // node.status({fill:"grey",shape:"ring",text:"node-red:common.status.not-connected"}); - // }); + if (node.board.isReady) { doit(); } + else { node.board.once("ready", function() { doit(); }); } + setTimeout(function() { if (!node.running) { startup(); } }, 4500); } - if (node.board.isReady) { doit(); } - else { node.board.on("ready", function() { doit(); }); } + startup(); } else { this.warn(RED._("arduino.errors.portnotconf")); } + node.on('close', function() { + node.running = false; + }); } RED.nodes.registerType("arduino in",DuinoNodeIn); @@ -118,53 +136,65 @@ module.exports = function(RED) { this.state = n.state; this.arduino = n.arduino; this.serverConfig = RED.nodes.getNode(this.arduino); - if (typeof this.serverConfig === "object") { - this.board = this.serverConfig.board; - var node = this; - node.status({fill:"red",shape:"ring",text:"node-red:common.status.connecting"}); - var doit = function() { - node.status({fill:"green",shape:"dot",text:"node-red:common.status.connected"}); - node.on("input", function(msg) { - if (node.state === "OUTPUT") { - node.board.pinMode(node.pin, 0x01); - if ((msg.payload === true)||(msg.payload.toString() == "1")||(msg.payload.toString().toLowerCase() == "on")) { - node.board.digitalWrite(node.pin, node.board.HIGH); + this.running = false; + var node = this; + if (typeof node.serverConfig === "object") { + var startup = function() { + node.board = node.serverConfig.board; + node.status({fill:"grey",shape:"ring",text:"node-red:common.status.connecting"}); + var doit = function() { + node.running = true; + node.status({fill:"green",shape:"dot",text:"node-red:common.status.connected"}); + node.on("input", function(msg) { + if (node.board.isReady) { + if (node.state === "OUTPUT") { + node.board.pinMode(node.pin, 0x01); + if ((msg.payload === true)||(msg.payload.toString() == "1")||(msg.payload.toString().toLowerCase() == "on")) { + node.board.digitalWrite(node.pin, node.board.HIGH); + } + if ((msg.payload === false)||(msg.payload.toString() == "0")||(msg.payload.toString().toLowerCase() == "off")) { + node.board.digitalWrite(node.pin, node.board.LOW); + } + } + if (node.state === "PWM") { + node.board.pinMode(node.pin, 0x03); + msg.payload = parseInt((msg.payload * 1) + 0.5); + if ((msg.payload >= 0) && (msg.payload <= 255)) { + node.board.analogWrite(node.pin, msg.payload); + } + } + if (node.state === "SERVO") { + node.board.pinMode(node.pin, 0x04); + msg.payload = parseInt((msg.payload * 1) + 0.5); + if ((msg.payload >= 0) && (msg.payload <= 180)) { + node.board.servoWrite(node.pin, msg.payload); + } + } + if (node.state === "SYSEX") { + node.board.sysexCommand(msg.payload); + } + if (node.state === "STRING") { + node.board.sendString(msg.payload.toString()); } - if ((msg.payload === false)||(msg.payload.toString() == "0")||(msg.payload.toString().toLowerCase() == "off")) { - node.board.digitalWrite(node.pin, node.board.LOW); } - } - if (node.state === "PWM") { - node.board.pinMode(node.pin, 0x03); - msg.payload = parseInt((msg.payload * 1) + 0.5); - if ((msg.payload >= 0) && (msg.payload <= 255)) { - node.board.analogWrite(node.pin, msg.payload); - } - } - if (node.state === "SERVO") { - node.board.pinMode(node.pin, 0x04); - msg.payload = parseInt((msg.payload * 1) + 0.5); - if ((msg.payload >= 0) && (msg.payload <= 180)) { - node.board.servoWrite(node.pin, msg.payload); - } - } - if (node.state === "SYSEX") { - node.board.sysexCommand(msg.payload); - } - if (node.state === "STRING") { - node.board.sendString(msg.payload.toString()); - } - }); - // node.board.on('close', function() { - // node.status({fill:"grey",shape:"ring",text:"node-red:common.status.not-connected"}); - // }); + }); + node.board.once('disconnect', function() { + node.status({fill:"red",shape:"ring",text:"node-red:common.status.not-connected"}); + if (node.running) { setTimeout(function() { node.running = false; startup(); }, 5500); } + }); + } + if (node.board.isReady) { doit(); } + else { node.board.once("ready", function() { doit(); }); } + setTimeout(function() { if (!node.running) { startup(); } }, 4500); } - if (node.board.isReady) { doit(); } - else { node.board.on("ready", function() { doit(); }); } + startup(); } else { - this.warn(RED._("arduino.errors.portnotconf")); + node.warn(RED._("arduino.errors.portnotconf")); } + node.on('close', function() { + node.running = false; + }); } RED.nodes.registerType("arduino out",DuinoNodeOut); diff --git a/hardware/Arduino/package.json b/hardware/Arduino/package.json index d0bcf4ac..aec979c2 100644 --- a/hardware/Arduino/package.json +++ b/hardware/Arduino/package.json @@ -1,6 +1,6 @@ { "name" : "node-red-node-arduino", - "version" : "0.1.0", + "version" : "0.2.0", "description" : "A Node-RED node to talk to an Arduino running firmata", "dependencies" : { "firmata" : "^2.0.0"