{"id":1249,"date":"2014-12-18T07:00:18","date_gmt":"2014-12-18T12:00:18","guid":{"rendered":"http:\/\/www.tigoe.com\/pcomp\/code\/?p=1249"},"modified":"2014-12-31T13:25:11","modified_gmt":"2014-12-31T18:25:11","slug":"programming-the-tree","status":"publish","type":"post","link":"https:\/\/www.tigoe.com\/pcomp\/code\/arduinowiring\/1249\/","title":{"rendered":"Programming a Christmas Tree"},"content":{"rendered":"<p>As we planned for Christmas this year, my partner suggested that maybe we should replace the lights for the tree. &#8220;While we&#8217;re at it,&#8221; she asked, &#8220;is there anything out there that&#8217;s more controllable than just the ones that twinkle on and off?&#8221;<\/p>\n<p>&#8220;Well,&#8221; I said, &#8220;there are NeoPixels&#8230;&#8221;<\/p>\n<p>We decided that it would be great to have a tree where the lights looked and acted like candles, flickering gently in a soft, warm glow, and fading from a bright orange down to a low reddish glow by the end of the evening. We also wanted to realize the cheesy quote\u00a0from <em>It&#8217;s A Wonderful Life<\/em> that <a href=\"http:\/\/youtu.be\/FcMgt3JQDxw\">&#8220;every time a bell rings, an angel gets its wings.&#8221;<\/a><\/p>\n<p>Here&#8217;s a timelapse of the tree in action:<\/p>\n<p><iframe loading=\"lazy\" title=\"Christmas Tree 2014 - Full sequence\" src=\"https:\/\/player.vimeo.com\/video\/115716997?dnt=1&amp;app_id=122963\" width=\"226\" height=\"400\" frameborder=\"0\" allow=\"autoplay; fullscreen\" allowfullscreen><\/iframe><\/p>\n<p>When you ring the bell, this happens:<\/p>\n<p><iframe loading=\"lazy\" title=\"Christmas Tree Twinkle effect\" src=\"https:\/\/player.vimeo.com\/video\/115716844?dnt=1&amp;app_id=122963\" width=\"226\" height=\"400\" frameborder=\"0\" allow=\"autoplay; fullscreen\" allowfullscreen><\/iframe><\/p>\n<p>The process of making it gave a chance to work with:<\/p>\n<ul>\n<li>\u00a0NeoPixels and the <a href=\"https:\/\/github.com\/adafruit\/Adafruit_NeoPixel\">Adafruit NeoPixel library<\/a><\/li>\n<li>Serial input to Arduino as a testing method<\/li>\n<li>the <a href=\"http:\/\/playground.arduino.cc\/Main\/CapacitiveSensor?from=Main.CapSense\">capacitive sensor library<\/a> for Arduino<\/li>\n<li>The <a href=\"http:\/\/arduino.cc\/en\/Reference\/YunBridgeLibrary\">Mailbox class of the Bridge library<\/a> for the\u00a0Arduino Y\u00fan<\/li>\n<li>Building a web interface for the Arduino Y\u00fan<\/li>\n<li>Using cron, Mailbox, and curl for task-scheduling on the\u00a0Arduino Y\u00fan<\/li>\n<\/ul>\n<p>You can find the code and circuit in the <a href=\"https:\/\/github.com\/tigoe\/NeoPixel_examples\/tree\/master\/BlinkyTree\">gitHub repository for this project<\/a>.<br \/>\n<!--more--><\/p>\n<h2>Hardware<\/h2>\n<p>I started looking for affordable strings of NeoPixels (or <a href=\"http:\/\/www.aliexpress.com\/item\/12mm-WS2811-as-WS2801-led-pixel-module-IP68-waterproof-DC5V-full-color-RGB-50pcs-a-string\/1022672558.html\">WS2811 addressable RGB LEDs<\/a>) on AliExpress.com. As I was looking, I learned that <a href=\"http:\/\/blinkinlabs.com\/\">Blinkinlabs<\/a> had just released a version\u00a0of their BlinkyTape <a href=\"https:\/\/blinkinlabs.myshopify.com\/collections\/frontpage\/products\/blinky-christmas-lights\">in a string format<\/a>. Having the built-in Atmega32U4 and microUSB (basically an Arduino Leonardo in the plug) would make my life a lot simpler, so I ordered a set of them. Since the bare strips were a lot cheaper, I ordered a couple sets of those as well, to finish off the tree.<\/p>\n<p>I\u00a0considered\u00a0a few different options for building this system:<\/p>\n<ol>\n<li>Control\u00a0the NeoPixels from a separate controller, like an Uno, Leonardo, or Adafruit Trinket. The advantage is that it&#8217;s cheap. The disadvantage is that I couldn&#8217;t do a nice user interface.<\/li>\n<li>Use the Blinkinlabs strings. Advantage: convenient, no wiring. Disadvantage: no user interface, and more expensive than option 1, and difficult to add the capacitive touch controller for the bell.<\/li>\n<li>Control the NeoPixels from an Arduino Y\u00fan. Advantage: great user interface options, plus built-in Atmega32U4 for real-time control. Disadvantage: more expensive controller.<\/li>\n<\/ol>\n<p>Since I wanted to build a web interface for control, and set a schedule for the lights each day, I went for option 3. The code was mostly developed using option 2,\u00a0then adapted slightly for the final version. The final system looked like this:<\/p>\n<p><a href=\"http:\/\/www.tigoe.com\/pcomp\/code\/wp-content\/uploads\/2014\/12\/BinkyTreeCircuit_bb.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter wp-image-1262 size-full\" src=\"http:\/\/www.tigoe.com\/pcomp\/code\/wp-content\/uploads\/2014\/12\/BinkyTreeCircuit_bb.png\" alt=\"BinkyTreeCircuit_bb\" width=\"578\" height=\"398\" srcset=\"https:\/\/www.tigoe.com\/pcomp\/code\/wp-content\/uploads\/2014\/12\/BinkyTreeCircuit_bb.png 578w, https:\/\/www.tigoe.com\/pcomp\/code\/wp-content\/uploads\/2014\/12\/BinkyTreeCircuit_bb-300x207.png 300w\" sizes=\"auto, (max-width: 578px) 100vw, 578px\" \/><\/a><\/p>\n<p>The Blinkinlights lights arrived first, so I started right away with color control, looking for just the right shades of orange and red to make the candle effect. I use the Adafruit NeoPixel library. The <a href=\"https:\/\/learn.adafruit.com\/adafruit-neopixel-uberguide\">Adafruit NeoPixel Uberguide<\/a> explains them well. You can set colors using a standard 24-bit number like the web. For example, 0x0000FF is blue; 0xFF0000 is red; and 0x00FF00 is green. \u00a0I had\u00a0an <a href=\"http:\/\/www.tigoe.com\/pcomp\/code\/arduinowiring\/1172\/\">example that would let me change each pixel&#8217;s color serially<\/a> so I could test the colors, then combined it with <a href=\"https:\/\/discussions.zoho.com\/processing\/user\/owaunandrew\">owaunandrew<\/a>&#8216;s\u00a0<a href=\"http:\/\/forum.processing.org\/one\/topic\/processing-color-picker.html\">Processing ColorPicker sketch<\/a> so that I could pick colors from the desktop. My <a href=\"https:\/\/github.com\/tigoe\/NeoPixel_examples\/tree\/master\/BlinkyTree\/NeoPixelColorPicker\">NeoPixel color picker sketch<\/a>\u00a0for Processing can be found on in the\u00a0\u00a0gitHub repo for this project.<\/p>\n<h2>Flickering and Fading to Red<\/h2>\n<p>I needed an array of colors for the bright state, \u00a0and a final color for the dim state, which I picked with the color picker. This started my list of global variables:<\/p>\n<pre class=\"brush: arduino; light: true; title: ; notranslate\" title=\"\">\r\n\/\/ initial reference color range:\r\nconst unsigned long referenceColors&#x5B;] = {0xCB5D0F, 0xB4470C, 0x95310C, 0x854E0B};\r\n\/\/ the final color of all pixels before they flicker out:\r\nconst unsigned long finalColor = 0x1F0F02;\r\n\/\/ changing range of keyframe colors for the pixels to flicker to:\r\nunsigned long keyColors&#x5B;] = {0xCB500F, 0xB4410C, 0x95230C, 0x853E0B};\r\n<\/pre>\n<p>The fading process had to have two parts: one part to generate the flicker from one reference color to another, and a second part to fade all the reference colors down to the final color. Neither the reference colors nor the final color should change, so they could be consts. In order to enable reset, I made a second array, <code>keyColors[]<\/code>, which contains the active set of colors at any given moment. The color values in <code>keyColors[]<\/code>, initially a copy of <code>referenceColors[]<\/code>, \u00a0are gradually faded down toward <code>finalColor<\/code>. To manage the flicker effect, I needed to keep track of each pixel&#8217;s current color and its target color. That called for two more arrays:<\/p>\n<pre class=\"brush: arduino; light: true; title: ; notranslate\" title=\"\">\r\nunsigned long targetColor&#x5B;numPixels];    \/\/ next target for each pixel\r\nunsigned long pixelColor&#x5B;numPixels];     \/\/ current color for each pixel\r\n<\/pre>\n<p>Rounding out the global variables, there&#8217;s the pin number for controlling the strip, the instance of the Adafruit NeoPixel library, the size of the keyColors[] array, and boolean flags for whether the lights are running, and for whether the fade is finished (these last come into play later on).<\/p>\n<p>The flicker happens in a function called <code>flickerPixels()<\/code>, and the fade down to red is done in <code>fadeToRed()<\/code>. There&#8217;s also an important function that compares two colors by separating them into their red, green, and blue components, and returning a color that&#8217;s one step closer to the target color.<\/p>\n<p>Here&#8217;s the initial sketch. Note that the control pin number is 12 here, not 13 as you&#8217; need for the Blinkinlights strip. I changed from the Blinkinlights strings to regular strings later on:<\/p>\n<pre class=\"brush: arduino; light: true; title: ; notranslate\" title=\"\">\r\n#include &lt;Adafruit_NeoPixel.h&gt;\r\n\r\nconst int controlPin = 12;  \/\/ the I\/O pin that the neopixel data signal is on\r\n\r\nconst int numPixels = 50;    \/\/ number of pixels in the strip\r\n\/\/ initialize the strip:\r\nAdafruit_NeoPixel strip = Adafruit_NeoPixel(numPixels, controlPin, NEO_RGB + NEO_KHZ800);\r\n\r\n\/\/ initial reference color range:\r\nconst unsigned long referenceColors&#x5B;] = {0xCB5D0F, 0xB4470C, 0x95310C, 0x854E0B};\r\n\/\/ the final color of all pixels before they flicker out:\r\nconst unsigned long finalColor = 0x1F0F02;\r\n\/\/ changing range of keyframe colors for the pixels to flicker to:\r\nunsigned long keyColors&#x5B;] = {0xCB500F, 0xB4410C, 0x95230C, 0x853E0B};\r\n\r\nunsigned long targetColor&#x5B;numPixels];    \/\/ next target for each pixel\r\nunsigned long pixelColor&#x5B;numPixels];     \/\/ current color for each pixel\r\n\r\n\/\/ count of keyframe colors:\r\nint numColors = sizeof(keyColors) \/ 4;\r\nunsigned long slowFadeInterval =  169400;   \/\/ in millis, the time between fade changes\r\nunsigned long lastFade = 0;                 \/\/ timestamp of the last call to fadeToRed()\r\nint flickerInterval = 30;                   \/\/ in millis, the delay between flicker steps\r\n\r\nboolean running = true; \/\/ whether or not your're running\r\nboolean finished = false; \/\/ whether or not the slow fade is finished\r\nvoid setup() {\r\n  strip.begin();          \/\/ initialize pixel strip\r\n}\r\n\r\nvoid loop() {\r\n  \/\/ create the flicker effect:\r\n  if (millis() % flickerInterval &lt; 2) {\r\n    flickerPixels();\r\n  }\r\n\r\n  \/\/ gradually fade the keyframe colors lower and more toward the red:\r\n  if (millis() - lastFade &gt;= slowFadeInterval) {\r\n    finished = fadeToRed();\r\n  }\r\n  \/\/ update the strip:\r\n  strip.show();\r\n}\r\n\r\n\/*\r\n  this function creates the flicker effect:\r\n*\/\r\nvoid flickerPixels() {\r\n  \/\/ iterate over all pixels:\r\n  for (int thisPixel = 0; thisPixel &lt; numPixels; thisPixel++) {\r\n    \/\/ if the target color matches the current color for this pixel,\r\n    \/\/ then pick a new target color randomly:\r\n    if (targetColor&#x5B;thisPixel] == pixelColor&#x5B;thisPixel]) {\r\n      int nextColor = random(numColors);\r\n      targetColor&#x5B;thisPixel] = keyColors&#x5B;nextColor];\r\n    }\r\n    \/\/ fade the pixel one step from the current color to the target color:\r\n    pixelColor&#x5B;thisPixel] = compare(pixelColor&#x5B;thisPixel], targetColor&#x5B;thisPixel]);\r\n    \/\/ set the pixel color in the strip:\r\n    strip.setPixelColor(thisPixel, pixelColor&#x5B;thisPixel]);\/\/ set the color for this pixel\r\n  }\r\n}\r\n\r\n\/*\r\n  This function fades all the key colors toward a low reddish orange\r\n*\/\r\nboolean fadeToRed() {\r\n  boolean result = true;\r\n  \/\/ iterate over all pixels:\r\n  for (int thisColor = 0; thisColor &lt; numColors; thisColor++) {\r\n    \/\/ calculate a new keyColor closer to the final color:\r\n    keyColors&#x5B;thisColor] = compare(keyColors&#x5B;thisColor], finalColor);\r\n\r\n    \/\/ if all the keyColors == the final color then you're finished:\r\n    if (keyColors&#x5B;thisColor] != finalColor) {\r\n      result = false;\r\n    }\r\n  }\r\n  lastFade = millis();\r\n  return result;\r\n}\r\n\r\n\/*\r\n  takes two colors and returns a color that's a point on each axis (r, g, b)\r\n  closer to the target color\r\n*\/\r\nunsigned long compare(unsigned long thisColor, unsigned long thatColor) {\r\n  \/\/ separate the first color:\r\n  byte r = thisColor &gt;&gt; 16;\r\n  byte g = thisColor &gt;&gt;  8;\r\n  byte b = thisColor;\r\n\r\n  \/\/ separate the second color:\r\n  byte targetR = thatColor &gt;&gt; 16;\r\n  byte targetG = thatColor &gt;&gt;  8;\r\n  byte targetB = thatColor;\r\n\r\n  \/\/ fade the first color toward the second color:\r\n  if (r &gt; targetR) r--;\r\n  if (g &gt; targetG) g--;\r\n  if (b &gt; targetB) b--;\r\n\r\n  if (r &lt; targetR) r++;\r\n  if (g &lt; targetG) g++;\r\n  if (b &lt; targetB) b++;\r\n\r\n  \/\/ combine the values to get the new color:\r\n  unsigned long result = ((unsigned long)r &lt;&lt; 16) | ((unsigned long)g &lt;&lt; 8) | b;\r\n  return result;\r\n}\r\n<\/pre>\n<h2>The Twinkle Effect (or &#8220;Every time a bell rings&#8230;&#8221;)<\/h2>\n<p>Once the flickering and fading was working, I added a routine to make a random light twinkle to white, for the &#8220;angel gets its wings&#8221; effect. This was simply a matter of picking a random pixel and setting its color to white, then letting the <code>flickerPixels()<\/code> and <code>fadeToRed()<\/code> functions restore it.<\/p>\n<p>I didn&#8217;t want to twinkle just any light, because some lights are not visible from the front of the tree. So I made a new global array, <code>visiblePixels[]<\/code>, and populated it with only the light\u00a0numbers that were visible from the front of the tree.<\/p>\n<p>Here&#8217;s the <code>twinkle()<\/code> function:<\/p>\n<pre class=\"brush: arduino; light: true; title: ; notranslate\" title=\"\">\r\n\r\n\/\/ new global variables:\r\nint visiblePixels&#x5B;] = {6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 40}; \/\/ pixels visible on the front of the tree\r\nint visibleCount = sizeof(visiblePixels) \/ 2;\r\n\r\n\/*\r\nthis function creates the twinkle effect:\r\n*\/\r\nvoid twinkle() {\r\n  int whichPixel = random(visibleCount);\r\n  int thisPixel = visiblePixels&#x5B;whichPixel]; \/\/ pick a random pixel from the visible list\r\n  pixelColor&#x5B;thisPixel] = 0xFFDDDD;          \/\/ set its color to white\r\n}\r\n<\/pre>\n<p>To test this function, I just used a serial input check in the main loop at first, like so:<\/p>\n<pre class=\"brush: arduino; light: true; title: ; notranslate\" title=\"\">\r\n   if (Serial.available() &gt; 0) {\r\n     char input = Serial.read();\r\n     if (input == 'x') {     \/\/ if the input is x, twinkle a light\r\n        twinkle();\r\n     }\r\n   }\r\n<\/pre>\n<p>To determine the visible lights, I wrote a sketch that allowed me to turn and off each light with a serial command, and asked Denise to tell me when she could see each light or not as I turned it on or off. The sketch saves a list of all the lights left on, and prints them out as a list. You can <a href=\"https:\/\/github.com\/tigoe\/NeoPixel_examples\/blob\/master\/BlinkyTree\/BlinkyTreeAddresser\/BlinkyTreeAddresser.ino\">see that sketch in the project&#8217;s gitHub repository<\/a>.<\/p>\n<p>Once I knew the twinkle effect worked the way I wanted it to, I added a capacitive touch sensor to the tree. I wired a piece of 22-AWG wire to a jingle bell that was hung from one branch, then ran the wire down the trunk to the processor, which was hidden under the skirt at the base of the tree. The capacitive touch sensing circuit took some experimentation to get it stable. To get this right I used the basic examples from the <a href=\"http:\/\/playground.arduino.cc\/Main\/CapacitiveSensor\">CapacitiveSensor Library<\/a> and modified the resistor until I got a value that triggered reliably when a person rang the bell. The stability of the circuit increased when I plugged the board was plugged into a grounded AC outlet. The final circuit is shown above. Here&#8217;s the final code for testing the sensor:<\/p>\n<pre class=\"brush: arduino; light: true; title: ; notranslate\" title=\"\">\r\n#include &lt;CapacitiveSensor.h&gt;\r\n\r\nCapacitiveSensor bell = CapacitiveSensor(10, 7);   \/\/ initialize cap touch library\r\nlong touchTime = 0;                      \/\/ time of last touch\r\nint touchState = 0;                      \/\/ if the bell is being touched\r\nint threshold = 1000;                    \/\/ touch sensitivity threshold\r\nint touchDelay = 500;                    \/\/ how long to delay before resetting touch sensor\r\n\r\nvoid setup() {\r\n  Serial.begin(9600);\r\n   bell.set_CS_AutocaL_Millis(0xFFFFFFFF);     \/\/ turn off touch sensor autocalibrate\r\n}\r\n\r\nvoid loop() {\r\n   \/\/ read touch sensor:\r\n  long bellTouch =  bell.capacitiveSensor(30);\r\n  \/\/ if the bell is touched and it wasn't touched\r\n  \/\/ on the last check:\r\n  if (bellTouch &gt; threshold &amp;&amp; touchState == 0) {\r\n    touchState = 1;\r\n    Serial.println(&quot;twinkle&quot;);\r\n    touchTime = millis();\r\n  }\r\n\r\n  \/\/ if the touch delay has passed, reset touchState:\r\n  if (millis() - touchTime &gt; touchDelay) {\r\n    touchState = 0;\r\n  }\r\n}\r\n<\/pre>\n<p>It&#8217;s important to test this with a <code>println()<\/code> statement, to make sure the twinkle effect is triggering only once every time you touch the bell. Otherwise, a single touch will trigger multiple lights to twinkle, which is not the desired effect.<\/p>\n<h2>Shutdown and Reset<\/h2>\n<p>When the fading effect reached the end of its run, the tree just sat with the lights in a dim red state. That&#8217;s no fun. So I wrote a function to turn off the lights one at a time when the tree reached the final color, and a reset function to set it back to its original state. Initially I triggered these with serial commands like the twinkle effect test, but later I added a web interface for them (see below). Here are the <code>resetStrip()<\/code> and <code>turnoff()<\/code> functions:<\/p>\n<pre class=\"brush: arduino; light: true; title: ; notranslate\" title=\"\">\r\n\/*\r\n This function resets all the pixels to their base colors:\r\n*\/\r\nboolean resetStrip() {\r\n \/\/ iterate over the pixels:\r\n for (int pixel = 0; pixel &lt; numPixels; pixel++) {\r\n \/\/ pick two random colors from the keyframe colors:\r\n int nextColor = random(numColors);\r\n int lastColor = random(numColors);\r\n targetColor&#x5B;pixel] = referenceColors&#x5B;nextColor];\r\n pixelColor&#x5B;pixel] = referenceColors&#x5B;lastColor];\r\n \/\/ set the pixel color:\r\n strip.setPixelColor(pixel, pixelColor&#x5B;pixel]);\/\/ set the color for this pixel\r\n }\r\n\r\n \/\/ reset the keyColor array with the reference color array:\r\n for (int p = 0; p &lt; numColors; p++) {\r\n keyColors&#x5B;p] = referenceColors&#x5B;p];\r\n }\r\n finished = false;\r\n return true;\r\n}\r\nboolean turnOff() {\r\n  \/\/ iterate over the pixels:\r\n  for (int pixel = 0; pixel &lt; numPixels; pixel++) {\r\n\r\n    \/\/ set the pixel color:\r\n    strip.setPixelColor(pixel, 0);\/\/ set the color for this pixel\r\n    strip.show();\r\n    delay(300);\r\n  }\r\n  return false;\r\n}\r\n<\/pre>\n<p>Now that these functions are introduced, I used the <code>running<\/code> flag to keep the lights off when they shouldn&#8217;t be running. The flag is initialized as true, and <code>turnOff()<\/code> sets it to false.<\/p>\n<p>I added a reset for the strip to the setup:<\/p>\n<pre class=\"brush: arduino; light: true; title: ; notranslate\" title=\"\">\r\nvoid setup() {\r\n  strip.begin();          \/\/ initialize pixel strip\r\n  resetStrip();           \/\/ start the long fade\r\n}\r\n<\/pre>\n<p>The main loop now looks like this:<\/p>\n<pre class=\"brush: arduino; light: true; title: ; notranslate\" title=\"\">\r\nvoid loop() {\r\n    \/\/ listen for serial commands:\r\n    if (Serial.available() &gt; 0) {\r\n      char input = Serial.read();\r\n      if (input == '0' ) {      \/\/ 0 means turn off lights\r\n        running = turnOff();\r\n      }\r\n      if (input == '1') {       \/\/ 1 means turn on lights\r\n        running = resetStrip();\r\n      }\r\n      if (input == 'x') {     \/\/ x means twinkle\r\n        twinkle();\r\n      }\r\n    }\r\n\r\n  if (running) {      \/\/ continue the long fade\r\n    \/\/ create the flicker effect:\r\n    if (millis() % flickerInterval &lt; 2) {\r\n      flickerPixels();\r\n    }\r\n\r\n    \/\/ gradually fade the keyframe colors lower and more toward the red:\r\n    if (millis() - lastFade &gt;= slowFadeInterval) {\r\n      finished = fadeToRed();\r\n    }\r\n  }\r\n  \/\/ when you reach the final colors, turn off:\r\n  if (finished) running = turnOff();\r\n\r\n  \/\/ read touch sensor:\r\n  long bellTouch =  bell.capacitiveSensor(30);\r\n  \/\/ if the bell is touched and it wasn't touched\r\n  \/\/ on the last check:\r\n  if (bellTouch &gt; threshold &amp;&amp; touchState == 0) {\r\n    touchState = 1;\r\n    twinkle();\r\n    touchTime = millis();\r\n  }\r\n\r\n  \/\/ if the touch delay has passed, reset touchState:\r\n  if (millis() - touchTime &gt; touchDelay) {\r\n    touchState = 0;\r\n  }\r\n\r\n  \/\/ update the strip:\r\n  strip.show();\r\n}\r\n<\/pre>\n<h2>The Web Interface<\/h2>\n<p>Once I had the lights working with the bell, and the fading effect working and a way to send in messages to the lights, I wanted to make a web interface. This is where the Y\u00fan was useful.<\/p>\n<p><strong>Note: Everything shown before this point will work on any Arduino, but the rest of this project will run only on an Arduino Y\u00fan.<\/strong><\/p>\n<p>The Bridge library has a Mailbox class that allows you to pass messages from the Y\u00fan&#8217;s linux processor to the 32U4 processor using a RESTian web interface. When you&#8217;ve added Mailbox to your sketch, you can make a web request like this:<\/p>\n<p><em>http:\/\/arduino.local\/mailbox\/hello<\/em><\/p>\n<p>And the 32U4 processor can get the last part of the string using a couple of lines of code, like this:<\/p>\n<pre class=\"brush: arduino; light: true; title: ; notranslate\" title=\"\">\r\nString message;\r\n\/\/ read all the messages present in the queue\r\n      while (Mailbox.messageAvailable())\r\n      {\r\n        Mailbox.readMessage(message);   \/\/ get the message\r\n        Serial.println(message);        \/\/ print it out\r\n<\/pre>\n<p>The web interface for our tree is pretty simple:<\/p>\n<p><em>http:\/\/arduino.local\/mailbox\/on<\/em>\u00a0 \u00a0 turned the tree on by calling the reset function<br \/>\n<em>http:\/\/arduino.local\/mailbox\/off<\/em>\u00a0 \u00a0 turned the tree off<br \/>\n<em>http:\/\/arduino.local\/mailbox\/twinkle<\/em>\u00a0 \u00a0 gives an angel its wings<\/p>\n<p>To implement this on the Arduino processor, I removed the serial input block and replaced it with the following Mailbox input block:<\/p>\n<pre class=\"brush: arduino; light: true; title: ; notranslate\" title=\"\">\r\n\/\/ new additions to the top of the sketch:\r\n#include &lt;Bridge.h&gt;\r\n#include &lt;Mailbox.h&gt;\r\n\r\n\/\/ additions to the setup:\r\nvoid setup() {\r\n  Bridge.begin();         \/\/ initialize Bridge\r\n  Mailbox.begin();        \/\/ initialize Mailbox\r\n  \/\/ rest of setup goes here\r\n}\r\n\r\n\/\/ changes to the main loop:\r\nvoid loop() {\r\n  String message;\r\n  \/\/ read the next message present in the queue\r\n  while (Mailbox.messageAvailable()) {\r\n    Mailbox.readMessage(message);\r\n    if (message == &quot;off&quot; ) {\r\n      running = turnOff();\r\n    }\r\n\r\n    if (message == &quot;on&quot;) {\r\n      running = resetStrip();\r\n    }\r\n\r\n    if (message == &quot;twinkle&quot;) {\r\n      twinkle();\r\n    }\r\n  }\r\n  \/\/ rest of the main loop goes here\r\n}\r\n<\/pre>\n<p>To build a web page for it, I used a little javaScript to automate the buttons using Lauren McCarthy&#8217;s <a href=\"http:\/\/p5js.org\/\">p5.js<\/a> library. I stored the web page on an SD card and installed on the Y\u00fan using the instructions in the <a href=\"http:\/\/arduino.cc\/en\/Tutorial\/TemperatureWebPanel\">TemperatureWebPanel<\/a> example. I got the <a href=\"http:\/\/www.orangefreesounds.com\/ding-sound-shiny\/\">ding sound from orangefreesounds.com<\/a>.<\/p>\n<p>Here&#8217;s the HTML:<\/p>\n<pre class=\"brush: xml; light: true; title: ; notranslate\" title=\"\">\r\n&lt;!DOCTYPE html&gt;\r\n&lt;html&gt;\r\n\t&lt;head&gt;\r\n\t\t&lt;script src=&quot;\/\/cdnjs.cloudflare.com\/ajax\/libs\/p5.js\/0.3.14\/p5.min.js&quot;&gt;&lt;\/script&gt;\r\n\t\t&lt;script src=&quot;\/\/cdnjs.cloudflare.com\/ajax\/libs\/p5.js\/0.3.14\/addons\/p5.dom.js&quot;&gt;&lt;\/script&gt;\r\n\t\t&lt;script src=&quot;\/\/cdnjs.cloudflare.com\/ajax\/libs\/p5.js\/0.3.14\/addons\/p5.sound.js&quot;&gt;&lt;\/script&gt;\r\n\t\t&lt;script&gt;\r\n\tvar twinkleButton, resetButton, offButton, result, mySound;\t\t\r\n\r\nfunction setup() {\r\n  \/\/ load the bell sound\r\n  mySound = loadSound('\/tree\/Ding-sound-shiny.mp3');\r\n\r\n  \/\/ create the twinkle button:\r\n  twinkleButton = createButton('Give an angel its wings');\r\n  twinkleButton.position(150, 65);        \/\/ position it\r\n  twinkleButton.mousePressed(twinkle);    \/\/ set the mousePressed callback function\r\n\r\n  \/\/ create the reset button:\r\n  resetButton = createButton('reset lights');\r\n  resetButton.position(150, 95);        \/\/ position it\r\n  resetButton.mousePressed(resetStrip); \/\/ set the mousePressed callback function\r\n\r\n  \/\/ create the lights off button:\r\n  offButton = createButton('turn off lights');\r\n  offButton.position(150, 125);        \/\/ position it\r\n  offButton.mousePressed(turnoff);     \/\/ set the mousePressed callback function\r\n}\r\n\r\nfunction twinkle() {\r\n\tresult = loadStrings(&quot;\/mailbox\/twinkle&quot;);\r\n\tmySound.play();\r\n}\r\n\r\nfunction resetStrip() {\r\n\tresult = loadStrings(&quot;\/mailbox\/on&quot;);\r\n}\r\n\r\nfunction turnoff() {\r\n\tresult = loadStrings(&quot;\/mailbox\/off&quot;);\r\n}\r\n\r\n       &lt;\/script&gt;\r\n\t&lt;\/head&gt;\r\n\t&lt;body&gt;\r\n        &lt;\/body&gt;\r\n&lt;\/html&gt;\r\n<\/pre>\n<h2>Automatic Scheduling<\/h2>\n<p>Since I wanted to have the tree turn on automatically at sundown and off after we went to bed, I set up a cron job on the Linux side of the Y\u00fan. <a href=\"http:\/\/linux.die.net\/man\/5\/crontab\">Cron<\/a> is a linux tool for scheduling tasks to happen. You set up a file, called a crontab, which sets the time you want a command to happen and the command you want to happen at the given time. A typical cron task might look like this:<\/p>\n<p><code><br \/>\n0 12 * * * echo \"hello\"<br \/>\n<\/code><\/p>\n<p>This job would print out the word &#8220;hello&#8221; every day at 12PM. The five columns of numbers are minutes (0 &#8211; 59), hour (0 &#8211; 23), day of month (0 &#8211; 31), month (0 &#8211; 12), day of week (0 &#8211; 6). A * in any column means to do it for every instance of that timespan. Here&#8217;s a useful <a href=\"http:\/\/www.adminschoice.com\/crontab-quick-reference\">cron quick reference<\/a>. Here are the details for <a href=\"http:\/\/wiki.openwrt.org\/doc\/howto\/notuci.config\">cron on openWRT<\/a>, the Y\u00fan&#8217;s linux distribution.<\/p>\n<p>Cron and the Bridge Mailbox class are useful ways to send timed messages from the linux side of the Y\u00fan to the Arduino side. The Linux processor can keep track of time in more complex ways, freeing the Arduino processor to focus on what it does well: realtime control of outputs and reading of sensors. By setting up a good crontab, and programming the Arduino processor to check messages regularly, you can achieve lots of different timed effects.<\/p>\n<p>To fill the Arduino processor&#8217;s mailbox, I used the linux <code>curl<\/code> command that allows you to make a HTTP request from the command line, like so:<\/p>\n<p><code>curl 'http:\/\/arduino.local\/mailbox\/twinkle'<\/code><\/p>\n<p>Since the web interface was on the same linux processor that was running the web service to which I was making requests, I knew that the address was http:\/\/localhost. The addresses were therefore:<\/p>\n<p><code><br \/>\nhttp:\/\/localhost\/mailbox\/on<br \/>\nhttp:\/\/localhost\/mailbox\/off<br \/>\nhttp:\/\/localhost\/mailbox\/twinkle<br \/>\n<\/code><\/p>\n<p>I wanted the lights on at 7AM and off at 8:15AM every day, then back on at 4:45PM and off again at 11PM every day. So I used the web interface and the <code>curl<\/code> command calling <em>\/mailbox\/on<\/em> and <em>\/mailbox\/off<\/em> as needed. My crontab file looked like this:<\/p>\n<p><code><br \/>\n0 7 * * * curl 'http:\/\/localhost\/mailbox\/on'<br \/>\n15 8 * * * curl 'http:\/\/localhost\/mailbox\/off'<br \/>\n45 16 * * * curl 'http:\/\/localhost\/mailbox\/on'<br \/>\n0 23 * * * curl 'http:\/\/localhost\/mailbox\/off'<br \/>\n<\/code><\/p>\n<p>To install and start this crontab on the Y\u00fan, I connected to the linux side via ssh from the command line of my computer:<\/p>\n<p><code><br \/>\n$ ssh root@arduino.localhost<br \/>\n<\/code><\/p>\n<p>Then when I was in, I issued the following command to change the default editor to nano, then start and enable cron:<\/p>\n<p><code><br \/>\n$ export EDITOR=nano<br \/>\n$ sh \/etc\/init.d\/cron start<br \/>\n$ sh \/etc\/init.d\/cron enable<br \/>\n<\/code><\/p>\n<p>then to edit the crontab:<\/p>\n<p><code><br \/>\n$ crontab -e<br \/>\n<\/code><\/p>\n<p>Then I added the lines above to the crontab file, and finished by saving it with control-X and Y to confirm. After that, it ran on its own, as long as the Y\u00fan was up and running.<\/p>\n<h2>The Finishing Touches<\/h2>\n<p>Not content to stop there, I really wanted to make the\u00a0fade sequence more flexible. \u00a0I picked the value for\u00a0slowFadeInterval so that I&#8217;d get about 4 hours of fading, but what if I wanted more than that, or less? Or what if I wanted to &#8220;fast-forward&#8221; the fade? I implemented these features with a couple more functions.<\/p>\n<p>First, I needed to know how many steps the total fade takes. To get that, you take the initial colors and the final color, separate them into their component red, green and blue components, then look for the largest difference. Here&#8217;s a function that does that:<\/p>\n<pre class=\"brush: arduino; light: true; title: ; notranslate\" title=\"\">\r\n\/*\r\n  This function calculates the fadeToRed() steps\r\n*\/\r\nlong calcFadeSteps() {\r\n  \/\/ separate the final color:\r\n  byte targetR = finalColor &gt;&gt; 16;\r\n  byte targetG = finalColor &gt;&gt;  8;\r\n  byte targetB = finalColor;\r\n\r\n  long numSteps = 0;\r\n  \/\/ loop over the reference colors\r\n  for (int thisColor = 0; thisColor &lt; numColors; thisColor++) {\r\n    \/\/ separate into R, G, B\r\n    byte r = referenceColors&#x5B;thisColor] &gt;&gt; 16;\r\n    byte g = referenceColors&#x5B;thisColor] &gt;&gt;  8;\r\n    byte b = referenceColors&#x5B;thisColor];\r\n\r\n    \/\/ calculate max of reference color - final color:\r\n    int redDifference = abs(r - targetR);\r\n    numSteps = max(redDifference, numSteps);\r\n    int greenDifference = abs(g - targetG);\r\n    numSteps = max(greenDifference, numSteps);\r\n    int blueDifference = abs(b - targetB);\r\n    numSteps = max(blueDifference, numSteps);\r\n  }\r\n  return numSteps;\r\n}\r\n<\/pre>\n<p>Once you know the number of steps, you need to know how many minutes you want those steps to take. The total cycle is the total fade time divided by the number of steps. Here&#8217;s a function for that:<\/p>\n<pre class=\"brush: arduino; light: true; title: ; notranslate\" title=\"\">\r\n\/*\r\n  This function calculates the interval for the fadeToRed() steps\r\n*\/\r\nunsigned long calcInterval(long fadeMinutes) {\r\n  if (fadeMinutes &lt;= 0) return 0;\r\n  unsigned long result = 0;\r\n  long steps = calcFadeSteps();\r\n\r\n  \/\/ return total fade time \/ numSteps\r\n  result = (fadeMinutes * 60 * 1000) \/ steps;\r\n  return result;\r\n}\r\n<\/pre>\n<p>To fast-forward, I decided the interface would be a slider that indicates the percentage of the cycle to which you want to jump. To implement that, I reset the strip, then step through a percentage of the total steps to get to the point I want. Here&#8217;s the function that does that:<\/p>\n<pre class=\"brush: arduino; light: true; title: ; notranslate\" title=\"\">\r\n\/*\r\n  This function fastforwards to a given percentage\r\n  of completion of the fadeToRed cycle\r\n*\/\r\nvoid fastForward(int targetPercent) {\r\n  if (targetPercent &lt;= 0) return;    \/\/ if targetPercent isn't valid, return\r\n\r\n  resetStrip();                      \/\/ reset the color values\r\n  long steps = calcFadeSteps();      \/\/ calculate how many steps to take\r\n\r\n  \/\/ calculate how many steps to take:\r\n  long targetStep = (steps * (100 - targetPercent)) \/ 100;\r\n  \/\/ step through that many steps:\r\n  while (steps &gt; targetStep) {\r\n    fadeToRed();        \/\/ fade the colors\r\n    steps--;            \/\/ decrement steps\r\n  }\r\n}\r\n<\/pre>\n<p>To add these functions to the user interface, I added two sliders to the web page.<\/p>\n<p>Here&#8217;s what it looks like now:<\/p>\n<p><a href=\"http:\/\/www.tigoe.com\/pcomp\/code\/wp-content\/uploads\/2014\/12\/web_page_screenshot.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-1277\" src=\"http:\/\/www.tigoe.com\/pcomp\/code\/wp-content\/uploads\/2014\/12\/web_page_screenshot.png\" alt=\"web_page_screenshot\" width=\"836\" height=\"524\" srcset=\"https:\/\/www.tigoe.com\/pcomp\/code\/wp-content\/uploads\/2014\/12\/web_page_screenshot.png 836w, https:\/\/www.tigoe.com\/pcomp\/code\/wp-content\/uploads\/2014\/12\/web_page_screenshot-300x188.png 300w\" sizes=\"auto, (max-width: 767px) 89vw, (max-width: 1000px) 54vw, (max-width: 1071px) 543px, 580px\" \/><\/a> And here&#8217;s the new HTML page that adds the two sliders:<\/p>\n<pre class=\"brush: xml; light: true; title: ; notranslate\" title=\"\">\r\n&lt;!DOCTYPE html&gt;\r\n&lt;html&gt;\r\n\t&lt;head&gt;\r\n\t\t&lt;script src=&quot;\/\/cdnjs.cloudflare.com\/ajax\/libs\/p5.js\/0.3.14\/p5.min.js&quot;&gt;&lt;\/script&gt;\r\n\t\t&lt;script src=&quot;\/\/cdnjs.cloudflare.com\/ajax\/libs\/p5.js\/0.3.14\/addons\/p5.dom.js&quot;&gt;&lt;\/script&gt;\r\n\t\t&lt;script src=&quot;\/\/cdnjs.cloudflare.com\/ajax\/libs\/p5.js\/0.3.14\/addons\/p5.sound.js&quot;&gt;&lt;\/script&gt;\r\n\t\t&lt;script&gt;\r\n\tvar twinkleButton, resetButton, offButton, result, mySound,fadeSlider;\t\t\r\n\r\nfunction setup() {\r\n  mySound = loadSound('\/tree\/Ding-sound-shiny.mp3');\r\n\r\n  twinkleButton = createButton('Give an angel its wings');\r\n  twinkleButton.position(150, 65);\r\n  twinkleButton.mousePressed(twinkle);\r\n\r\n  resetButton = createButton('reset lights');\r\n  resetButton.position(150, 95);\r\n  resetButton.mousePressed(resetStrip);\r\n\r\n  offButton = createButton('turn off lights');\r\n  offButton.position(150, 125);\r\n  offButton.mousePressed(turnoff);\r\n\r\n  var percentSpan = getElement(&quot;percent&quot;);\r\n  percentSpan.position(150, 155);\r\n  var percentSlider = getElement(&quot;percentSlider&quot;);\r\n  percentSlider.mouseReleased(fastForward);\r\n\r\n  var fadeTimeSpan = getElement(&quot;totalFadeTime&quot;);\r\n  fadeTimeSpan.position(150, 185);\r\n  fadeSlider = getElement(&quot;totalFadeSlider&quot;);\r\n  fadeSlider.mouseReleased(setFadeTime);\r\n}\r\n\r\nfunction twinkle() {\r\n\tresult = loadStrings(&quot;\/mailbox\/twinkle&quot;);\r\n\tmySound.play();\r\n}\r\n\r\nfunction resetStrip() {\r\n\tresult = loadStrings(&quot;\/mailbox\/on&quot;);\r\n}\r\n\r\nfunction turnoff() {\r\n\tresult = loadStrings(&quot;\/mailbox\/off&quot;);\r\n}\r\n\r\nfunction fastForward() {\r\n\tvar mySlider = getElement(&quot;percentSlider&quot;);\r\n\tvar myLabel = getElement(&quot;percentLabel&quot;);\r\n\tmyLabel.html(mySlider.value() + &quot;%&quot;);\r\n\tresult = loadStrings(&quot;\/mailbox\/ff\/&quot; + mySlider.value() );\r\n}\r\n\r\nfunction setFadeTime() {\r\n\tvar fadeLabel = getElement(&quot;totalFadeLabel&quot;);\r\n\tvar sliderLabel = Math.floor(fadeSlider.value() \/ 60) + &quot; hours, &quot;\r\n\t\t+ Math.floor(fadeSlider.value() % 60) + &quot; minutes&quot;;\r\n\tfadeLabel.html(sliderLabel);\r\n\tresult = loadStrings(&quot;\/mailbox\/fade\/&quot; + fadeSlider.value() );\r\n\r\n}\r\n\r\n\t&lt;\/script&gt;\r\n\t&lt;\/head&gt;\r\n\t&lt;body&gt;\r\n\t\t&lt;span id=&quot;percent&quot;&gt;\r\n\t\t\tPercent finished:\r\n\t\t\t&lt;input type=&quot;range&quot; id=&quot;percentSlider&quot; min=&quot;1&quot; max=&quot;100&quot; step=&quot;1&quot; \/\t&gt;\r\n\t\t\t&lt;label id=&quot;percentLabel&quot;&gt;&lt;\/label&gt;\r\n\t\t&lt;\/span&gt;\r\n\t\t&lt;span id=&quot;totalFadeTime&quot;&gt;Total Fade Time (in minutes):\r\n\t\t\t&lt;input type=&quot;range&quot; id=&quot;totalFadeSlider&quot; min=&quot;5&quot; max=&quot;400&quot; step=&quot;5&quot; value=&quot;60&quot; \/\t&gt;\r\n\t\t\t&lt;label id=&quot;totalFadeLabel&quot;&gt;&lt;\/label&gt;\r\n\t&lt;\/body&gt;\r\n&lt;\/html&gt;\r\n<\/pre>\n<p>It&#8217;s not a perfect web interface, as there&#8217;s no way to query the tree for its current state, and dynamically update the web page. But that leaves me a project for next year.<\/p>\n<p>The final code and circuits for this project are available in the <a href=\"https:\/\/github.com\/tigoe\/NeoPixel_examples\/tree\/master\/BlinkyTree\">gitHub repository for this project<\/a>.<\/p>\n<p>Here&#8217;s one more video of the final effect in action:<\/p>\n<p><iframe loading=\"lazy\" title=\"christmas-tree-2014\" src=\"https:\/\/player.vimeo.com\/video\/115453913?dnt=1&amp;app_id=122963\" width=\"226\" height=\"400\" frameborder=\"0\" allow=\"autoplay; fullscreen\" allowfullscreen><\/iframe><\/p>\n<p>Happy holidays!<\/p>\n","protected":false},"excerpt":{"rendered":"<p>As we planned for Christmas this year, my partner suggested that maybe we should replace the lights for the tree. &#8220;While we&#8217;re at it,&#8221; she asked, &#8220;is there anything out there that&#8217;s more controllable than just the ones that twinkle on and off?&#8221; &#8220;Well,&#8221; I said, &#8220;there are NeoPixels&#8230;&#8221; We decided that it would be &hellip; <\/p>\n<p class=\"link-more\"><a href=\"https:\/\/www.tigoe.com\/pcomp\/code\/arduinowiring\/1249\/\" class=\"more-link\">Continue reading<span class=\"screen-reader-text\"> &#8220;Programming a Christmas Tree&#8221;<\/span><\/a><\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[9,22,24,100],"tags":[107,108,110,109],"class_list":["post-1249","post","type-post","status-publish","format-standard","hentry","category-arduinowiring","category-AVR","category-circuits","category-code","tag-arduino-yun","tag-blinkytape","tag-neopixel","tag-ws2811"],"_links":{"self":[{"href":"https:\/\/www.tigoe.com\/pcomp\/code\/wp-json\/wp\/v2\/posts\/1249","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.tigoe.com\/pcomp\/code\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.tigoe.com\/pcomp\/code\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.tigoe.com\/pcomp\/code\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/www.tigoe.com\/pcomp\/code\/wp-json\/wp\/v2\/comments?post=1249"}],"version-history":[{"count":10,"href":"https:\/\/www.tigoe.com\/pcomp\/code\/wp-json\/wp\/v2\/posts\/1249\/revisions"}],"predecessor-version":[{"id":1286,"href":"https:\/\/www.tigoe.com\/pcomp\/code\/wp-json\/wp\/v2\/posts\/1249\/revisions\/1286"}],"wp:attachment":[{"href":"https:\/\/www.tigoe.com\/pcomp\/code\/wp-json\/wp\/v2\/media?parent=1249"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.tigoe.com\/pcomp\/code\/wp-json\/wp\/v2\/categories?post=1249"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.tigoe.com\/pcomp\/code\/wp-json\/wp\/v2\/tags?post=1249"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}