mirror of
https://github.com/node-red/node-red-nodes.git
synced 2023-10-10 13:36:58 +02:00
Added pulse-in; added debouncing
Added the pulse-in node code. Added simple debouncing logic to discrete-in (note: this implementation may be badly affected if there is a lot of very fast bouncing.
This commit is contained in:
parent
f46b59d69f
commit
b95567dfb4
@ -14,7 +14,7 @@
|
|||||||
limitations under the License.
|
limitations under the License.
|
||||||
-->
|
-->
|
||||||
|
|
||||||
<!-- Define the edit dialog -->
|
<!-- Edit dialog for discrete-in -->
|
||||||
<script type="text/x-red" data-template-name="discrete-in">
|
<script type="text/x-red" data-template-name="discrete-in">
|
||||||
<div class="form-row">
|
<div class="form-row">
|
||||||
<label for="node-input-pin"><i class="icon-asterisk"></i>Input pin</label>
|
<label for="node-input-pin"><i class="icon-asterisk"></i>Input pin</label>
|
||||||
@ -56,6 +56,11 @@
|
|||||||
<div class="form-row">
|
<div class="form-row">
|
||||||
<label for="node-input-activeLow">Active low</label>
|
<label for="node-input-activeLow">Active low</label>
|
||||||
<input type="checkbox" id="node-input-activeLow" style="display:inline-block; width:auto; vertical-align:top;">
|
<input type="checkbox" id="node-input-activeLow" style="display:inline-block; width:auto; vertical-align:top;">
|
||||||
|
</div>
|
||||||
|
<div class="form-row">
|
||||||
|
<label for="node-input-debounce">Debounce</label>
|
||||||
|
<input type="checkbox" id="node-input-debounce" style="display:inline-block; width:auto; vertical-align:top;">
|
||||||
|
</div>
|
||||||
<div class="form-row">
|
<div class="form-row">
|
||||||
<label for="node-input-updateInterval"><i class="icon-repeat"></i> Update at</label>
|
<label for="node-input-updateInterval"><i class="icon-repeat"></i> Update at</label>
|
||||||
<input id="node-input-updateInterval" type="text" style="width: 65px">
|
<input id="node-input-updateInterval" type="text" style="width: 65px">
|
||||||
@ -71,8 +76,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
<!-- Help text for discrete-in -->
|
||||||
<!-- Add help text -->
|
|
||||||
<script type="text/x-red" data-help-name="discrete-in">
|
<script type="text/x-red" data-help-name="discrete-in">
|
||||||
<p>
|
<p>
|
||||||
Discrete input for the Beaglebone Black. Sends a message on the first output
|
Discrete input for the Beaglebone Black. Sends a message on the first output
|
||||||
@ -88,7 +92,7 @@ of the active time, not the pin state sent on the first output
|
|||||||
</p>
|
</p>
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<!-- Register the node -->
|
<!-- Register discrete-in -->
|
||||||
<script type="text/javascript">
|
<script type="text/javascript">
|
||||||
RED.nodes.registerType('discrete-in', {
|
RED.nodes.registerType('discrete-in', {
|
||||||
category: 'advanced-input', // the palette category
|
category: 'advanced-input', // the palette category
|
||||||
@ -111,3 +115,113 @@ of the active time, not the pin state sent on the first output
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
<!-- Edit dialog for pulse-in -->
|
||||||
|
<script type="text/x-red" data-template-name="pulse-in">
|
||||||
|
<div class="form-row">
|
||||||
|
<label for="node-input-pin"><i class="icon-asterisk"></i>Input pin</label>
|
||||||
|
<select type="text" id="node-input-pin" style="width: 200px;">
|
||||||
|
<option value="">select pin</option>
|
||||||
|
<option value="P8_7">GPIO2_2 (P8 pin 7)</option>
|
||||||
|
<option value="P8_8">GPIO2_3 (P8 pin 8)</option>
|
||||||
|
<option value="P8_9">GPIO2_5 (P8 pin 9)</option>
|
||||||
|
<option value="P8_10">GPIO2_4 (P8 pin 10)</option>
|
||||||
|
<option value="P8_11">GPIO1_13 (P8 pin 11)</option>
|
||||||
|
<option value="P8_12">GPIO1_12 (P8 pin 12)</option>
|
||||||
|
<option value="P8_13">GPIO0_23 (P8 pin 13)</option>
|
||||||
|
<option value="P8_14">GPIO0_26 (P8 pin 14)</option>
|
||||||
|
<option value="P8_15">GPIO1_15 (P8 pin 15)</option>
|
||||||
|
<option value="P8_16">GPIO1_14 (P8 pin 16)</option>
|
||||||
|
<option value="P8_17">GPIO0_27 (P8 pin 17)</option>
|
||||||
|
<option value="P8_18">GPIO2_1 (P8 pin 18)</option>
|
||||||
|
<option value="P8_19">GPIO0_22 (P8 pin 19)</option>
|
||||||
|
<option value="P8_26">GPIO1_29 (P8 pin 26)</option>
|
||||||
|
<option value="P9_11">GPIO0_30 (P9 pin 11)</option>
|
||||||
|
<option value="P9_12">GPIO1_28 (P9 pin 12)</option>
|
||||||
|
<option value="P9_13">GPIO0_31 (P9 pin 13)</option>
|
||||||
|
<option value="P9_14">GPIO1_18 (P9 pin 14)</option>
|
||||||
|
<option value="P9_15">GPIO1_16 (P9 pin 15)</option>
|
||||||
|
<option value="P9_16">GPIO1_19 (P9 pin 16)</option>
|
||||||
|
<option value="P9_17">GPIO0_5 (P9 pin 17)</option>
|
||||||
|
<option value="P9_18">GPIO0_4 (P9 pin 18)</option>
|
||||||
|
<option value="P9_21">GPIO0_3 (P9 pin 21)</option>
|
||||||
|
<option value="P9_22">GPIO0_2 (P9 pin 22)</option>
|
||||||
|
<option value="P9_23">GPIO1_17 (P9 pin 23)</option>
|
||||||
|
<option value="P9_24">GPIO0_15 (P9 pin 24)</option>
|
||||||
|
<option value="P9_26">GPIO0_14 (P9 pin 26)</option>
|
||||||
|
<option value="P9_27">GPIO3_19 (P9 pin 27)</option>
|
||||||
|
<option value="P9_30">GPIO3_16 (P9 pin 30)</option>
|
||||||
|
<option value="P9_41">GPIO0_20 (P9 pin 41)</option>
|
||||||
|
<option value="P9_42">GPIO0_7 (P9 pin 42)</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div class="form-row">
|
||||||
|
<label for="node-input-countType">Count</label>
|
||||||
|
<select type="text" id="node-input-countType" style="width: 100px;">
|
||||||
|
<option value="pulse">pulses</option>
|
||||||
|
<option value="edge">edges</option>
|
||||||
|
</select>
|
||||||
|
<div class="form-row">
|
||||||
|
<label for="node-input-countUnit"><i class="icon-repeat"></i> Scaling</label>
|
||||||
|
<input id="node-input-countUnit" type="text" style="width: 65px">
|
||||||
|
<label> units per count</label>
|
||||||
|
</div>
|
||||||
|
<div class="form-row">
|
||||||
|
<label for="node-input-countRate"><i class="icon-repeat"></i> Rate</label>
|
||||||
|
<input id="node-input-countRate" type="text" style="width: 65px">
|
||||||
|
<label> units per count/second</label>
|
||||||
|
</div>
|
||||||
|
<div class="form-row">
|
||||||
|
<label for="node-input-updateInterval"><i class="icon-repeat"></i> Update at</label>
|
||||||
|
<input id="node-input-updateInterval" type="text" style="width: 65px">
|
||||||
|
<label>sec intervals</label>
|
||||||
|
</div>
|
||||||
|
<div class="form-row">
|
||||||
|
<label for="node-input-topic"><i class="icon-tasks"></i> Topic</label>
|
||||||
|
<input type="text" id="node-input-topic" placeholder="Topic">
|
||||||
|
</div>
|
||||||
|
<div class="form-row">
|
||||||
|
<label for="node-input-name"><i class="icon-tag"></i> Name</label>
|
||||||
|
<input type="text" id="node-input-name" placeholder="Name">
|
||||||
|
</div>
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<!-- Help text for pulse-in -->
|
||||||
|
<script type="text/x-red" data-help-name="pulse-in">
|
||||||
|
<p>
|
||||||
|
Pulse input for the Beaglebone Black. Counts input pulses or pulse edges, outputs
|
||||||
|
the total counts and the rate of counts/second, each with scaling applied.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
Sends the total count message on the first output, and the current count
|
||||||
|
rate message on the second output, at the chosen interval. Any input message
|
||||||
|
will reset the total count
|
||||||
|
</p>
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<!-- Register pulse-in -->
|
||||||
|
<script type="text/javascript">
|
||||||
|
RED.nodes.registerType('pulse-in', {
|
||||||
|
category: 'advanced-input', // the palette category
|
||||||
|
color:"#c6dbef",
|
||||||
|
defaults: { // defines the editable properties of the node
|
||||||
|
name: { value:"" }, // along with default values.
|
||||||
|
updateInterval: { value:2, required:true, validate:RED.validators.number() },
|
||||||
|
topic: { value:"" },
|
||||||
|
pin: { value:"", required:true },
|
||||||
|
countType: { value:"pulse", required:true },
|
||||||
|
countUnit: { value:1, required:true, validate:RED.validators.number() },
|
||||||
|
countRate: { value:1, required:true, validate:RED.validators.number() }
|
||||||
|
},
|
||||||
|
inputs:1, // set the number of inputs - only 0 or 1
|
||||||
|
outputs:2, // set the number of outputs - 0 to n
|
||||||
|
icon: "arrow-in.png", // set the icon (held in public/icons)
|
||||||
|
label: function() { // sets the default label contents
|
||||||
|
return this.name || "discrete-in: " + this.pin;
|
||||||
|
},
|
||||||
|
labelStyle: function() { // sets the class to apply to the label
|
||||||
|
return this.name ? "node_label_italic" : "";
|
||||||
|
}
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
@ -24,7 +24,7 @@ try {
|
|||||||
require("util").log("[145-digital-in] Error: cannot find module 'bonescript'");
|
require("util").log("[145-digital-in] Error: cannot find module 'bonescript'");
|
||||||
}
|
}
|
||||||
|
|
||||||
// The node constructor
|
// discrete-in node constructor
|
||||||
function DiscreteInputNode(n) {
|
function DiscreteInputNode(n) {
|
||||||
RED.nodes.createNode(this, n);
|
RED.nodes.createNode(this, n);
|
||||||
|
|
||||||
@ -36,26 +36,57 @@ function DiscreteInputNode(n) {
|
|||||||
else
|
else
|
||||||
this.activeState = 1;
|
this.activeState = 1;
|
||||||
this.updateInterval = n.updateInterval * 1000; // How often to send totalActiveTime messages
|
this.updateInterval = n.updateInterval * 1000; // How often to send totalActiveTime messages
|
||||||
|
this.debounce = n.debounce; // Enable switch contact debouncing algorithm
|
||||||
|
|
||||||
this.interruptAttached = false; // Flag: should we detach interrupt when we are closed?
|
this.interruptAttached = false; // Flag: should we detach interrupt when we are closed?
|
||||||
this.intervalId = null; // Remember the timer ID so we can delete it when we are closed
|
this.intervalId = null; // Remember the timer ID so we can delete it when we are closed
|
||||||
this.currentState = 0; // The pin input state "1" or "0"
|
this.currentState = 0; // The pin input state "1" or "0"
|
||||||
this.lastActiveTime = NaN; // The date (in ms since epoch) when the pin last went high
|
this.lastActiveTime = NaN; // The date (in ms since epoch) when the pin last went high
|
||||||
|
// switch to process.hrtime()
|
||||||
this.totalActiveTime = 0; // The total time in ms that the pin has been high (since reset)
|
this.totalActiveTime = 0; // The total time in ms that the pin has been high (since reset)
|
||||||
this.starting = true;
|
this.starting = true;
|
||||||
|
this.debouncing = false; // True after a change of state while waiting for the 7ms debounce time to elapse
|
||||||
|
|
||||||
// Define 'node' to allow us to access 'this' from within callbacks (the 'var' is essential -
|
// Define 'node' to allow us to access 'this' from within callbacks (the 'var' is essential -
|
||||||
// otherwise there is only one global 'node' for all instances of DiscreteInputNode!)
|
// otherwise there is only one global 'node' for all instances of DiscreteInputNode!)
|
||||||
var node = this;
|
var node = this;
|
||||||
|
|
||||||
// This function is called whenever the input pin changes state. We update the currentState
|
// This function is called by the input pin change-of-state interrupt. If
|
||||||
// and the ActiveTime variables, and send a message on the first output with the new state
|
// debounce is disabled, send the output message. Otherwise, if we are
|
||||||
// Note: this function gets called spuriously when the interrupt is first enabled: in this
|
// currently debouncing, ignore this interrupt. If we are not debouncing,
|
||||||
// case x.value is undefined - we must test for this
|
// schedule a re-read of the input pin in 7ms time, and set the debouncing flag
|
||||||
|
// Note: this function gets called spuriously when the interrupt is first enabled:
|
||||||
|
// in this case x.value is undefined - we must test for this
|
||||||
var interruptCallback = function (x) {
|
var interruptCallback = function (x) {
|
||||||
if (x.value != undefined && node.currentState !== Number(x.value)) {
|
if (x.value !== undefined && node.currentState !== Number(x.value)) {
|
||||||
|
if (node.debounce) {
|
||||||
|
if (node.debouncing === false) {
|
||||||
|
node.debouncing = true;
|
||||||
|
setTimeout(function () { bonescript.digitalRead(node.pin, debounceCallback); }, 7);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
sendStateMessage(x);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// This function is called approx 7ms after a potential change-of-state which we
|
||||||
|
// are debouncing. Terminate the debounce, and send a message if the state has
|
||||||
|
// actually changed
|
||||||
|
var debounceCallback = function (x) {
|
||||||
|
node.debouncing = false;
|
||||||
|
if (x.value !== undefined && node.currentState !== Number(x.value)) {
|
||||||
|
sendStateMessage(x);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// This function is called when either the interruptCallback or the debounceCallback
|
||||||
|
// have determined we have a 'genuine' change of state. Update the currentState and
|
||||||
|
// ActiveTime variables, and send a message on the first output with the new state
|
||||||
|
var sendStateMessage = function (x) {
|
||||||
node.currentState = Number(x.value);
|
node.currentState = Number(x.value);
|
||||||
var now = Date.now();
|
var now = Date.now();
|
||||||
|
// switch to process.hrtime()
|
||||||
if (node.currentState === node.activeState) {
|
if (node.currentState === node.activeState) {
|
||||||
node.lastActiveTime = now;
|
node.lastActiveTime = now;
|
||||||
} else if (!isNaN(node.lastActiveTime)) {
|
} else if (!isNaN(node.lastActiveTime)) {
|
||||||
@ -65,7 +96,6 @@ function DiscreteInputNode(n) {
|
|||||||
msg.topic = node.topic;
|
msg.topic = node.topic;
|
||||||
msg.payload = node.currentState;
|
msg.payload = node.currentState;
|
||||||
node.send([msg, null]);
|
node.send([msg, null]);
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// This function is called by the timer. It updates the ActiveTime variables, and sends a
|
// This function is called by the timer. It updates the ActiveTime variables, and sends a
|
||||||
@ -75,21 +105,31 @@ function DiscreteInputNode(n) {
|
|||||||
var now = Date.now();
|
var now = Date.now();
|
||||||
node.totalActiveTime += now - node.lastActiveTime;
|
node.totalActiveTime += now - node.lastActiveTime;
|
||||||
node.lastActiveTime = now;
|
node.lastActiveTime = now;
|
||||||
|
// switch to process.hrtime()
|
||||||
}
|
}
|
||||||
var msg = {};
|
var msg = {};
|
||||||
msg.topic = node.topic;
|
msg.topic = node.topic;
|
||||||
msg.payload = node.totalActiveTime / 1000;
|
msg.payload = node.totalActiveTime / 1000;
|
||||||
node.send([null, msg]);
|
node.send([null, msg]);
|
||||||
// Re-synchronise the pin state if we have missed a state change interrupt for some reason
|
// Re-synchronise the pin state if we have missed a state change interrupt for some
|
||||||
|
// reason, and we are not in the process of debouncing one
|
||||||
|
if (node.debouncing === false) {
|
||||||
bonescript.digitalRead(node.pin, interruptCallback);
|
bonescript.digitalRead(node.pin, interruptCallback);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// This function is called when we receive an input message. Clear the ActiveTime variables
|
// This function is called when we receive an input message. If the topic is "load"
|
||||||
// (so we start counting from zero again)
|
// set the totalActiveTime to the numeric value of the payload, if possible. Otherwise
|
||||||
var inputCallback = function (msg) {
|
// clear the totalActiveTime (so we start counting from zero again)
|
||||||
|
var inputCallback = function (ipMsg) {
|
||||||
|
if (String(ipMsg.topic).search("load") < 0 || isFinite(ipMsg.payload) == false) {
|
||||||
node.totalActiveTime = 0;
|
node.totalActiveTime = 0;
|
||||||
|
} else {
|
||||||
|
node.totalActiveTime = Number(ipMsg.payload);
|
||||||
|
}
|
||||||
if (node.currentState === node.activeState) {
|
if (node.currentState === node.activeState) {
|
||||||
node.lastActiveTime = Date.now();
|
node.lastActiveTime = Date.now();
|
||||||
|
// switch to process.hrtime()
|
||||||
}
|
}
|
||||||
if (node.starting) {
|
if (node.starting) {
|
||||||
node.starting = false;
|
node.starting = false;
|
||||||
@ -113,6 +153,7 @@ function DiscreteInputNode(n) {
|
|||||||
node.currentState = Number(x.value);
|
node.currentState = Number(x.value);
|
||||||
if (node.currentState === node.activeState) {
|
if (node.currentState === node.activeState) {
|
||||||
node.lastActiveTime = Date.now();
|
node.lastActiveTime = Date.now();
|
||||||
|
// switch to process.hrtime()
|
||||||
}
|
}
|
||||||
// Attempt to attach a change-of-state interrupt handler to the pin. If we succeed,
|
// Attempt to attach a change-of-state interrupt handler to the pin. If we succeed,
|
||||||
// set the input event and interval handlers, then send an initial message with the
|
// set the input event and interval handlers, then send an initial message with the
|
||||||
@ -132,8 +173,89 @@ function DiscreteInputNode(n) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Node constructor for pulse-in
|
||||||
|
// The node constructor
|
||||||
|
function PulseInputNode(n) {
|
||||||
|
RED.nodes.createNode(this, n);
|
||||||
|
|
||||||
|
// Store local copies of the node configuration (as defined in the .html)
|
||||||
|
this.topic = n.topic; // the topic is not currently used
|
||||||
|
this.pin = n.pin; // The Beaglebone Black pin identifying string
|
||||||
|
this.updateInterval = n.updateInterval * 1000; // How often to send totalActiveTime messages
|
||||||
|
this.countType = n.countType;
|
||||||
|
this.countUnit = n.countUnit;
|
||||||
|
this.countRate = n.countRate;
|
||||||
|
|
||||||
|
this.interruptAttached = false; // Flag: should we detach interrupt when we are closed?
|
||||||
|
this.intervalId = null; // Remember the timer ID so we can delete it when we are closed
|
||||||
|
|
||||||
|
this.pulseTime = [[NaN, NaN], [NaN, NaN]];
|
||||||
|
this.pulseCount = 0;
|
||||||
|
|
||||||
|
// Define 'node' to allow us to access 'this' from within callbacks (the 'var' is essential -
|
||||||
|
// otherwise there is only one global 'node' for all instances of DiscreteInputNode!)
|
||||||
|
var node = this;
|
||||||
|
|
||||||
|
var interruptCallback = function (x) {
|
||||||
|
node.pulseTime = node.pulseTime[[1], process.hrtime()];
|
||||||
|
node.pulseCount = node.pulseCount + 1;
|
||||||
|
};
|
||||||
|
|
||||||
|
var inputCallback = function (msg) {
|
||||||
|
if (String(msg.topic).search("load") < 0 || isFinite(msg.payload) == false) {
|
||||||
|
node.pulseCount = 0;
|
||||||
|
} else {
|
||||||
|
node.pulseCount = Number(msg.payload);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
var timerCallback = function () {
|
||||||
|
var now = process.hrtime();
|
||||||
|
var lastTime = pulseTime[1][0] - pulseTime[0][0] + (pulseTime[1][1] - pulseTime[0][1]) / 1e9;
|
||||||
|
var thisTime = now[0] - pulseTime[1][0] + (now[1] - pulseTime[1][1]) / 1e9;
|
||||||
|
var msg = [{ topic:node.topic }, { topic:node.topic }];
|
||||||
|
msg[0].payload = node.countUnit * node.pulseCount;
|
||||||
|
msg[1].payload = node.countRate / Math.max(thisTime, lastTime);
|
||||||
|
node.send(msg);
|
||||||
|
};
|
||||||
|
|
||||||
|
// If we have a valid pin, set it as an input and read the (digital) state
|
||||||
|
if (["P8_7", "P8_8", "P8_9", "P8_10", "P8_11", "P8_12", "P8_13", "P8_14", "P8_15",
|
||||||
|
"P8_16", "P8_17", "P8_18", "P8_19", "P8_26", "P9_11", "P9_12", "P9_13", "P9_14",
|
||||||
|
"P9_15", "P9_16", "P9_17", "P9_18", "P9_21", "P9_22", "P9_23", "P9_24", "P9_26",
|
||||||
|
"P9_27", "P9_30", "P9_41", "P9_42"].indexOf(node.pin) >= 0) {
|
||||||
|
// Don't set up interrupts & intervals until after the close event handler has been installed
|
||||||
|
process.nextTick(function () {
|
||||||
|
bonescript.pinMode(node.pin, bonescript.INPUT);
|
||||||
|
bonescript.digitalRead(node.pin, function (x) {
|
||||||
|
// Initialise the currentState based on the value read
|
||||||
|
node.currentState = Number(x.value);
|
||||||
|
// Attempt to attach a change-of-state interrupt handler to the pin. If we succeed,
|
||||||
|
// set the input event and interval handlers, then send an initial message with the
|
||||||
|
// pin state on the first output
|
||||||
|
var interruptType;
|
||||||
|
if (node.countType == "pulse") {
|
||||||
|
interruptType = bonescript.FALLING ;
|
||||||
|
} else {
|
||||||
|
interruptType = bonescript.CHANGE;
|
||||||
|
}
|
||||||
|
if (bonescript.attachInterrupt(node.pin, true, interruptType, interruptCallback)) {
|
||||||
|
node.interruptAttached = true;
|
||||||
|
node.on("input", inputCallback);
|
||||||
|
node.intervalId = setInterval(timerCallback, node.updateInterval);
|
||||||
|
} else {
|
||||||
|
node.error("Failed to attach interrupt");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
node.error("Unconfigured input pin");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Register the node by name. This must be called before overriding any of the Node functions.
|
// Register the node by name. This must be called before overriding any of the Node functions.
|
||||||
RED.nodes.registerType("discrete-in", DiscreteInputNode);
|
RED.nodes.registerType("discrete-in", DiscreteInputNode);
|
||||||
|
RED.nodes.registerType("pulse-in", PulseInputNode);
|
||||||
|
|
||||||
// On close, detach the interrupt (if we attached one) and clear the interval (if we set one)
|
// On close, detach the interrupt (if we attached one) and clear the interval (if we set one)
|
||||||
DiscreteInputNode.prototype.close = function () {
|
DiscreteInputNode.prototype.close = function () {
|
||||||
@ -144,3 +266,13 @@ DiscreteInputNode.prototype.close = function () {
|
|||||||
clearInterval(this.intervalId);
|
clearInterval(this.intervalId);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// On close, detach the interrupt (if we attached one) and clear the interval (if we set one)
|
||||||
|
PulseInputNode.prototype.close = function () {
|
||||||
|
if (this.interruptAttached) {
|
||||||
|
bonescript.detachInterrupt(this.pin);
|
||||||
|
}
|
||||||
|
if (this.intervalId !== null) {
|
||||||
|
clearInterval(this.intervalId);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user