Got to start somewhere

This commit is contained in:
Nicholas O'Leary
2013-09-05 15:02:48 +01:00
commit 32796dd74c
155 changed files with 21836 additions and 0 deletions

View File

@@ -0,0 +1,148 @@
<!--
Copyright 2013 IBM Corp.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<script type="text/x-red" data-template-name="arduino in">
<div class="form-row">
<label for="node-input-arduino"><i class="icon-tasks"></i> Arduino</label>
<input type="text" id="node-input-arduino">
</div>
<div class="form-row">
<label for="node-input-pin"><i class="icon-asterisk"></i> Pin</label>
<input type="text" id="node-input-pin" placeholder="2">
</div>
<div class="form-row">
<label for="node-input-state"><i class="icon-wrench"></i> Type</label>
<select type="text" id="node-input-state" style="width: 150px;">
<option value="INPUT">Digital pin</option>
<option value="ANALOG">Analogue pin</option>
</select>
</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>
<script type="text/x-red" data-help-name="arduino in">
<p>Arduino input node. Connects to local Arduino and monitors the selected pin for changes. Uses <a href="http://firmata.org/" target="_new"><i>Firmata</i>.</a></p>
<p>You can select either Digital or Analogue input. Outputs the value read as <b>msg.payload</b> and the pin number as <b>msg.topic</b>.</p>
<p>It only outputs on a change of value - fine for digital inputs, but you can get a lot of data from analogue pins which you must then handle.</p>
<p>You can set the sample rate in ms from 20 to 65535.</p>
</script>
<script type="text/javascript">
RED.nodes.registerType('arduino in',{
category: 'advanced-input',
color:"#c6dbef",
defaults: {
name: {value:""},
pin: {value:"",required:true},
state: {value:"INPUT",required:true},
arduino: {type:"arduino-board",required:true}
},
inputs:0,
outputs:1,
icon: "arduino.png",
label: function() {
var a = "";
if (this.state == "ANALOG") a = "A";
return this.name||"Pin: "+a+this.pin;
},
labelStyle: function() {
return this.name?"node_label_italic":"";
}
});
</script>
<script type="text/x-red" data-template-name="arduino out">
<div class="form-row">
<label for="node-input-arduino"><i class="icon-tasks"></i> Arduino</label>
<input type="text" id="node-input-arduino">
</div>
<div class="form-row">
<label for="node-input-pin"><i class="icon-asterisk"></i> Pin</label>
<input type="text" id="node-input-pin" placeholder="13">
</div>
<div class="form-row">
<label for="node-input-state"><i class="icon-wrench"></i> Type</label>
<select type="text" id="node-input-state" style="width: 150px;">
<option value="OUTPUT">Digital (0/1)</option>
<option value="PWM">Analogue (0-255)</option>
<option value="SERVO">Servo (0-180)</option>
</select>
</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>
<script type="text/x-red" data-help-name="arduino out">
<p>Arduino output node. Connects to local Arduino and writes to the selected digital pin. Uses <a href="http://firmata.org/" target="_new"><i>Firmata</i>.</a></p>
<p>You can select Digital, Analogue (PWM) or Servo type outputs. Expects a numeric value in <b>msg.payload</b>. The pin number is set in the properties panel.</p>
</script>
<script type="text/javascript">
RED.nodes.registerType('arduino out',{
category: 'advanced-output',
color:"#c6dbef",
defaults: {
name: {value:""},
pin: {value:""},
state: {value:"",required:true},
arduino: {type:"arduino-board",required:true}
},
inputs:1,
outputs:0,
icon: "arduino.png",
align: "right",
label: function() {
return this.name||"Pin: "+this.pin;
},
labelStyle: function() {
return this.name?"node_label_italic":"";
}
});
</script>
<script type="text/x-red" data-template-name="arduino-board">
<div class="form-row">
<label for="node-config-input-device"><i class="icon-bullhorn"></i> Arduino Port</label>
<input type="text" id="node-config-input-device" placeholder="ttyU" style="width:50%;">
</div>
<div class="form-row">
<label for="node-config-input-repeat"><i class="icon-repeat"></i> Sample (ms)</label>
<input type="text" id="node-config-input-repeat" placeholder="25">
</div>
<!-- <div class="form-row">
<label for="node-config-input-baud"><i class="icon-bullhorn"></i> Baudrate</label>
<input type="text" id="node-config-input-baud" placeholder="115200" style="width:50%;">
</div> -->
</script>
<script type="text/javascript">
RED.nodes.registerType('arduino-board',{
category: 'config',
defaults: {
//baud: {baud:"57600",required:true},
repeat: {value:"25",required:true,validate:RED.validators.number()},
device: {value:"",required:true}
},
label: function() {
return this.device||"arduino";
}
});
</script>

