{"id":2392,"date":"2023-01-17T18:47:21","date_gmt":"2023-01-18T02:47:21","guid":{"rendered":"https:\/\/beaglebay.com\/duinogear\/?post_type=docs&#038;p=2392"},"modified":"2023-01-18T08:49:27","modified_gmt":"2023-01-18T16:49:27","password":"","slug":"arduino-library-for-output-duinonodes","status":"publish","type":"docs","link":"https:\/\/beaglebay.com\/duinogear\/docs\/arduino-library-for-output-duinonodes\/","title":{"rendered":"Arduino Library for Output duinoNodes"},"content":{"rendered":"\n<p><\/p>\n\n\n\n<p id=\"block-82ccffbb-54ba-4e00-bf09-10a15fdd69ab\">Output duinoNodes (<a href=\"https:\/\/beaglebay.com\/duinogear\/product\/dnou1-digital-output-duinonode-kit\/\">DNOU1 <\/a>&amp; <a href=\"https:\/\/beaglebay.com\/duinogear\/product\/dnou8-digital-output-duinonode\/\">DNOU8<\/a>) are 8-bit serial in, parallel out shift register logic devices. Accordingly, board ports can be turned on or off using the <a rel=\"noreferrer noopener\" href=\"https:\/\/www.arduino.cc\/reference\/tr\/language\/functions\/advanced-io\/shiftout\/\" target=\"_blank\">Arduino library function shiftout()<\/a>. The duinoNodes software library provides an addressing system and additional functionality you may find useful.<\/p>\n\n\n\n<p id=\"block-d1058ee5-d523-4d7a-9d41-9d04e94fa5d6\">The library &#8212; duinoNodes-biuvvo.zip &#8212; should have been automatically added to your cart when you purchased your duinoNode product, and is now available through your Lew&#8217;s Duino Gear account.<\/p>\n\n\n\n<p id=\"block-b2b2370d-80a0-4655-87fa-fc51061a49fb\">Download the file and install it by unzipping it into your<strong> Arduino\/libraries<\/strong> directory. Navigate to <strong>Arduino\/libraries\/duinoNodes\/examples\/outputNodesDemo<\/strong>\/ and load outputNodesDemo.ino. You can attach LEDs and\/or relays to the outputs of your boards to see the sketch demo the use of the board(s).<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"block-7a7c4ca4-b2db-403c-a27a-d3e52cc436ae\"><strong>Basic Usage<\/strong><\/h2>\n\n\n\n<p id=\"block-14691877-3b65-4adb-8b46-db0bb4d85f05\">To use the library, add #include &lt;duinoNodes.h&gt; at the top of your main sketch:<\/p>\n\n\n\n<pre id=\"block-31787805-285d-4c80-99a1-f00f5ac9e6b0\" class=\"wp-block-code\"><code>#include &lt;duinoNodes.h&gt;<\/code><\/pre>\n\n\n\n<p id=\"block-1be96249-1b0e-41d7-98af-d6e479c6bab4\">You must set the number of nodes in use. To do that, define NUM_OUTPUT_NODES before including the header file. Finally, create a global variable for the &#8220;outputNodes&#8221; object used to reference the boards; in the demo sketch the variable is called &#8220;outputs&#8221;:<\/p>\n\n\n\n<pre id=\"block-79de1ced-cb39-404c-9f8d-119ed073fa50\" class=\"wp-block-code\"><code>#define NUM_OUTPUT_NODES 2<br>#include \"duinoNodes.h\"<br>outputNodes *outputs;<\/code><\/pre>\n\n\n\n<p id=\"block-f1ec04c0-d30a-4c06-8606-3c7160213c58\">In setup(), initialize the duinoNodes with this call:<\/p>\n\n\n\n<pre id=\"block-4268d39b-06e3-4ca0-b19f-927ac47c24f3\" class=\"wp-block-code\"><code>outputs = new outputNodes(NUM_OUTPUT_NODES, OUTPUT_CLOCK, OUTPUT_LATCH, OUTPUT_DATA);<\/code><\/pre>\n\n\n\n<p id=\"block-c763ef29-8666-469d-91f5-6a9d221364bc\">This will instantiate the outputNodes object using the default CLOCK, LATCH and DATA pins &#8212; D2, D3 and D4 respectively. To change the defaults define OUTPUT_CLOCK, OUTPUT_LATCH and OUTPUT_DATA with different pin values <strong>before <\/strong>including the library header, like this:<\/p>\n\n\n\n<pre id=\"block-e73656fa-d533-4587-a58c-5d97826713b5\" class=\"wp-block-code\"><code>#define OUTPUT_CLOCK A1<br>#define OUTPUT_LATCH A2<br>#define OUTPUT_DATA 6<br>#define NUM_OUTPUT_NODES 2 <br>#include \"duinoNodes.h\" <br>outputNodes *outputs; <\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"block-9d6bb5f4-7bf9-4e6b-b26d-1e4c5ea16e12\">Addressing and Manipulating Ports<\/h2>\n\n\n\n<p id=\"block-9514f838-5f28-47f0-b083-658c06c6f769\">Each port can be addressed by its sequential ID. With one board (Board 0), the available sequential IDs are 0 to 7. Each board you add to the chain adds additional sequential IDs. So, ports on board 1 can be addressed by IDs 8 &#8211; 15, ports on board 2 can be address by IDs 16 &#8211; 23, and so on.<\/p>\n\n\n\n<p id=\"block-07400c0b-afef-48e5-88cf-4b0c6221d059\">The Sequential ID can be calculated this way, where the Board Number can be from 0 &#8211; 63, and the Port Number ranges from 0 &#8211; 7:<\/p>\n\n\n\n<pre id=\"block-1e543578-434b-48ae-95a4-7720a61859f7\" class=\"wp-block-preformatted\">Sequential ID = (Board Number x 8) + Port Number<\/pre>\n\n\n\n<p id=\"block-523445bd-3a55-4a14-a055-12631b6d8cd4\">To facilitate using ports in groups, each port can also be referenced by a nodeAddress structure, defined as follows:<\/p>\n\n\n\n<pre id=\"block-405683eb-5a04-4c4d-91e7-bcc47c83e067\" class=\"wp-block-code\"><code>typedef struct nodeAddress {<br>  word node;<br>  byte pin;<br>};<\/code><\/pre>\n\n\n\n<p id=\"block-e09b716a-5bf9-43c1-b9c5-29732a3f1bed\">Addresses in this form can be grouped into a nodeList, allowing all member nodes to be turned on or off at the same time.<\/p>\n\n\n\n<pre id=\"block-e7bec961-946c-439c-ae37-b393bddc7579\" class=\"wp-block-code\"><code>typedef struct nodeList {<br>  int elements; \/\/ number of nodes in the list<br>  nodeAddress *nodes;<br>};<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"block-1ac7feab-a7ce-48a7-adcb-bcc8370db7a6\">Methods<\/h2>\n\n\n\n<p id=\"block-172ef8f7-6605-45b1-88b9-c3f5fc610465\">The outputsNodes object offers multiple methods for manipulating the ports. Any individual port can be turned on or off using the nodeWrite() method with the sequential ID of the port:<\/p>\n\n\n\n<pre id=\"block-bbd20822-73df-4134-8e98-1a386902d99e\" class=\"wp-block-code\"><code>outputs-&gt;nodeWrite(ID, 1); \/\/turns port on<br>outputs-&gt;nodeWrite(ID, 0); \/\/turns port off<\/code><\/pre>\n\n\n\n<p id=\"block-47e88cb6-3fdb-428b-8d55-c11e27a0b382\">Sometimes you want to switch multiple ports in parallel, such as where you have a group of lights you want to go on and off at the same time. To do that, you first create an array of nodeAddress objects. In the following example with two nodes, an array of nodeAddresses includes two random ports from each board.<\/p>\n\n\n\n<pre id=\"block-59f9143d-d29a-4bfc-ab70-e78d86cd9bc1\" class=\"wp-block-code\"><code>nodeAddress a_group&#91;4] = {<br>   {word(0, 0), 0},<br>   {word(0, 0), 4},<br>   {word(0, 1), 2},<br>   {word(0, 1), 3}<br>  };<\/code><\/pre>\n\n\n\n<p id=\"block-d933ec04-8769-4f31-8f7f-fae6cce0968d\">Next create a nodeList with the array and the number of addresses in the array:<\/p>\n\n\n\n<pre id=\"block-437ee000-07cf-429a-88ff-02c049c5fd64\" class=\"wp-block-code\"><code>nodeList list_of_items = {4,  a_group};<\/code><\/pre>\n\n\n\n<p id=\"block-7ad20e5c-01cd-4e79-bfa3-a9d3aced5f94\">There are two methods that can be applied to a nodeList:<\/p>\n\n\n\n<pre id=\"block-2fb977ff-2b28-4ae4-90c9-7c810e454882\" class=\"wp-block-code\"><code>outputs-&gt;nodesOn(list_of_items); \/\/ turns all ports on<br><br>outputs-&gt;nodesOff(list_of_items); \/\/ turns all ports off<\/code><\/pre>\n\n\n\n<p id=\"block-e0f326a5-fc2c-423d-8fb2-23d2401537e5\">Pin states are manipulated and maintained in RAM; pin state data is pushed out to the boards whenever there is a change that needs to be communicated. The foregoing methods all set pin states and automatically refresh the outputs to reflect changes.<\/p>\n\n\n\n<p id=\"block-126a7a34-a282-45d9-998c-046fb1eaeccd\">Sometimes, you may want to <em>manipulate pin states without refreshing <\/em>the output ports right away. Use the nodeSetPin() method to do this:<\/p>\n\n\n\n<pre id=\"block-9f76450b-0992-497a-a592-5c2f742e7833\" class=\"wp-block-code\"><code>outputs-&gt;nodeSetPin(ID, state &#91;0 or 1]);<\/code><\/pre>\n\n\n\n<p id=\"block-8ec5f095-a5b7-4ed7-b4f4-181c2f3b65bb\">You can also get the current state of a pin using the nodeGetPin() method which returns the pin state as either true (1) or false (0):<\/p>\n\n\n\n<pre id=\"block-a09720ae-860e-4d42-96c5-07c49506c3d5\" class=\"wp-block-code\"><code>outputs-&gt;nodeGetPin(ID);<\/code><\/pre>\n\n\n\n<p id=\"block-45fc1c50-9335-47ed-9c0d-2dbab58b372a\">This makes it easy to flip the state of a port:<\/p>\n\n\n\n<pre id=\"block-01459666-2d45-463b-9359-d248183aaf54\" class=\"wp-block-code\"><code> outputs-&gt;nodeSetPin(ID,  !outputs-&gt;nodeGetPin(ID) ); <\/code><\/pre>\n\n\n\n<p id=\"block-6fa96a8e-aa87-4f94-af05-73ffd2577dae\">You can get or set the pin byte of a node (board) instead of addressing its individual ports; this eliminates address calculations and results in the maximum possible rate of change of port states. This is also useful where you want to manipulate ports asynchronously relative to refresh calls.<\/p>\n\n\n\n<p id=\"block-e23b4306-5866-4083-bec9-1c4fb4e1b479\">Three helper methods are available:<\/p>\n\n\n\n<pre id=\"block-86e46788-a07c-463c-8ae1-ac57713581de\" class=\"wp-block-preformatted\">outputs-&gt;nodeGet(node) \u2013 returns the pin byte for the node. The state of each port is represented by a bit in the pin byte.<\/pre>\n\n\n\n<pre id=\"block-a7e0c665-5ea8-438a-afce-25461e6c9a44\" class=\"wp-block-preformatted\">outputs-&gt;nodeSet(node, pins) \u2013 sets the pins byte of the node. Change the value of \"pins\" bits to turn ports on or off.<\/pre>\n\n\n\n<p id=\"block-0cde575c-3444-4e6a-872c-c46559dc9fb9\">Any time you want to refresh the outputs, call the nodesRefresh() method:<\/p>\n\n\n\n<pre id=\"block-0c905461-64c6-4ff9-a5c5-82a405e44d26\" class=\"wp-block-preformatted\">outputs-&gt;nodesRefresh() \u2013 pushes current pin data out to the nodes and refreshes outputs.<\/pre>\n","protected":false},"excerpt":{"rendered":"<p>Output duinoNodes (DNOU1 &amp; DNOU8) are 8-bit serial in, parallel out shift register logic devices. Accordingly, board ports can be turned on or off using the Arduino library function shiftout(). The duinoNodes software library provides an addressing system and additional functionality you may find useful. The library &#8212; duinoNodes-biuvvo.zip &#8212; should have been automatically added&hellip;&nbsp;<a href=\"https:\/\/beaglebay.com\/duinogear\/docs\/arduino-library-for-output-duinonodes\/\" rel=\"bookmark\">Read More &raquo;<span class=\"screen-reader-text\">Arduino Library for Output duinoNodes<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":981,"comment_status":"closed","ping_status":"closed","template":"","meta":{"neve_meta_sidebar":"","neve_meta_container":"","neve_meta_enable_content_width":"","neve_meta_content_width":0,"neve_meta_title_alignment":"","neve_meta_author_avatar":"","neve_post_elements_order":"","neve_meta_disable_header":"","neve_meta_disable_footer":"","neve_meta_disable_title":"","footnotes":""},"doc_category":[116],"doc_tag":[],"class_list":["post-2392","docs","type-docs","status-publish","has-post-thumbnail","hentry","doc_category-duinonode_library"],"year_month":"2026-04","word_count":839,"total_views":0,"reactions":{"happy":0,"normal":0,"sad":0},"author_info":{"name":"Site Administrator","author_nicename":"lew-admin","author_url":"https:\/\/beaglebay.com\/duinogear\/author\/lew-admin\/"},"doc_category_info":[{"term_name":"duinoNode Library","term_url":"https:\/\/beaglebay.com\/duinogear\/docs-category\/duinonode_library\/"}],"doc_tag_info":[],"jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/beaglebay.com\/duinogear\/wp-json\/wp\/v2\/docs\/2392","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/beaglebay.com\/duinogear\/wp-json\/wp\/v2\/docs"}],"about":[{"href":"https:\/\/beaglebay.com\/duinogear\/wp-json\/wp\/v2\/types\/docs"}],"author":[{"embeddable":true,"href":"https:\/\/beaglebay.com\/duinogear\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/beaglebay.com\/duinogear\/wp-json\/wp\/v2\/comments?post=2392"}],"version-history":[{"count":3,"href":"https:\/\/beaglebay.com\/duinogear\/wp-json\/wp\/v2\/docs\/2392\/revisions"}],"predecessor-version":[{"id":2400,"href":"https:\/\/beaglebay.com\/duinogear\/wp-json\/wp\/v2\/docs\/2392\/revisions\/2400"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/beaglebay.com\/duinogear\/wp-json\/wp\/v2\/media\/981"}],"wp:attachment":[{"href":"https:\/\/beaglebay.com\/duinogear\/wp-json\/wp\/v2\/media?parent=2392"}],"wp:term":[{"taxonomy":"doc_category","embeddable":true,"href":"https:\/\/beaglebay.com\/duinogear\/wp-json\/wp\/v2\/doc_category?post=2392"},{"taxonomy":"doc_tag","embeddable":true,"href":"https:\/\/beaglebay.com\/duinogear\/wp-json\/wp\/v2\/doc_tag?post=2392"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}