UNPKG

node-red-node-arduino

Version:

A Node-RED Node, to talk to a chip as I/O extender, which is running Firmata firmware

250 lines (228 loc) 12.4 kB
<!-- This is THE board, which is running Firmata firmware. Tipically an Arduino or RPi-Pico --> <script type="text/html" data-template-name="arduino-board"> <div class="form-row"> <label for="node-config-input-name"><i class="fa fa-tag"></i> <span data-i18n="arduino.label.name"></span></label> <input type="text" id="node-config-input-name" style="width:60%;"/> </div> <div class="form-row"> <label for="node-config-input-device"><i class="fa fa-random"></i> <span data-i18n="arduino.label.port"></span></label> <input type="text" id="node-config-input-device" style="width:60%;" data-i18n="[placeholder]arduino.placeholder.port"/> <a id="node-config-lookup-serial" class="red-ui-button"><i id="node-config-lookup-serial-icon" class="fa fa-search"></i></a> <div class="form-tips"><span data-i18n="[html]arduino.tip.port"></span></div> </div> <div class="form-row"> <div class="form-tips"><span data-i18n="[html]arduino.tip.otherboards"></span></div> </div> <div class="form-row"> <label for="node-config-input-samplingInt" style="width:150px;"><i class="fa fa-circle"></i> <span data-i18n="arduino.label.samplingInt"></span></label> <input type="number" id="node-config-input-samplingInt" style="width:20%;" data-i18n="[placeholder]arduino.placeholder.samplingInt" min=10 max=65500 /> mS </div> <div class="form-row"> <label for="node-config-input-log2consol"><i class="icon-bookmark"></i>Log to console</label> <input type="checkbox" id="node-config-input-log2consol"> <div class="form-tips"><span data-i18n="[html]arduino.tip.log2consol"></span></div> </div> <!-- arduino.tip.... strings are stored at: 35-arduino.json file --> </script> <script type="text/javascript"> RED.nodes.registerType('arduino-board',{ category: 'config', defaults: { device : {value: "" , required: true }, name : {value: "" , required: false}, samplingInt: {value: 250 , required: false}, // will read analog inputs 4x / sec by default. Can be 19-65500 log2consol : {value: false, required: false} }, label: function() { if (this.name !== "") return this.name else return this.device || "firmata-board-" + this.id; // (bad naming :-( ) device should be: "port" }, oneditprepare: function() { try { $("#node-config-input-device").autocomplete( "destroy" ); // Remove auto-complete functionality from an <input>. } catch(err) { }; $("#node-config-lookup-serial").click(async function() { // Board's serial port search function console.log("Serial Auto-search started."); $("#node-config-lookup-serial-icon").removeClass('fa-search').addClass('spinner'); $("#node-config-lookup-serial").addClass('disabled'); try { $.getJSON('arduinoports', async function(data, data2) { //console.log('Serial Auto-search found data: %o', data); //console.log('Data2: %o', data2); // UI Updates $("#node-config-lookup-serial-icon").removeClass('spinner').addClass('fa-search'); $("#node-config-lookup-serial").removeClass('disabled'); // Ensure ports is an array (fallback to empty array) ports = data || []; $("#node-config-input-device").autocomplete({ source: ports, minLength: 0, close: function(event, ui) { console.log("Serial Auto-search closing."); $("#node-config-input-device").autocomplete("destroy"); } }).autocomplete("search", ""); }); } catch (error) { console.error('Error fetching serial ports:', error); // Reset UI on error $("#node-config-lookup-serial-icon").removeClass('spinner').addClass('fa-search'); $("#node-config-lookup-serial").removeClass('disabled'); } }); } }); </script> <!-- In - node --> <script type="text/html" data-template-name="arduino in"> <div class="form-row"> <label for="node-input-name"><i class="fa fa-tag"></i> <span data-i18n="node-red:common.label.name"></span></label> <input type="text" id="node-input-name" data-i18n="[placeholder]node-red:common.label.name"> </div> <div class="form-row"> <label for="node-input-arduino"><i class="fa fa-tasks"></i> Arduino</label> <input type="text" id="node-input-arduino"> </div> <div class="form-row"> <label for="node-input-state"><i class="fa fa-wrench"></i> <span data-i18n="arduino.label.type"></span></label> <select type="text" id="node-input-state" style="width:200px;"> <option value="INPUT" data-i18n="arduino.state.in.digital"></option> <option value="PULLUP" data-i18n="arduino.state.in.pullup"></option> <option value="ANALOG" data-i18n="arduino.state.in.analogue"></option> <option value="STRING" data-i18n="arduino.state.in.string"></option> </select> </div> <div class="form-row"> <label for="node-input-pin"><i class="fa fa-circle"></i> <span data-i18n="arduino.label.pin"></span></label> <input type="number" min="0" max="99" id="node-input-pin" style="width:20%;" placeholder="2"> </div> <div class="form-tips"><span data-i18n="[html]arduino.tip.pin"></span></div> <div class="form-tips"><span data-i18n="[html]arduino.tip.io"></span></div> </script> <script type="text/javascript"> RED.nodes.registerType('arduino in',{ category: 'Arduino', color:"#3fadb5", defaults: { name: {value:""}, pin: {value:"",validate: function(v) { var ct = $("#node-input-state").val() || this.state; return ct === 'STRING' || (v !== ''); }}, state: {value:"INPUT",required:true}, arduino: {type:"arduino-board"} }, inputs:0, outputs:1, icon: "arduino.png", label: function() { if (this.state === "STRING") { return "String"; } let 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-help-name="arduino in"> <p>This is a "Firmata protocol" based communication, between Node-RED and a connected (Arduino, ESP32, RPi-Pico, etc..) board(s), running firmata firmware. </p> <p>It is working with many boards, not just Arduino. </p> <p>This node's code is at: https://github.com/node-red/node-red-nodes/tree/master/hardware/Arduino </p> <p> </p> <h3>Settings:</h3> <p>[b]Arduino:[/b] You can create a new "board", or choose from previously created. That will represent the chip or board connected.</p> <p>On Unix/linux systems, it is recommended to choose the COM port at "by-serial", so it works always, no matter which USB port it gets re-plugged.</p> <p><i>(It will look like this:</i> <code>/dev/serial/by-id/usb-Arduino_RaspberryPi_Pico_076461E62D414FE3-if00</code>)</p> <p> </p> <p>[b]Type:[/b] Can be: [Digital in] / [Digital Pullup in] / [Analogue in] / [String]</p> <p>[b]Pin:[/b] a number between 0 and the highest GPIO</p> <p>[b]Warning:[/b] Analogue pins are counted from 0. (Not the actual GPIO port.) For example RPi-Pico: [0,1,2,3] where 3 is the built-in Temp reader.</p> <p> </p> <h3>The "in" node:</h3> <p>In = Input means: the board which is running firmata is getting data from input pins.</p> <p>Then it is sending those data to the host controller, which runs Node-RED.</p> <p> </p> <p>The sampling interval (frequency), at which data is being collected and sent to host, is set on board's firmata side. If not, default value is: <b>19ms</b> </p> <p>The connection between the board(s) and the host can be Wifi, BlueTooth, USB.\n <i>(But the base protocol through those is: Serial port transfer. Default baudRate: 57600 .) Usually: USB port.</i></p> <p> </p> <h3>Change Log + More info:</h3> <p> see: https://github.com/node-red/node-red-nodes/blob/master/hardware/Arduino/README.md </p> </script> <script type="text/html" data-template-name="arduino out"> <div class="form-row"> <label for="node-input-name"><i class="fa fa-tag"></i> <span data-i18n="node-red:common.label.name"></span></label> <input type="text" id="node-input-name" data-i18n="[placeholder]node-red:common.label.name"> </div> <div class="form-row"> <label for="node-input-arduino"><i class="fa fa-tasks"></i> Arduino</label> <input type="text" id="node-input-arduino"> </div> <div class="form-row"> <label for="node-input-state"><i class="fa fa-wrench"></i> <span data-i18n="arduino.label.type"></span></label> <select type="text" id="node-input-state" style="width:200px;"> <option value="OUTPUT" data-i18n="arduino.state.out.digital"></option> <option value="PWM" data-i18n="arduino.state.out.analogue"></option> <option value="SERVO" data-i18n="arduino.state.out.servo"></option> <option value="STRING" data-i18n="arduino.state.out.string"></option> <option value="RESET" data-i18n="arduino.state.out.reset"></option> <option value="INTERVAL" data-i18n="arduino.state.out.interval"></option> </select> </div> <div class="form-row"> <label for="node-input-pin"><i class="fa fa-circle"></i> <span data-i18n="arduino.label.pin"></span></label> <input type="number" min="0" max="99" id="node-input-pin" style="width:20%;" placeholder="13"> </div> <div class="form-tips"><span data-i18n="[html]arduino.tip.pin"></span></div> <div class="form-tips"><span data-i18n="[html]arduino.tip.io"></span></div> </script> <script type="text/x-red" data-help-name="arduino out"> <p>... First read the help at "Arduino in".</p> <p>This node's code is at: https://github.com/node-red/node-red-nodes/tree/master/hardware/Arduino </p> <p> </p> <h3>The "in" node:</h3> <p>Out = Output means: you can set individual pins to turn LOW / HIGH / or "x %"=PWM=fast pulses to control voltage.</p> <p>You can select:</p><ul> <li>- <b>Digital</b> - accepts 0, 1, true, false, on, off</li> <li>- <b>Analogue</b> (PWM) - accepts Integer 0 to 255</li> <li>- <b>Servo</b> - accepts Integer 0 - 180</li> <li>- <b>String</b> - to send a *String* to the Arduino</li> <li>- <b>reset</b> - to reset the board, if `msg.payoload = true or 1`</li> <li>- <b>Sampling interval</b> - to set a new time (10ms - 65535ms) how fast analogue input data will be transfered</li> </ul> <p>Digital, PWM, Servo will expects a value in `msg.payload`. </p> <p>The pin number must be set in the properties (config) panel before Deploy.</p> <p> </p> <p>You can also send `msg.payoload = "reset"` to any Output Node without pre-configuring it, to reset the board.</p> </script> <script type="text/javascript"> RED.nodes.registerType('arduino out', { category: 'Arduino', color:"#3fadb5", defaults: { name: {value:""}, pin: {value:"", validate: function(v) { var ct = $("#node-input-state").val() || this.state; return ct === 'STRING' || (v !== ''); }}, state: {value:"",required:true}, arduino: {type:"arduino-board"} }, inputs:1, outputs:0, icon: "arduino.png", align: "right", label: function() { if (this.state === "STRING") { return "String"; } return this.name||"Pin: "+this.pin; }, labelStyle: function() { return this.name?"node_label_italic":""; } }); </script>