View File

@@ -0,0 +1,167 @@
/**
* Copyright 2013 IBM Corp.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
**/
var RED = require("../../red/red");
var util = require("util");
var firmata = require("firmata");
var arduinoReady = false;
var thisboard = null;
// The Board Definition - this opens (and closes) the connection
function ArduinoNode(n) {
RED.nodes.createNode(this,n);
this.device = n.device;
this.repeat = n.repeat||25;
util.log("[firmata] Opening"+this.device);
// var tou = setInterval(function() {
// if (!arduinoReady) {
// clearInterval(tou);
arduinoReady = false;
if (thisboard == null) {
this.board = new firmata.Board(this.device, function(err) {
if (err) {
util.log("[firmata] "+err);
return;
}
arduinoReady = true;
util.log('[firmata] Arduino connected');
});
thisboard = this.board;
}
else {
util.log("[firmata] Arduino already connected");
this.board = thisboard;
console.log(this.board._events);
this.board.removeAllListeners();
arduinoReady = true;
}
// } else { util.log("[firmata] Waiting for Firmata"); }
// }, 1000); // wait for firmata to disconnect from arduino
this._close = function() {
//this.board.sp.close(function() { console.log("[firmata] Serial port closed"); arduinoReady = false; });
util.log("[firmata] Stopped");
}
}
RED.nodes.registerType("arduino-board",ArduinoNode);
ArduinoNode.prototype.close = function() {
this._close();
}
// The Input Node
function DuinoNodeIn(n) {
RED.nodes.createNode(this,n);
this.buttonState = -1;
this.pin = n.pin;
this.state = n.state;
this.arduino = n.arduino;
this.serverConfig = RED.nodes.getNode(this.arduino);
this.board = this.serverConfig.board;
this.repeat = this.serverConfig.repeat;
var node = this;
var tout = setInterval(function() {
if (arduinoReady) {
clearInterval(tout);
console.log(node.state,node.pin,node.board.MODES[node.state]);
node.board.pinMode(node.pin, node.board.MODES[node.state]);
node.board.setSamplingInterval(node.repeat);
var oldrdg = "";
if (node.state == "ANALOG") {
node.board.analogRead(node.pin, function(data) {
var msg = {payload:data, topic:"A"+node.pin};
if (data != oldrdg) {
node.send(msg);
oldrdg = data;
}
});
}
else {
node.board.digitalRead(node.pin, function(data) {
var msg = {payload:data, topic:node.pin};
node.send(msg);
});
}
}
else { node.log("Waiting for Arduino"); }
}, 2000); // loop to wait for firmata to connect to arduino
this._close = function() {
clearInterval(this._interval);
util.log("[firmata] input eventlistener stopped");
}
}
RED.nodes.registerType("arduino in",DuinoNodeIn);
DuinoNodeIn.prototype.close = function() {
this._close();
}
// The Output Node
function DuinoNodeOut(n) {
RED.nodes.createNode(this,n);
this.buttonState = -1;
this.pin = n.pin;
this.state = n.state;
this.arduino = n.arduino;
this.serverConfig = RED.nodes.getNode(this.arduino);
this.board = this.serverConfig.board;
var node = this;
this.on("input", function(msg) {
//console.log(msg);
if (arduinoReady) {
if (node.state == "OUTPUT") {
if ((msg.payload == true)||(msg.payload == 1)||(msg.payload.toString().toLowerCase() == "on")) {
node.board.digitalWrite(node.pin, node.board.HIGH);
}
if ((msg.payload == false)||(msg.payload == 0)||(msg.payload.toString().toLowerCase() == "off")) {
node.board.digitalWrite(node.pin, node.board.LOW);
}
}
if (node.state == "PWM") {
msg.payload = msg.payload * 1;
if ((msg.payload >= 0) && (msg.payload <= 255)) {
//console.log(msg.payload, node.pin);
node.board.servoWrite(node.pin, msg.payload);
}
}
if (node.state == "SERVO") {
msg.payload = msg.payload * 1;
if ((msg.payload >= 0) && (msg.payload <= 180)) {
//console.log(msg.payload, node.pin);
node.board.servoWrite(node.pin, msg.payload);
}
}
}
//else { console.log("Arduino not ready"); }
});
var touo = setInterval(function() {
if (arduinoReady) {
clearInterval(touo);
//console.log(node.state,node.pin,node.board.MODES[node.state]);
node.board.pinMode(node.pin, node.board.MODES[node.state]);
}
}, 5000); // loop to wait for firmata to connect to arduino
}
RED.nodes.registerType("arduino out",DuinoNodeOut);

