{"id":414,"date":"2015-10-01T15:53:10","date_gmt":"2015-10-01T22:53:10","guid":{"rendered":"http:\/\/thenscaler.com\/?p=414"},"modified":"2015-10-01T15:53:10","modified_gmt":"2015-10-01T22:53:10","slug":"a-programmable-layout-controller","status":"publish","type":"post","link":"https:\/\/thenscaler.com\/?p=414","title":{"rendered":"A Programmable Layout Controller"},"content":{"rendered":"<p>Programming an Arduino to run turnouts, lights or animation on the layout is only part of the challenge. The other part is how do you control the board and tell it what you want it to do?<\/p>\n<div id=\"attachment_234\" style=\"width: 310px\" class=\"wp-caption alignleft\"><a href=\"https:\/\/thenscaler.com\/wp-content\/uploads\/2014\/12\/Servo-Control-by-Button-with-leds.jpg\"><img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-234\" class=\"size-medium wp-image-234\" src=\"https:\/\/thenscaler.com\/wp-content\/uploads\/2014\/12\/Servo-Control-by-Button-with-leds-300x213.jpg\" alt=\"Servo Control with LED Feedback\" width=\"300\" height=\"213\" srcset=\"https:\/\/thenscaler.com\/wp-content\/uploads\/2014\/12\/Servo-Control-by-Button-with-leds-300x213.jpg 300w, https:\/\/thenscaler.com\/wp-content\/uploads\/2014\/12\/Servo-Control-by-Button-with-leds.jpg 912w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/><\/a><p id=\"caption-attachment-234\" class=\"wp-caption-text\">Servo Control with LED Feedback<\/p><\/div>\n<p>From an Arduino point of view, any sensor attached to a pin can trigger action in a sketch. As shown in <a href=\"https:\/\/thenscaler.com\/?page_id=174\">Turnout Control with Arduino &amp; Servos<\/a>, mechanical buttons and switches can be attached to pins to tell the board what to do. In the example circuit, a single button triggers servo action. If you want to include feedback indicators as in this example circuit &#8212; these could be layout signals or panel indicators &#8212; you can hard-wire everything together to the same Arduino board.<\/p>\n<h2>Until you run out of pins<\/h2>\n<p>Pin management is critical as you ask the Arduino to do more and more. Every new sensor or triggering device consumes pins (as does every new actuator or output device). While learning what I could do with an Arduino on the layout, I realized that I needed get beyond the hardwired controls used in experiments and demos to a generic, software-based control system. To do that I was going to have to network everything together.<\/p>\n<h2>Networking Arduinos<\/h2>\n<div id=\"attachment_387\" style=\"width: 310px\" class=\"wp-caption alignright\"><a href=\"https:\/\/thenscaler.com\/wp-content\/uploads\/2015\/09\/Uno-with-Ethernet-Shield.jpg\"><img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-387\" class=\"wp-image-387 size-medium\" src=\"https:\/\/thenscaler.com\/wp-content\/uploads\/2015\/09\/Uno-with-Ethernet-Shield-300x206.jpg\" alt=\"Uno with Ethernet Shield\" width=\"300\" height=\"206\" srcset=\"https:\/\/thenscaler.com\/wp-content\/uploads\/2015\/09\/Uno-with-Ethernet-Shield-300x206.jpg 300w, https:\/\/thenscaler.com\/wp-content\/uploads\/2015\/09\/Uno-with-Ethernet-Shield.jpg 434w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/><\/a><p id=\"caption-attachment-387\" class=\"wp-caption-text\">Uno with Ethernet Shield<\/p><\/div>\n<p>In <a href=\"https:\/\/thenscaler.com\/?p=375\">Roundhouse Rebuild Part 2<\/a> I mentioned, without explanation, that I was using Ethernet, and went on to discuss the evolving Simple Network Command System. I decided to go with wired Ethernet because of the easy availability of inexpensive Ethernet shields based on the WIZnet W5100 Ethernet Controller chip (<a href=\"http:\/\/amzn.to\/1FLz7I3\" target=\"_blank\">under 10 dollars per shield<\/a>), and an easy to use Arduino library included in the <a href=\"https:\/\/www.arduino.cc\/en\/Main\/Software\" target=\"_blank\">IDE<\/a>. It is as close to plug &amp; play as networking gets on an Arduino. The only additional equipment required are one or more inexpensive 10\/100 switches (for example: <a href=\"http:\/\/www.amazon.com\/gp\/product\/B000FNFSPY\/ref=as_li_tl?ie=UTF8&amp;camp=1789&amp;creative=9325&amp;creativeASIN=B000FNFSPY&amp;linkCode=as2&amp;tag=thenscaler-20&amp;linkId=XX4HB2WEFAZNXDT4\">TP-LINK TL-SF1005D 5-port 10\/100Mbps Desktop Switch<\/a>; don&#8217;t get gigabit switches to work with these shields, you&#8217;re just asking for trouble) to\u00a0 interconnect the devices. I use a <a href=\"https:\/\/thenscaler.com\/?page_id=380\" target=\"_blank\">per-device assigned address system<\/a> which helps keep the equipment roster simple (no router or <a href=\"https:\/\/en.wikipedia.org\/wiki\/Dynamic_Host_Configuration_Protocol\" target=\"_blank\">DHCP <\/a>required).<\/p>\n<p>Why not just use the Digital Command Control system for the Arduino net? The short answer is that while it is <strong><em>clearly doable<\/em><\/strong>, for the purposes of this project I am going to keep the Arduino net separate because:<\/p>\n<ol>\n<li>Everything I do here has to work for both DC and DCC layouts. I own both DCC and unconverted DC locomotives; the layout has to work the same in either mode.<\/li>\n<li>Compared to conventional networking, DCC is a relatively difficult way to conduct bidirectional communications between Arduino boards.<\/li>\n<li>Keeping them separate does not preclude enabling communication between the two systems down the road.<\/li>\n<\/ol>\n<p>If you want to pursue DCC communication and Arduino, the <a href=\"http:\/\/mrrwa.org\/\" target=\"_blank\">Model Railroading with Arduino<\/a> site is a great place to start. The biggest impediment for most modelers will be the lack of commercial interface hardware to connect an Arduino to either track power or the command bus (although the circuits are easy enough to build); the closest commercial solution would be to use a USB interface, like the <a href=\"http:\/\/amzn.to\/1QNUEAr\" target=\"_blank\">Digitrax PR3XTRA USB Programmer<\/a>, <a href=\"http:\/\/www.rr-cirkits.com\/index.html\" target=\"_blank\">RR-CirKits LocoBuffer-USB<\/a> or the <a href=\"http:\/\/www.sprog-dcc.co.uk\/\" target=\"_blank\">SPROG II USB<\/a>, to tap into the DCC command system <a href=\"http:\/\/jmri.sourceforge.net\/help\/en\/manual\/DecoderPro3\/Start_DCC_Hardware.shtml\" target=\"_blank\">just as you would with JMRI<\/a>.<\/p>\n<p>My ultimate goal is to build the layout&#8217;s electronic and mechanical foundation around a network of Arduino boards. For communication among Arduino boards, Ethernet makes the most sense right now because it is the most &#8220;frictionless&#8221; route to achieve my goals (a wireless form would be even better, but would be a little more difficult to implement, so I&#8217;m holding that option for the future); communication between the Arduino net and the DCC system is a topic for the future\u2014and the possibilities go way beyond treating Arduinos as decoders.<\/p>\n<h2>Building The Controller<\/h2>\n<div id=\"attachment_428\" style=\"width: 310px\" class=\"wp-caption alignleft\"><a href=\"https:\/\/thenscaler.com\/wp-content\/uploads\/2015\/09\/2050-04.jpg\"><img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-428\" class=\"wp-image-428 size-medium\" src=\"https:\/\/thenscaler.com\/wp-content\/uploads\/2015\/09\/2050-04-300x225.jpg\" alt=\"2050-04\" width=\"300\" height=\"225\" srcset=\"https:\/\/thenscaler.com\/wp-content\/uploads\/2015\/09\/2050-04-300x225.jpg 300w, https:\/\/thenscaler.com\/wp-content\/uploads\/2015\/09\/2050-04.jpg 970w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/><\/a><p id=\"caption-attachment-428\" class=\"wp-caption-text\">Adafruit 3.5&#8243; TFT screen displaying a bitmap.<\/p><\/div>\n<p>The concept for a prototype controller was simple enough: start with an <a href=\"http:\/\/amzn.to\/1RiSAkT\" target=\"_blank\">Uno<\/a>, add an Ethernet shield and add a small touchscreen for display and user input. Put it all in a box with an Ethernet jack, a USB jack and power connector. Software generates screen displays, interprets touches and communicates with devices it is controlling.<\/p>\n<p>For the screen I chose the <a href=\"http:\/\/www.adafruit.com\/products\/2050\" target=\"_blank\">Adafruit 3.5&#8243; TFT Touchscreen<\/a>, seen here attached to an Uno via a breadboard (NB: The wiring shown is the minimum required to run the screen; the touch overlay and the SD Card reader require additional connections). It is capable of full 16bit color with a resolution of 320 x 480 pixels. The Adafruit library provides basic graphic primitive functions, basic text functions and bitmap functions allowing image display. It has a resistive touch overlay. Adafruit has an <a href=\"https:\/\/learn.adafruit.com\/adafruit-3-5-color-320x480-tft-touchscreen-breakout\" target=\"_blank\">excellent tutorial<\/a> on using this screen with their library.<\/p>\n<div id=\"attachment_427\" style=\"width: 310px\" class=\"wp-caption alignright\"><a href=\"https:\/\/thenscaler.com\/wp-content\/uploads\/2015\/09\/2050-01.jpg\"><img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-427\" class=\"size-medium wp-image-427\" src=\"https:\/\/thenscaler.com\/wp-content\/uploads\/2015\/09\/2050-01-300x225.jpg\" alt=\"Back of 3.8&quot; TFT Screen\" width=\"300\" height=\"225\" srcset=\"https:\/\/thenscaler.com\/wp-content\/uploads\/2015\/09\/2050-01-300x225.jpg 300w, https:\/\/thenscaler.com\/wp-content\/uploads\/2015\/09\/2050-01.jpg 970w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/><\/a><p id=\"caption-attachment-427\" class=\"wp-caption-text\">Back of 3.5&#8243; TFT Touchscreen<\/p><\/div>\n<p>The screen comes with a choice of interfaces: you can use the SPI bus interface in order to use the fewest pins on your Arduino, or you can devote more pins to use the faster 8 bit interface. You select the interface and solder the header pins on the appropriate side.\u00a0 A\u00a0 solder jumper on the back determines which interface is active; the decision is reversible. An SD Card reader is included for convenient storage of bitmap files.<\/p>\n<p>On an Uno, the Ethernet shield dictates that the TFT screen has to be run via SPI; there aren&#8217;t enough pins otherwise. The application does not require the SD Card Reader so I don&#8217;t connect it to the UNO.<\/p>\n<p>I fabricated a wiring harness for attaching the screen to the Uno\\Ethernet combo, then mounted everything in a Radio Shack project box as shown below.<\/p>\n<div id=\"attachment_440\" style=\"width: 310px\" class=\"wp-caption alignleft\"><a href=\"https:\/\/thenscaler.com\/wp-content\/uploads\/2015\/09\/wiring.jpg\"><img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-440\" class=\"wp-image-440 size-medium\" src=\"https:\/\/thenscaler.com\/wp-content\/uploads\/2015\/09\/wiring-300x200.jpg\" alt=\"Wiring Harness\" width=\"300\" height=\"200\" srcset=\"https:\/\/thenscaler.com\/wp-content\/uploads\/2015\/09\/wiring-300x200.jpg 300w, https:\/\/thenscaler.com\/wp-content\/uploads\/2015\/09\/wiring.jpg 902w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/><\/a><p id=\"caption-attachment-440\" class=\"wp-caption-text\">Wiring Harness<\/p><\/div>\n<p>The connectors on the wiring harness are <a href=\"http:\/\/www.adafruit.com\/products\/1540\" target=\"_blank\">male <\/a>or <a href=\"http:\/\/www.adafruit.com\/products\/598\" target=\"_blank\">female <\/a>PCB Headers; I solder the wires to the PCB side of the fittings, then cover each connection with heat shrink tubing. White wires connect to digital pins 7 through 13 (except 10, which is reserved for the Ethernet shield) and are for the TFT interface. Green wires are for the touch overlay and connect to Analog pins A2 &#8211; A5. Red supplies 5v, and black ground, to the TFT screen. The <a href=\"http:\/\/www.adafruit.com\/products\/909\" target=\"_blank\">Ethernet extension<\/a> cable and the <a href=\"http:\/\/www.adafruit.com\/products\/907\" target=\"_blank\">USB extension<\/a> cable both came from <a href=\"http:\/\/www.adafruit.com\" target=\"_blank\">Adafruit<\/a>.<\/p>\n<div id=\"attachment_441\" style=\"width: 310px\" class=\"wp-caption aligncenter\"><a href=\"https:\/\/thenscaler.com\/wp-content\/uploads\/2015\/09\/inside.jpg\"><img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-441\" class=\"wp-image-441 size-medium\" src=\"https:\/\/thenscaler.com\/wp-content\/uploads\/2015\/09\/inside-300x200.jpg\" alt=\"Inside the Controller\" width=\"300\" height=\"200\" srcset=\"https:\/\/thenscaler.com\/wp-content\/uploads\/2015\/09\/inside-300x200.jpg 300w, https:\/\/thenscaler.com\/wp-content\/uploads\/2015\/09\/inside.jpg 902w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/><\/a><p id=\"caption-attachment-441\" class=\"wp-caption-text\">Inside the Controller<\/p><\/div>\n<div id=\"attachment_442\" style=\"width: 310px\" class=\"wp-caption alignright\"><a href=\"https:\/\/thenscaler.com\/wp-content\/uploads\/2015\/09\/inside2.jpg\"><img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-442\" class=\"size-medium wp-image-442\" src=\"https:\/\/thenscaler.com\/wp-content\/uploads\/2015\/09\/inside2-300x200.jpg\" alt=\"Controller with Screen Wiring Attached\" width=\"300\" height=\"200\" srcset=\"https:\/\/thenscaler.com\/wp-content\/uploads\/2015\/09\/inside2-300x200.jpg 300w, https:\/\/thenscaler.com\/wp-content\/uploads\/2015\/09\/inside2.jpg 902w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/><\/a><p id=\"caption-attachment-442\" class=\"wp-caption-text\">Controller with Screen Wiring Attached<\/p><\/div>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>Here it is in operation:<\/p>\n<div id=\"attachment_439\" style=\"width: 310px\" class=\"wp-caption alignleft\"><a href=\"https:\/\/thenscaler.com\/wp-content\/uploads\/2015\/09\/controller.jpg\"><img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-439\" class=\"size-medium wp-image-439\" src=\"https:\/\/thenscaler.com\/wp-content\/uploads\/2015\/09\/controller-300x200.jpg\" alt=\"The Programmable Controller\" width=\"300\" height=\"200\" srcset=\"https:\/\/thenscaler.com\/wp-content\/uploads\/2015\/09\/controller-300x200.jpg 300w, https:\/\/thenscaler.com\/wp-content\/uploads\/2015\/09\/controller.jpg 902w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/><\/a><p id=\"caption-attachment-439\" class=\"wp-caption-text\">The Programmable Controller<\/p><\/div>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>You may have guessed the fan ( on the left side ) was an afterthought. The cheap Ethernet shields I use are heat sensitive; they will crash when put in a confined space with poor air circulation.\u00a0 Out in the open no problem; in a box, its a problem. Found that out the hard way. So I added a little fan to pull the air through the box (if you look closely, you&#8217;ll see there are holes around the bottom); works fine if noisily. Obviously, I will plan for air circulation when I build the main layout control panel. Such is prototyping!<\/p>\n<h2>What it Does<\/h2>\n<p>The controller sketch displays menus with buttons that, when touched, will cause the controller to either go to a different menu or send a command packet to the target device. Command packets are strings, formatted thus: <em>function<\/em> \/ <em>option<\/em> \/ <em>data.<\/em> For more about my protocol and the network polling process, see the Simple Network Command System section near the end of <a href=\"https:\/\/thenscaler.com\/?p=375\">Roundhouse Rebuild Part 2<\/a>.<\/p>\n<p>The Main Menu provides access to sub-menus that I&#8217;ve created to support parts of the project.<\/p>\n<div id=\"attachment_443\" style=\"width: 310px\" class=\"wp-caption aligncenter\"><a href=\"https:\/\/thenscaler.com\/wp-content\/uploads\/2015\/09\/main_menu.jpg\"><img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-443\" class=\"size-medium wp-image-443\" src=\"https:\/\/thenscaler.com\/wp-content\/uploads\/2015\/09\/main_menu-300x180.jpg\" alt=\"Controller Main Menu\" width=\"300\" height=\"180\" srcset=\"https:\/\/thenscaler.com\/wp-content\/uploads\/2015\/09\/main_menu-300x180.jpg 300w, https:\/\/thenscaler.com\/wp-content\/uploads\/2015\/09\/main_menu.jpg 360w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/><\/a><p id=\"caption-attachment-443\" class=\"wp-caption-text\">Controller Main Menu<\/p><\/div>\n<p>All menus are built with buttons. A structure type called button_t holds button data:<\/p>\n<pre>typedef struct {\r\n\u00a0 int x;\r\n\u00a0 int y;\r\n\u00a0 int txtX;\r\n\u00a0 int txt;\r\n} button_t;<\/pre>\n<p><span style=\"color: #0000ff;\">X<\/span> and <span style=\"color: #0000ff;\">y<\/span> are the coordinates of the upper left corner of the button; the width and height are the same for all buttons in this version of the system. <span style=\"color: #0000ff;\">txtX<\/span> is the x coordinate for the button text; the y coordinate is calculated and there is no text centering function. Finally, <span style=\"color: #0000ff;\">txt<\/span> is an offset into a button_labels array pointing to the button text.<\/p>\n<p>For the main menu, the button set definition looks like this:<\/p>\n<pre>const button_t buttons_main[SIZE_MAIN_SET] = {\r\n\u00a0 {90, 80, 115, 0 },\r\n\u00a0 {250, 80, 254, 1},\r\n\u00a0 {175, 140, 185, 16}};<\/pre>\n<p>Determining if a button has been touched is fairly straight forward. The coordinates of a touch <span style=\"color: #0000ff;\">p<\/span> are compared to each button, as <span style=\"color: #0000ff;\">b<\/span>, in the current set to see if it is on or within the button boundaries.<\/p>\n<pre>p.x &gt;= b.x &amp;&amp; p.x &lt;= (b.x + BUTTON_WIDTH) &amp;&amp; p.y &gt;= b.y &amp;&amp; p.y &lt;= (b.y + BUTTON_HEIGHT)<\/pre>\n<h2>Whacking My Head on the Memory Ceiling<\/h2>\n<p>The graphics libraries contain a lot of code. With the newest <a href=\"https:\/\/www.arduino.cc\/en\/Main\/Software\" target=\"_blank\">Arduino IDE<\/a>, the controller sketch compiles to 27,030 bytes, about 83% of available program space; it was about 29k bytes with the previous IDE.<\/p>\n<p>That is still tight enough that I cannot include SD Card access and a function to draw a bitmap from a file without going 15% over the absolute memory limit for an <a href=\"http:\/\/amzn.to\/1RiSAkT\" target=\"_blank\">UNO<\/a>. In the future I&#8217;ll use an <a href=\"http:\/\/amzn.to\/1LUtjgB\" target=\"_blank\">Arduino MEGA 2560 Board<\/a> instead of an UNO for control panel applications because of its vastly superior memory resources (and it has a lot more pins to work with). The remaining 17% with the current sketch gives me plenty of room for now.<\/p>\n<p>The trickier bit of <a href=\"https:\/\/www.arduino.cc\/en\/Tutorial\/Memory\" target=\"_blank\">memory management<\/a> is &#8220;dynamic memory,&#8221; which (on an UNO) is 2,048 bytes of shared memory space used for local variables. Local variables are created when functions are called and destroyed when they are exited. Global variables&#8211;variables declared outside of any function that are always <em>in scope<\/em> and available wherever you are in your sketch&#8211;are also stored in the same space. Global variables reduce the amount of dynamic memory available for local variables and, if not managed, can strangle your sketch.<\/p>\n<p>Fortunately, the majority of global variables turn out to be constants &#8212; unchanging values or text used by the application. This kind of data can be stored in the program space instead of dynamic memory; the limitations are that<\/p>\n<ul>\n<li>you can&#8217;t change the value stored in program space while the sketch is running, and<\/li>\n<li>you have to copy a value from program space to dynamic memory in order to use it.<\/li>\n<\/ul>\n<p>The <a href=\"https:\/\/www.arduino.cc\/en\/Reference\/PROGMEM\" target=\"_blank\">PROGMEM <\/a>keyword is used to tell the compiler to store something in program space instead of dynamic memory. To park menu titles and button text in program space, I did this:<\/p>\n<pre>const char mstr_0[] PROGMEM = \"Main Menu\";\r\nconst char mstr_1[] PROGMEM = \"Lighting Menu\";\r\nconst char mstr_2[] PROGMEM = \"Roundhouse Menu\";\r\nconst char mstr_3[] PROGMEM = \"Test Loop Menu\";\r\n\r\nconst char* const menus[] PROGMEM = {mstr_0, mstr_1, mstr_2, mstr_3};\r\n\r\nconst char str_0[] PROGMEM = \"Lights\";\r\nconst char str_1[] PROGMEM = \"Roundhouse\";\r\nconst char str_2[] PROGMEM = \"&lt;-Back\";\r\nconst char str_3[] PROGMEM = \"\u00a0 Night\";\r\nconst char str_4[] PROGMEM = \"\u00a0\u00a0 Day\";\r\nconst char str_5[] PROGMEM = \" Mid-Day\";\r\nconst char str_6[] PROGMEM = \" Sunrise\";\r\nconst char str_7[] PROGMEM = \" Sunset\";\r\nconst char str_8[] PROGMEM = \"\u00a0\u00a0 Low\";\r\nconst char str_9[] PROGMEM = \"\u00a0 High\";\r\nconst char str_10[] PROGMEM = \" Stall 1\";\r\nconst char str_11[] PROGMEM = \" Stall 2\";\r\nconst char str_12[] PROGMEM = \" Stall 3\";\r\nconst char str_13[] PROGMEM = \" Stall 4\";\r\nconst char str_14[] PROGMEM = \" Stall 5\";\r\nconst char str_15[] PROGMEM = \"Afternoon\";\r\nconst char str_16[] PROGMEM = \"Test Loop\";\r\nconst char str_17[] PROGMEM = \"Main\";\r\nconst char str_18[] PROGMEM = \"Siding\";\r\nconst char str_19[] PROGMEM = \"Occupancy\";\r\n\r\nconst char* const button_labels[] PROGMEM = {str_0, str_1, str_2, str_3,\r\n str_4, str_5, str_6, str_7, str_8, str_9, str_10, str_11, str_12,\r\n str_13, str_14, str_15, str_16, str_17, str_18, str_19};<\/pre>\n<p>Copying the title of the main menu into a local variable <span style=\"color: #0000ff;\">text<\/span> looks like this:<\/p>\n<pre>strcpy_P(text, (char*)pgm_read_word((&amp;menus[0])));<\/pre>\n<p>For getting the button labels:<\/p>\n<pre>\u00a0strcpy_P(text, (char*)pgm_read_word((&amp;button_labels[b.txt])));<\/pre>\n<p>An alternate way to store static data in program memory is to use the F macro, as in this declaration of a local variable that initializes with a static value that is stored in and retrieved from program memory:<\/p>\n<pre>String readyStr = F(\"Ready\");<\/pre>\n<p>At this point I find it useful to make it a habit to use these tools in all sketches to tame dynamic memory space. Currently the controller sketch uses only 771 bytes or 37% of dynamic memory for global variables, leaving plenty of space for locals.<\/p>\n<h2>Menus<\/h2>\n<p>The Lighting and Roundhouse menus look like this:<\/p>\n<div id=\"attachment_444\" style=\"width: 310px\" class=\"wp-caption aligncenter\"><a href=\"https:\/\/thenscaler.com\/wp-content\/uploads\/2015\/09\/lighting_menu.jpg\"><img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-444\" class=\"wp-image-444 size-medium\" src=\"https:\/\/thenscaler.com\/wp-content\/uploads\/2015\/09\/lighting_menu-300x180.jpg\" alt=\"lighting_menu\" width=\"300\" height=\"180\" srcset=\"https:\/\/thenscaler.com\/wp-content\/uploads\/2015\/09\/lighting_menu-300x180.jpg 300w, https:\/\/thenscaler.com\/wp-content\/uploads\/2015\/09\/lighting_menu.jpg 360w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/><\/a><p id=\"caption-attachment-444\" class=\"wp-caption-text\">Lighting Menu<\/p><\/div>\n<p>&nbsp;<\/p>\n<div id=\"attachment_445\" style=\"width: 310px\" class=\"wp-caption aligncenter\"><a href=\"https:\/\/thenscaler.com\/wp-content\/uploads\/2015\/09\/roundhouse_menu.jpg\"><img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-445\" class=\"size-medium wp-image-445\" src=\"https:\/\/thenscaler.com\/wp-content\/uploads\/2015\/09\/roundhouse_menu-300x180.jpg\" alt=\"Roundhouse Menu\" width=\"300\" height=\"180\" srcset=\"https:\/\/thenscaler.com\/wp-content\/uploads\/2015\/09\/roundhouse_menu-300x180.jpg 300w, https:\/\/thenscaler.com\/wp-content\/uploads\/2015\/09\/roundhouse_menu.jpg 360w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/><\/a><p id=\"caption-attachment-445\" class=\"wp-caption-text\">Roundhouse Menu<\/p><\/div>\n<p>These are the controls I used off screen to control lighting when making the <a href=\"https:\/\/www.youtube.com\/watch?v=aduRoBVf7rQ\">Roundhouse demo video<\/a>. Overhead lighting was supplied by 4 led light bars (<a href=\"https:\/\/thenscaler.com\/?page_id=279\">152 RGB ALEDS total<\/a>) controlled by a networked UNO.<\/p>\n<hr \/>\n<p>I&#8217;ve been busy at the test loop trying out various ideas.\u00a0 <strong>Turnout control<\/strong>, <strong>signals<\/strong> and <strong>block occupancy detection<\/strong> (I have a method that <strong>works for both DC and DCC<\/strong> layouts), all play a part in the next step toward the layout. I&#8217;ll leave you to ponder the test loop menu until next time.<\/p>\n<div id=\"attachment_446\" style=\"width: 310px\" class=\"wp-caption aligncenter\"><a href=\"https:\/\/thenscaler.com\/wp-content\/uploads\/2015\/09\/testloop_menu.jpg\"><img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-446\" class=\"size-medium wp-image-446\" src=\"https:\/\/thenscaler.com\/wp-content\/uploads\/2015\/09\/testloop_menu-300x180.jpg\" alt=\"Test Loop Controls\" width=\"300\" height=\"180\" srcset=\"https:\/\/thenscaler.com\/wp-content\/uploads\/2015\/09\/testloop_menu-300x180.jpg 300w, https:\/\/thenscaler.com\/wp-content\/uploads\/2015\/09\/testloop_menu.jpg 360w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/><\/a><p id=\"caption-attachment-446\" class=\"wp-caption-text\">Test Loop Controls<\/p><\/div>\n<p>&nbsp;<\/p>\n<hr \/>\n<p>&nbsp;<\/p>\n<hr \/>\n<p>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Programming an Arduino to run turnouts, lights or animation on the layout is only part of the challenge. The other part is how do you control the board and tell it what you want it to do? From an Arduino point of view, any sensor attached to a pin can trigger action in a sketch. [&hellip;]<\/p>\n","protected":false},"author":2,"featured_media":439,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[35,21,34],"tags":[22,40,23,41,27,42,39],"class_list":["post-414","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-electronics","category-layout-control","category-lighting-and-animation","tag-arduino","tag-dc","tag-dcc","tag-ethernet","tag-mrrwa","tag-networking","tag-programming"],"_links":{"self":[{"href":"https:\/\/thenscaler.com\/index.php?rest_route=\/wp\/v2\/posts\/414","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/thenscaler.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/thenscaler.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/thenscaler.com\/index.php?rest_route=\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/thenscaler.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=414"}],"version-history":[{"count":41,"href":"https:\/\/thenscaler.com\/index.php?rest_route=\/wp\/v2\/posts\/414\/revisions"}],"predecessor-version":[{"id":469,"href":"https:\/\/thenscaler.com\/index.php?rest_route=\/wp\/v2\/posts\/414\/revisions\/469"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/thenscaler.com\/index.php?rest_route=\/wp\/v2\/media\/439"}],"wp:attachment":[{"href":"https:\/\/thenscaler.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=414"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/thenscaler.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=414"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/thenscaler.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=414"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}