View File

@@ -0,0 +1,69 @@
<!--
Copyright 2013 IBM Corp.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<script type="text/x-red" data-template-name="rpi-gpio in">
<div class="form-row">
<label for="node-input-pin"><i class="icon-asterisk"></i> Pin</label>
<select type="text" id="node-input-pin" style="width: 150px;">
<option value="7">7</option>
<option value="11">11</option>
<option value="12">12</option>
<option value="13">13</option>
<option value="15">15</option>
<option value="16">16</option>
<option value="18">18</option>
<option value="22">22</option>
</select>
</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>
<div class="form-row">
<label for="node-input-resistor"><i class=" icon-resize-full"></i> Resistor?</label>
<select type="text" id="node-input-resistor" style="width: 150px;">
<option value="no">no</option>
<option value="pullup">pullup</option>
<option value="pulldown">pulldown</option>
</select>
</div>
<div class="form-tips">Tip: if pull up/down resistor is selected, the <code>gpio-admin</code> command <em>must</em> be used
to do the actual enabling. If 'no' resistor is selected, nothing further needs to be done
to use this node. See <code>man gpio-admin</code> for more details.</div>
</script>
<script type="text/javascript">
RED.nodes.registerType('rpi-gpio in',{
category: 'advanced-input',
color:"#c6dbef",
defaults: {
name: { value:""},
resistor: { value: "no"},
pin: {value:"",required:true},
},
inputs:0,
outputs:1,
icon: "rpi.png",
label: function() {
return this.name||"Pin: "+this.pin;
//+(this.resistor == "no"?"":" ("+(this.resistor=="pullup"?"":"&darr;")+")");
},
labelStyle: function() {
return this.name?"node_label_italic":"";
}
});
</script>

View File

@@ -0,0 +1,71 @@
/**
* Copyright 2013 IBM Corp.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
**/
var RED = require("../../red/red");
var gpio = require("pi-gpio");
function GPIOInNode(n) {
RED.nodes.createNode(this,n);
this.buttonState = -1;
this.pin = n.pin;
this.resistor = n.resistor;
var node = this;
if (this.pin) {
var setupPin = function(err) {
if (err) {
node.error(err);
} else {
node._interval = setInterval(function(){
gpio.read(node.pin, function(err, value) {
if(err){
node.error(err);
} else{
if(node.buttonState !== value){
var previousState = node.buttonState;
node.buttonState = value;
if (previousState !== -1) {
var msg = {payload:node.buttonState};
node.send(msg);
}
}
}
});
}, 50);
}
};
if (this.resistor == "no") {
gpio.open(this.pin,"input",setupPin());
} else {
// Assume enabled externally via gpio-admin
setupPin();
}
} else {
this.error("Invalid GPIO pin: "+this.pin);
}
}
RED.nodes.registerType("rpi-gpio in",GPIOInNode);
GPIOInNode.prototype.close = function() {
clearInterval(this._interval);
if (this.resistor == "no") {
gpio.close(this.pin);
}
}

View File

@@ -0,0 +1,59 @@
<!--
Copyright 2013 IBM Corp.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<script type="text/x-red" data-template-name="rpi-gpio out">
<div class="form-row">
<label for="node-input-pin"><i class="icon-asterisk"></i> Pin</label>
<select type="text" id="node-input-pin" style="width: 150px;">
<option value="7">7</option>
<option value="11">11</option>
<option value="12">12</option>
<option value="13">13</option>
<option value="15">15</option>
<option value="16">16</option>
<option value="18">18</option>
<option value="22">22</option>
</select>
</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>
<script type="text/javascript">
RED.nodes.registerType('rpi-gpio out',{
category: 'advanced-output',
color:"#c6dbef",
defaults: {
name: { value:""},
resistor: { value: "no"},
pin: {value:"",required:true},
},
inputs:1,
outputs:0,
icon: "rpi.png",
align: "right",
label: function() {
return this.name||"Pin: "+this.pin;
//+(this.resistor == "no"?"":" ("+(this.resistor=="pullup"?"":"&darr;")+")");
},
labelStyle: function() {
return this.name?"node_label_italic":"";
}
});
</script>

View File

@@ -0,0 +1,51 @@
/**
* Copyright 2013 IBM Corp.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
**/
var RED = require("../../red/red");
var gpio = require("pi-gpio");
function GPIOOutNode(n) {
RED.nodes.createNode(this,n);
this.pin = n.pin;
var node = this;
if (this.pin) {
gpio.open(this.pin,"output",function(err) {
if (err) {
node.error(err);
} else {
node.on("input",function(msg) {
gpio.write(node.pin,msg.payload,function(err) {
if (err) node.error(err);
});
});
}
});
} else {
this.error("Invalid GPIO pin: "+this.pin);
}
}
RED.nodes.registerType("rpi-gpio out",GPIOOutNode);
GPIOOutNode.prototype.close = function() {
gpio.close(this.pin);
}

View File

@@ -0,0 +1,47 @@
<!--
Copyright 2013 IBM Corp.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<script type="text/x-red" data-template-name="blink">
<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>
<div class="form-tips">Expects a msg.payload with three part csv string of r,g,b.</div>
</script>
<script type="text/x-red" data-help-name="blink">
<p>Thingm Blink1 output node. Expects a msg.payload with a three part csv string of r,g,b.</p>
</script>
<script type="text/javascript">
RED.nodes.registerType('blink',{
category: 'output',
color:"cornsilk",
defaults: {
name: {value:""}
},
inputs:1,
outputs:0,
icon: "arrow-in.png",
align: "right",
label: function() {
return this.name||"blink1";
},
labelStyle: function() {
return (this.name||!this.topic)?"node_label_italic":"";
}
});
</script>

View File

@@ -0,0 +1,46 @@
/**
* Copyright 2013 IBM Corp.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
**/
var RED = require("../../red/red");
var Blink1 = require("node-blink1");
function Blink1Node(n) {
RED.nodes.createNode(this,n);
var node = this;
try {
var blink1 = new Blink1.Blink1();
node.log("started");
this.on("input", function(msg) {
if (msg != null) {
var rgb = msg.payload.split(',');
// only do it if three parameters...
if (rgb.length == 3) {
blink1.setRGB( (rgb[0]*1)&255, (rgb[1]*1)&255, (rgb[2]*1)&255 );
}
else {
//let Andy do fancy colours by name here if he wants...
node.log("received "+msg.payload);
}
}
});
}
catch(e) {
node.error(e);
}
}
RED.nodes.registerType("blink",Blink1Node);