{"id":624,"date":"2015-09-09T12:56:49","date_gmt":"2015-09-09T17:56:49","guid":{"rendered":"http:\/\/bitquill.net\/blog\/?p=624"},"modified":"2016-05-12T14:24:39","modified_gmt":"2016-05-12T19:24:39","slug":"esp8266-light-controller-clock","status":"publish","type":"post","link":"http:\/\/bitquill.net\/blog\/esp8266-light-controller-clock\/","title":{"rendered":"Week-long hack: ESP8266 touchscreen WiFi light controller and clock"},"content":{"rendered":"<p>A couple of months ago I picked up cheap\u00c2\u00a0WiFi-controlled LED bulbs (<a title=\"MagicLight WiFi LED light bulb - Amazon.com\" href=\"http:\/\/www.amazon.com\/gp\/product\/B00SIDVZSW\">one<\/a>\u00c2\u00a0among\u00c2\u00a0dozens\u00c2\u00a0of very similar devices), after seeing them at a friend&#8217;s place. \u00c2\u00a0This turned out to be an excuse to play with the\u00c2\u00a0<a title=\"ESP8266 - Wikipedia\" href=\"https:\/\/en.wikipedia.org\/wiki\/ESP8266\">ESP8266<\/a>, which has inspired <a title=\"ESP8266 (tag) - Hackaday\" href=\"https:\/\/hackaday.com\/tag\/esp8266\/\">several hacks<\/a>.<\/p>\n<p>I was overall very happy with these bulbs: decent Android and iOS apps and, compared to fancier solutions (e.g., Philips Hue or Belkin WeMo), they\u00c2\u00a0do not require any proprietary base stations, and you can&#8217;t beat the price! \u00c2\u00a0However, switching off the lights before falling asleep involved\u00c2\u00a0hunting for the phone, opening the app, and waiting for it to scan the network; not an ideal user experience. \u00c2\u00a0I was actually missing our old <a title=\"X10 (industry standard) - Wikipedia\" href=\"https:\/\/en.wikipedia.org\/wiki\/X10_(industry_standard)\">X10<\/a>\u00c2\u00a0alarm clock controller (remember those?), so I decided to make one from scratch, because&#8230; why not?<\/p>\n<p>Although the X10 Powerhouse controller&#8217;s faux-wood styling\u00c2\u00a0and 7-segment LED had a certain&#8230; charm, I decided to go more modern and use a touchscreen. \u00c2\u00a0I also designed a 3D printed enclosure with simple geometric shapes and used it as a further excuse to play with 3D print finishing techniques. \u00c2\u00a0Here is the final result:<\/p>\n<p><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" data-attachment-id=\"631\" data-permalink=\"http:\/\/bitquill.net\/blog\/esp8266-light-controller-clock\/espclock-beautyshot\/\" data-orig-file=\"https:\/\/i0.wp.com\/bitquill.net\/blog\/wp-content\/uploads\/2015\/09\/espclock-beautyshot.jpg?fit=1947%2C1095\" data-orig-size=\"1947,1095\" data-comments-opened=\"1\" data-image-meta=\"{&quot;aperture&quot;:&quot;2.4&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;iPad Air&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;1441719702&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;3.3&quot;,&quot;iso&quot;:&quot;32&quot;,&quot;shutter_speed&quot;:&quot;0.041666666666667&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;1&quot;}\" data-image-title=\"ESP Clock\" data-image-description=\"\" data-image-caption=\"\" data-large-file=\"https:\/\/i0.wp.com\/bitquill.net\/blog\/wp-content\/uploads\/2015\/09\/espclock-beautyshot.jpg?fit=1024%2C576\" class=\"alignnone wp-image-631\" src=\"https:\/\/i0.wp.com\/bitquill.net\/blog\/wp-content\/uploads\/2015\/09\/espclock-beautyshot.jpg?resize=768%2C432\" alt=\"ESP Clock\" width=\"768\" height=\"432\" srcset=\"https:\/\/i0.wp.com\/bitquill.net\/blog\/wp-content\/uploads\/2015\/09\/espclock-beautyshot.jpg?resize=1024%2C576 1024w, https:\/\/i0.wp.com\/bitquill.net\/blog\/wp-content\/uploads\/2015\/09\/espclock-beautyshot.jpg?resize=300%2C169 300w, https:\/\/i0.wp.com\/bitquill.net\/blog\/wp-content\/uploads\/2015\/09\/espclock-beautyshot.jpg?w=1947 1947w\" sizes=\"auto, (max-width: 768px) 100vw, 768px\" \/><\/p>\n<p>And here it is in action:<\/p>\n<p><iframe loading=\"lazy\" src=\"https:\/\/www.youtube.com\/embed\/hKBLLkvEEXE\" width=\"560\" height=\"315\" frameborder=\"0\" allowfullscreen=\"allowfullscreen\"><\/iframe><\/p>\n<p>If this seems interesting, read on for details. \u00c2\u00a0The source code for everything is <a title=\"spapadim\/ESPClock - GitHub\" href=\"https:\/\/github.com\/spapadim\/ESPClock\">available on GitHub<\/a>. <strong>Edit:<\/strong>\u00c2\u00a0You can also check the <a href=\"https:\/\/hackaday.io\/project\/7611-diy-chumby-lite\">Hackaday.io project page<\/a> for occasional updates.<\/p>\n<p><!--more--><\/p>\n<p><strong>Component selection.<\/strong>\u00c2\u00a0There are several boards with the ESP8266, most of them using the ESP-12 module. I decided to go with the\u00c2\u00a0<a title=\"SparkFin ESP8266 Thing - SparkFun\" href=\"https:\/\/www.sparkfun.com\/products\/13231\">SparkFun Thing<\/a>\u00c2\u00a0(which directly incorporates the ESP chip), as it also includes a LiPo charge controller. \u00c2\u00a0Perhaps overkill for battery backup, but nice to have. \u00c2\u00a0If you do use the charge controller, then the price is very reasonable (e.g., an\u00c2\u00a0<a title=\"Adafruit HUZZAH ESP8266 Breakout - Adafruit\" href=\"https:\/\/www.adafruit.com\/product\/2471\">Adafruit ESP breakout<\/a> and <a title=\"Adafruit Micro Lipo w\/MicroUSB Jack - USB LiIon\/LiPoly charger - Adafruit\" href=\"https:\/\/www.adafruit.com\/product\/1904\">Micro-LiPo<\/a>\u00c2\u00a0combo will cost about the same&#8211;although flash is 4x larger and the ESP-12 module is FCC-approved). Also, it&#8217;s a very nice board for experimentation and it&#8217;s become my go-to ESP board: nice header layout, and the easiest to program (tip: instead of fiddling with the DTR jumper on the Thing, just cut your DTR wire\u00c2\u00a0and insert a pin header pair: once <code>esptool<\/code> starts uploading, just pull the pin and.. done!).<!--more--><\/p>\n<p>For the display, modules with a parallel interface were out of the question, since the ESP does not have enough pins. After some googling, I found\u00c2\u00a0<a title=\"Serial IPS TFT 320x240 with Touchscreen - Digole\" href=\"http:\/\/digole.com\/index.php?productID=1208\">Digole&#8217;s IPS touchscreen<\/a>, which incorporates a PIC MCU and can connect over UART, I2C, or SPI (selectable via a solder jumper).\u00c2\u00a0There are several users that really like Digole&#8217;s display modules and, particularly their older models, seem quite popular. The display itself is very nice. \u00c2\u00a0However, touchscreen support appears to be relatively recent and isn&#8217;t that great (more later). \u00c2\u00a0It is also a bit on the expensive side, the firmware is not upgradeable (so you&#8217;re basically stuck with whatever version your module comes loaded with &#8212; I got one with an older version that has some bugs with 18-bit color support), and manufacturing quality could have been a bit better (mine had <a href=\"http:\/\/i.imgur.com\/FDIPy4Ll.jpg\">poor reflow<\/a>). \u00c2\u00a0Still, for prototype experimentation, this isn&#8217;t a bad module and the company is generally helpful to customer inquiries.<\/p>\n<p>I also picked up a DS3231 RTC module off of Amazon, but I ended up not using it; periodically synchronizing with an NTP server is more than good enough.<\/p>\n<p><strong>Total cost.<\/strong>\u00c2\u00a0 The first version of this device comes to about $45 including everything: SparkFun Thing ($15), touchscreen (highest cost at $21.50), and 500mAh LiPo cell ($8.50 off eBay). However, in retrospect, it could be done for much less:\u00c2\u00a0<strong>about $13 total (!)<\/strong>\u00c2\u00a0if you skip the LiPo (and charge controller), using a $5-6 ESP module instead, and also get a much cheaper ILI9341 touchscreen module (not IPS, but just $7 off eBay; I have one on the way from China). This does not include plastic filament (maybe a dollar?), paint (assuming you have these already, doesn&#8217;t use much), and labor.<\/p>\n<p><strong>3D-printed enclosure.<\/strong>\u00c2\u00a0I mocked a couple of profiles in 2D CAD to see what I like, and then did the actual design in OpenSCAD, which is my go-to CAD tool, because&#8230; code! (Who has time for point-and-click? :) \u00c2\u00a0It&#8217;s a fairly standard affair, with simple geometric shapes, designed in multiple pieces for printing.<\/p>\n<p><a href=\"https:\/\/i0.wp.com\/bitquill.net\/blog\/wp-content\/uploads\/2015\/09\/openscad.png\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" data-attachment-id=\"660\" data-permalink=\"http:\/\/bitquill.net\/blog\/esp8266-light-controller-clock\/openscad\/\" data-orig-file=\"https:\/\/i0.wp.com\/bitquill.net\/blog\/wp-content\/uploads\/2015\/09\/openscad.png?fit=1564%2C880\" data-orig-size=\"1564,880\" data-comments-opened=\"1\" data-image-meta=\"{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}\" data-image-title=\"openscad\" data-image-description=\"\" data-image-caption=\"\" data-large-file=\"https:\/\/i0.wp.com\/bitquill.net\/blog\/wp-content\/uploads\/2015\/09\/openscad.png?fit=1024%2C576\" class=\"alignnone wp-image-660\" src=\"https:\/\/i0.wp.com\/bitquill.net\/blog\/wp-content\/uploads\/2015\/09\/openscad.png?resize=768%2C432\" alt=\"openscad\" width=\"768\" height=\"432\" srcset=\"https:\/\/i0.wp.com\/bitquill.net\/blog\/wp-content\/uploads\/2015\/09\/openscad.png?resize=1024%2C576 1024w, https:\/\/i0.wp.com\/bitquill.net\/blog\/wp-content\/uploads\/2015\/09\/openscad.png?resize=300%2C169 300w, https:\/\/i0.wp.com\/bitquill.net\/blog\/wp-content\/uploads\/2015\/09\/openscad.png?w=1564 1564w\" sizes=\"auto, (max-width: 768px) 100vw, 768px\" \/><\/a><\/p>\n<p>The picture above shows the parts in their printing orientation. The standoffs are conical to eliminate the need for supports (alternatively, I could have printed them as separate parts, but getting them inserted is too fiddly, especially in tight spaces like this). The cylindrical sections (middle right) are support ribs which I ABS-glued to the main enclosure&#8217;s vertices. They serve two purposes. First, to hold the endcaps in place (the ribs are slightly shorter than the enclosure). Second, to provide some extra support (after gluing, rib layers are perpendicular to enclosure layers). Printing them separately may be unnecessary overkill (there is also a version of the enclosure and ribs in one piece, which requires some extra support to print, but not much), but gluing them is easy enough so&#8230; why not.\u00c2\u00a0The little clip (top right) is for holding the LiPo cell in place, and is also glued inside the main enclosure. \u00c2\u00a0It&#8217;s printed separately to eliminate the need for support\u00c2\u00a0(and, at the prototyping stage, also make it\u00c2\u00a0a little easier\u00c2\u00a0to try different battery sizes, without having to re-print the whole thing or do separate test-prints).<\/p>\n<p>One part of the design that does require a lot of support is the opening for the display. \u00c2\u00a0I entertained the idea of printing the main enclosure in three vertical sections (and gluing them together), but eventually decided against it. Printing that successfully took a bit of trial and error. \u00c2\u00a0I use both Cura and Slic3r. \u00c2\u00a0For most parts I used Slic3r (mainly because\u00c2\u00a0it produces smoother outer perimeters, and also integrates better with Octoprint). \u00c2\u00a0However, for the life of me, I haven&#8217;t managed to print supports that break off easily. \u00c2\u00a0Even with the new pillar mode, most parts are fine, except one part somewhere that&#8217;s just too close to the print to separate! \u00c2\u00a0Cura, on the other hand, always does an excellent job with supports.<\/p>\n<p>Finally, when designing cases like this, one of the (many!) things I like about open-source hardware is that I can download the PCB layout and get precise component positions and dimensions; no calipers and almost-there test prints! \u00c2\u00a0Sometimes it&#8217;s the little things&#8230;<\/p>\n<p>You will note, however, that there are holes to insert hex nuts, which are visible from the outside and would have been rather ugly (you don&#8217;t see exposed fasteners in &#8220;real&#8221; products). \u00c2\u00a0Which brings me to the next trick.<\/p>\n<p><strong>Friction welding: dos and don&#8217;ts.<\/strong>\u00c2\u00a0 I first heard about friction welding through Make magazine&#8217;s excellent <a title=\"Skill Builder - Finishing and Post-Processing Your 3D Printed Objects -- Make:\" href=\"http:\/\/makezine.com\/projects\/make-34\/skill-builder-finishing-and-post-processing-your-3d-printed-objects\/\">article on 3D print post-processing<\/a>\u00c2\u00a0and since then it has become one of my favorite techniques.\u00c2\u00a0I&#8217;ve seen a few tutorials on YouTube about friction welding plastics using a rotary tool. \u00c2\u00a0However, at least the ones I found, seem to be from people who recently\u00c2\u00a0learned the technique themselves and are excited to share it. \u00c2\u00a0I wish Make: had placed more emphasis on this (it would have saved me several failed attempts), but <strong>do not skip step 2c (pre-heating the surfaces); this is crucial!<\/strong>\u00c2\u00a0 And, no matter what you do, <strong>do not immediately press the spinning, cold filament onto the cold pieces\u00c2\u00a0<\/strong>(as some of these tutorials appear to suggest), since you&#8217;ll most likely gouge them. \u00c2\u00a0An alternative I&#8217;ve found to pre-heating with a heat gun is to <strong>use friction itself to do the preheating<\/strong>. Initially, just barely touch the spinning filament onto the plastic surfaces (not on the metal). \u00c2\u00a0Without applying any pressure, <strong>wait until you see a tiny bit of plastic start flowing<\/strong>. \u00c2\u00a0Only then gradually increase the pressure and start moving the filament, to keep a consistent flow. \u00c2\u00a0Also, if blobs form on the tip of the filament, it&#8217;s best to stop and lightly spin it\u00c2\u00a0against some sandpaper to clean them off.<\/p>\n<p><strong>Embedding nuts with friction welding.\u00c2\u00a0<\/strong>Using friction welding to embed nuts is a trick I came upon by accident. \u00c2\u00a0When I was building my <a title=\"Kossel - RepRapWiki\" href=\"http:\/\/reprap.org\/wiki\/Kossel\">Kossel<\/a>-based printer, I overtighened the screws holding the rods to the effector, stripping the cutouts for the nylocs. \u00c2\u00a0I was too lazy\/impatient to print another effector, so I just quickly filled the gaps using friction welding. \u00c2\u00a0I&#8217;m still using that effector, which has held the nuts very nicely for over a year (and after having\u00c2\u00a0taken the effector apart several times, to tweak various things).<\/p>\n<p>I now regularly use this technique to also hold magnets and, generally, anything inserted that needs to stay put. \u00c2\u00a0Superglue is the easiest, but it develops stress cracks and invariably fails over time (and, if you&#8217;re thinking threadlocker, don&#8217;t: it will craze the plastic, especially ABS). \u00c2\u00a0Next easiest is using a soldering iron to press the nuts\/items into the plastic, which is I use very often (I regularly design all my holes undersized and do this anyway). \u00c2\u00a0However: (i) you can&#8217;t use it on non-metal items; (ii) you can&#8217;t use it on magnets (the necessary heat will demagnetize them); (iii) if you don&#8217;t have a steady hand, you may loosen\u00c2\u00a0the hole enough to cause the part to fall out eventually, even if it seems fine at first. \u00c2\u00a0Friction welding takes a bit more time, but it&#8217;s the best solution I&#8217;ve found so far and it&#8217;s also very easy after just a little bit of \u00c2\u00a0practice. \u00c2\u00a0I haven&#8217;t tried threaded inserts yet. The McMaster-Carr &#8220;heat-set inserts for plastics&#8221; (it appears their site does not support direct linking!?)\u00c2\u00a0that <a href=\"https:\/\/www.youtube.com\/watch?v=iGNXHWPFAKo&amp;t=113s\">Werner Berry uses<\/a>\u00c2\u00a0look really nice and I&#8217;ve been itching to try them, but that&#8217;s another piece of hardware I need to keep around.<\/p>\n<p>Another nice thing is that you can use this trick to embed blind nuts that are not visible from the outside. \u00c2\u00a0This is a trick that is rather obvious (once you&#8217;ve done all the above :). \u00c2\u00a0First, insert the nuts (I used the soldering iron) and make sure the surface is flat (lightly file, if necessary):<\/p>\n<p><a href=\"https:\/\/i0.wp.com\/bitquill.net\/blog\/wp-content\/uploads\/2015\/09\/insert1.jpg\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" data-attachment-id=\"643\" data-permalink=\"http:\/\/bitquill.net\/blog\/esp8266-light-controller-clock\/insert1\/\" data-orig-file=\"https:\/\/i0.wp.com\/bitquill.net\/blog\/wp-content\/uploads\/2015\/09\/insert1.jpg?fit=1353%2C1522\" data-orig-size=\"1353,1522\" data-comments-opened=\"1\" data-image-meta=\"{&quot;aperture&quot;:&quot;2.4&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;iPad Air&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;1441436393&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;3.3&quot;,&quot;iso&quot;:&quot;160&quot;,&quot;shutter_speed&quot;:&quot;0.041666666666667&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;1&quot;}\" data-image-title=\"insert1\" data-image-description=\"\" data-image-caption=\"\" data-large-file=\"https:\/\/i0.wp.com\/bitquill.net\/blog\/wp-content\/uploads\/2015\/09\/insert1.jpg?fit=910%2C1024\" class=\"alignnone wp-image-643\" src=\"https:\/\/i0.wp.com\/bitquill.net\/blog\/wp-content\/uploads\/2015\/09\/insert1.jpg?resize=384%2C432\" alt=\"insert1\" width=\"384\" height=\"432\" srcset=\"https:\/\/i0.wp.com\/bitquill.net\/blog\/wp-content\/uploads\/2015\/09\/insert1.jpg?resize=910%2C1024 910w, https:\/\/i0.wp.com\/bitquill.net\/blog\/wp-content\/uploads\/2015\/09\/insert1.jpg?resize=267%2C300 267w, https:\/\/i0.wp.com\/bitquill.net\/blog\/wp-content\/uploads\/2015\/09\/insert1.jpg?w=1353 1353w\" sizes=\"auto, (max-width: 384px) 100vw, 384px\" \/><\/a>\u00c2\u00a0<a href=\"https:\/\/i0.wp.com\/bitquill.net\/blog\/wp-content\/uploads\/2015\/09\/insert2.jpg\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" data-attachment-id=\"642\" data-permalink=\"http:\/\/bitquill.net\/blog\/esp8266-light-controller-clock\/insert2\/\" data-orig-file=\"https:\/\/i0.wp.com\/bitquill.net\/blog\/wp-content\/uploads\/2015\/09\/insert2.jpg?fit=1210%2C1361\" data-orig-size=\"1210,1361\" data-comments-opened=\"1\" data-image-meta=\"{&quot;aperture&quot;:&quot;2.4&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;iPad Air&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;1441438722&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;3.3&quot;,&quot;iso&quot;:&quot;160&quot;,&quot;shutter_speed&quot;:&quot;0.041666666666667&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;1&quot;}\" data-image-title=\"insert2\" data-image-description=\"\" data-image-caption=\"\" data-large-file=\"https:\/\/i0.wp.com\/bitquill.net\/blog\/wp-content\/uploads\/2015\/09\/insert2.jpg?fit=910%2C1024\" class=\"alignnone wp-image-642\" src=\"https:\/\/i0.wp.com\/bitquill.net\/blog\/wp-content\/uploads\/2015\/09\/insert2.jpg?resize=384%2C432\" alt=\"insert2\" width=\"384\" height=\"432\" srcset=\"https:\/\/i0.wp.com\/bitquill.net\/blog\/wp-content\/uploads\/2015\/09\/insert2.jpg?resize=910%2C1024 910w, https:\/\/i0.wp.com\/bitquill.net\/blog\/wp-content\/uploads\/2015\/09\/insert2.jpg?resize=267%2C300 267w, https:\/\/i0.wp.com\/bitquill.net\/blog\/wp-content\/uploads\/2015\/09\/insert2.jpg?w=1210 1210w\" sizes=\"auto, (max-width: 384px) 100vw, 384px\" \/><\/a><\/p>\n<p>Make sure that the fastener axis is oriented properly (if not, adjust). \u00c2\u00a0Then, fully thread the holes from the outside. \u00c2\u00a0Use a proper tap (not a screw) to cut threads, especially for finer pitches. \u00c2\u00a0Do not skip this step (more later).<\/p>\n<p><a href=\"https:\/\/i0.wp.com\/bitquill.net\/blog\/wp-content\/uploads\/2015\/09\/insert3.jpg\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" data-attachment-id=\"641\" data-permalink=\"http:\/\/bitquill.net\/blog\/esp8266-light-controller-clock\/insert3\/\" data-orig-file=\"https:\/\/i0.wp.com\/bitquill.net\/blog\/wp-content\/uploads\/2015\/09\/insert3.jpg?fit=1354%2C1523\" data-orig-size=\"1354,1523\" data-comments-opened=\"1\" data-image-meta=\"{&quot;aperture&quot;:&quot;2.4&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;iPad Air&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;1441436954&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;3.3&quot;,&quot;iso&quot;:&quot;80&quot;,&quot;shutter_speed&quot;:&quot;0.041666666666667&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;1&quot;}\" data-image-title=\"insert3\" data-image-description=\"\" data-image-caption=\"\" data-large-file=\"https:\/\/i0.wp.com\/bitquill.net\/blog\/wp-content\/uploads\/2015\/09\/insert3.jpg?fit=910%2C1024\" class=\"alignnone wp-image-641\" src=\"https:\/\/i0.wp.com\/bitquill.net\/blog\/wp-content\/uploads\/2015\/09\/insert3.jpg?resize=384%2C432\" alt=\"insert3\" width=\"384\" height=\"432\" srcset=\"https:\/\/i0.wp.com\/bitquill.net\/blog\/wp-content\/uploads\/2015\/09\/insert3.jpg?resize=910%2C1024 910w, https:\/\/i0.wp.com\/bitquill.net\/blog\/wp-content\/uploads\/2015\/09\/insert3.jpg?resize=267%2C300 267w, https:\/\/i0.wp.com\/bitquill.net\/blog\/wp-content\/uploads\/2015\/09\/insert3.jpg?w=1354 1354w\" sizes=\"auto, (max-width: 384px) 100vw, 384px\" \/><\/a>\u00c2\u00a0<a href=\"https:\/\/i0.wp.com\/bitquill.net\/blog\/wp-content\/uploads\/2015\/09\/insert4.jpg\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" data-attachment-id=\"640\" data-permalink=\"http:\/\/bitquill.net\/blog\/esp8266-light-controller-clock\/insert4\/\" data-orig-file=\"https:\/\/i0.wp.com\/bitquill.net\/blog\/wp-content\/uploads\/2015\/09\/insert4.jpg?fit=1350%2C1519\" data-orig-size=\"1350,1519\" data-comments-opened=\"1\" data-image-meta=\"{&quot;aperture&quot;:&quot;2.4&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;iPad Air&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;1441437374&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;3.3&quot;,&quot;iso&quot;:&quot;125&quot;,&quot;shutter_speed&quot;:&quot;0.041666666666667&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;1&quot;}\" data-image-title=\"insert4\" data-image-description=\"\" data-image-caption=\"\" data-large-file=\"https:\/\/i0.wp.com\/bitquill.net\/blog\/wp-content\/uploads\/2015\/09\/insert4.jpg?fit=910%2C1024\" class=\"alignnone wp-image-640\" src=\"https:\/\/i0.wp.com\/bitquill.net\/blog\/wp-content\/uploads\/2015\/09\/insert4.jpg?resize=384%2C432\" alt=\"insert4\" width=\"384\" height=\"432\" srcset=\"https:\/\/i0.wp.com\/bitquill.net\/blog\/wp-content\/uploads\/2015\/09\/insert4.jpg?resize=910%2C1024 910w, https:\/\/i0.wp.com\/bitquill.net\/blog\/wp-content\/uploads\/2015\/09\/insert4.jpg?resize=267%2C300 267w, https:\/\/i0.wp.com\/bitquill.net\/blog\/wp-content\/uploads\/2015\/09\/insert4.jpg?w=1350 1350w\" sizes=\"auto, (max-width: 384px) 100vw, 384px\" \/><\/a><\/p>\n<p>Finally, apply molten plastic, starting from the outside (i.e., touching the perimeter of the hole, plastic-to-plastic) and working your way towards the center. \u00c2\u00a0Once you&#8217;re done (if you do it right, you should end up with a very clean-looking plug, without any gouges or streaks), lightly file to make the surface flat.<\/p>\n<p><a href=\"https:\/\/i0.wp.com\/bitquill.net\/blog\/wp-content\/uploads\/2015\/09\/weld1.jpg\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" data-attachment-id=\"645\" data-permalink=\"http:\/\/bitquill.net\/blog\/esp8266-light-controller-clock\/weld1\/\" data-orig-file=\"https:\/\/i0.wp.com\/bitquill.net\/blog\/wp-content\/uploads\/2015\/09\/weld1.jpg?fit=1483%2C1668\" data-orig-size=\"1483,1668\" data-comments-opened=\"1\" data-image-meta=\"{&quot;aperture&quot;:&quot;2.4&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;iPad Air&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;1441441886&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;3.3&quot;,&quot;iso&quot;:&quot;125&quot;,&quot;shutter_speed&quot;:&quot;0.041666666666667&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;1&quot;}\" data-image-title=\"weld1\" data-image-description=\"\" data-image-caption=\"\" data-large-file=\"https:\/\/i0.wp.com\/bitquill.net\/blog\/wp-content\/uploads\/2015\/09\/weld1.jpg?fit=910%2C1024\" class=\"alignnone wp-image-645\" src=\"https:\/\/i0.wp.com\/bitquill.net\/blog\/wp-content\/uploads\/2015\/09\/weld1.jpg?resize=384%2C432\" alt=\"weld1\" width=\"384\" height=\"432\" srcset=\"https:\/\/i0.wp.com\/bitquill.net\/blog\/wp-content\/uploads\/2015\/09\/weld1.jpg?resize=910%2C1024 910w, https:\/\/i0.wp.com\/bitquill.net\/blog\/wp-content\/uploads\/2015\/09\/weld1.jpg?resize=267%2C300 267w, https:\/\/i0.wp.com\/bitquill.net\/blog\/wp-content\/uploads\/2015\/09\/weld1.jpg?w=1483 1483w\" sizes=\"auto, (max-width: 384px) 100vw, 384px\" \/><\/a>\u00c2\u00a0<a href=\"https:\/\/i0.wp.com\/bitquill.net\/blog\/wp-content\/uploads\/2015\/09\/weld2.jpg\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" data-attachment-id=\"644\" data-permalink=\"http:\/\/bitquill.net\/blog\/esp8266-light-controller-clock\/weld2\/\" data-orig-file=\"https:\/\/i0.wp.com\/bitquill.net\/blog\/wp-content\/uploads\/2015\/09\/weld2.jpg?fit=1519%2C1709\" data-orig-size=\"1519,1709\" data-comments-opened=\"1\" data-image-meta=\"{&quot;aperture&quot;:&quot;2.4&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;iPad Air&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;1441442621&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;3.3&quot;,&quot;iso&quot;:&quot;125&quot;,&quot;shutter_speed&quot;:&quot;0.041666666666667&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;1&quot;}\" data-image-title=\"weld2\" data-image-description=\"\" data-image-caption=\"\" data-large-file=\"https:\/\/i0.wp.com\/bitquill.net\/blog\/wp-content\/uploads\/2015\/09\/weld2.jpg?fit=910%2C1024\" class=\"alignnone wp-image-644\" src=\"https:\/\/i0.wp.com\/bitquill.net\/blog\/wp-content\/uploads\/2015\/09\/weld2.jpg?resize=384%2C432\" alt=\"weld2\" width=\"384\" height=\"432\" srcset=\"https:\/\/i0.wp.com\/bitquill.net\/blog\/wp-content\/uploads\/2015\/09\/weld2.jpg?resize=910%2C1024 910w, https:\/\/i0.wp.com\/bitquill.net\/blog\/wp-content\/uploads\/2015\/09\/weld2.jpg?resize=267%2C300 267w, https:\/\/i0.wp.com\/bitquill.net\/blog\/wp-content\/uploads\/2015\/09\/weld2.jpg?w=1519 1519w\" sizes=\"auto, (max-width: 384px) 100vw, 384px\" \/><\/a><\/p>\n<p>Done! Now the nuts are not visible from the outside, and you have a very clean finish. \u00c2\u00a0Additional advantages of this approach: you do not need easy access to the hole from the fastener side (in this enclosure it would have been very difficult to insert the nuts and\/or tap the holes from the inside), and you can use a regular taper or plug tap (rather than a bottom tap).<\/p>\n<p><strong>3D-print finishing.<\/strong>\u00c2\u00a0Although I often like the surface finish of 3D printed layers, in this case I wanted a smoother, more &#8220;product-like&#8221; finish. \u00c2\u00a0Some time ago I bought some <a title=\"XTC-3D High Performance 3D Print Coating - SmoothOn\" href=\"http:\/\/www.smooth-on.com\/Epoxy-Coatings-XTC\/c1397_1429\/index.html\">XTC-3D<\/a>\u00c2\u00a0and this was a good opportunity to play with it a little more. \u00c2\u00a0Overall, XTC works very well; especially on organic\/curved shapes, you&#8217;re pretty much done after applying. Do follow the instructions about applying very thin coats (it <em>will<\/em> even out, even if it does not look like it at first). \u00c2\u00a0However, in this case (no pun intended) there were two issues. First, I used an older printer (a Solidoodle 2; my Kossel is not yet set up for long ABS prints) which has significant banding. XTC is good, but it&#8217;s not magic; I did some initial sanding (and cleaning with denatured alcohol) before applying the XTC resin. \u00c2\u00a0Second, on large flat surfaces, you will get some minor unevenness and some tiny bubbles here and there.\u00c2\u00a0Light sanding (with a sanding block!) will address most of these issues, but in some places you may need to use a little filler. \u00c2\u00a0One-part Bondo spot putty is sufficient for this. \u00c2\u00a0Apply it generously, and after it is dry, sand most of it off (it sands very easily). \u00c2\u00a0Do wait for it to set, though. \u00c2\u00a0Especially on thick coats, the manufacturer&#8217;s recommended set time (25 minutes) may not be sufficient; rule of thumb is to wait until it turns light pink <em>everywhere<\/em> and then wait some more.<\/p>\n<p><a href=\"https:\/\/i0.wp.com\/bitquill.net\/blog\/wp-content\/uploads\/2015\/09\/bondo1.jpg\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" data-attachment-id=\"648\" data-permalink=\"http:\/\/bitquill.net\/blog\/esp8266-light-controller-clock\/bondo1\/\" data-orig-file=\"https:\/\/i0.wp.com\/bitquill.net\/blog\/wp-content\/uploads\/2015\/09\/bondo1.jpg?fit=1396%2C1571\" data-orig-size=\"1396,1571\" data-comments-opened=\"1\" data-image-meta=\"{&quot;aperture&quot;:&quot;2.4&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;iPad Air&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;1441534573&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;3.3&quot;,&quot;iso&quot;:&quot;40&quot;,&quot;shutter_speed&quot;:&quot;0.041666666666667&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;1&quot;}\" data-image-title=\"bondo1\" data-image-description=\"\" data-image-caption=\"\" data-large-file=\"https:\/\/i0.wp.com\/bitquill.net\/blog\/wp-content\/uploads\/2015\/09\/bondo1.jpg?fit=910%2C1024\" class=\"alignnone wp-image-648\" src=\"https:\/\/i0.wp.com\/bitquill.net\/blog\/wp-content\/uploads\/2015\/09\/bondo1.jpg?resize=384%2C432\" alt=\"bondo1\" width=\"384\" height=\"432\" srcset=\"https:\/\/i0.wp.com\/bitquill.net\/blog\/wp-content\/uploads\/2015\/09\/bondo1.jpg?resize=910%2C1024 910w, https:\/\/i0.wp.com\/bitquill.net\/blog\/wp-content\/uploads\/2015\/09\/bondo1.jpg?resize=267%2C300 267w, https:\/\/i0.wp.com\/bitquill.net\/blog\/wp-content\/uploads\/2015\/09\/bondo1.jpg?w=1396 1396w\" sizes=\"auto, (max-width: 384px) 100vw, 384px\" \/><\/a>\u00c2\u00a0<a href=\"https:\/\/i0.wp.com\/bitquill.net\/blog\/wp-content\/uploads\/2015\/09\/bondo2.jpg\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" data-attachment-id=\"649\" data-permalink=\"http:\/\/bitquill.net\/blog\/esp8266-light-controller-clock\/bondo2\/\" data-orig-file=\"https:\/\/i0.wp.com\/bitquill.net\/blog\/wp-content\/uploads\/2015\/09\/bondo2.jpg?fit=1721%2C1936\" data-orig-size=\"1721,1936\" data-comments-opened=\"1\" data-image-meta=\"{&quot;aperture&quot;:&quot;2.4&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;iPad Air&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;1441542837&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;3.3&quot;,&quot;iso&quot;:&quot;50&quot;,&quot;shutter_speed&quot;:&quot;0.041666666666667&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;1&quot;}\" data-image-title=\"bondo2\" data-image-description=\"\" data-image-caption=\"\" data-large-file=\"https:\/\/i0.wp.com\/bitquill.net\/blog\/wp-content\/uploads\/2015\/09\/bondo2.jpg?fit=910%2C1024\" class=\"alignnone wp-image-649\" src=\"https:\/\/i0.wp.com\/bitquill.net\/blog\/wp-content\/uploads\/2015\/09\/bondo2.jpg?resize=384%2C432\" alt=\"bondo2\" width=\"384\" height=\"432\" srcset=\"https:\/\/i0.wp.com\/bitquill.net\/blog\/wp-content\/uploads\/2015\/09\/bondo2.jpg?resize=910%2C1024 910w, https:\/\/i0.wp.com\/bitquill.net\/blog\/wp-content\/uploads\/2015\/09\/bondo2.jpg?resize=267%2C300 267w, https:\/\/i0.wp.com\/bitquill.net\/blog\/wp-content\/uploads\/2015\/09\/bondo2.jpg?w=1721 1721w\" sizes=\"auto, (max-width: 384px) 100vw, 384px\" \/><\/a><\/p>\n<p>All things considered, XTC-3D works great (unfortunately, I forgot to take pictures after applying just the XTC-3D). It definitely beats sanding (substantially reducing it), as well as two-part body fillers (which I haven&#8217;t used with prints, but I&#8217;ve used in <a title=\"Custom-fabricated tweeter pods - bitquill\" href=\"http:\/\/bitquill.net\/blog\/adventures-in-fiberglassing-custom-fabricated-tweeter-pods\/\">another project<\/a>\u00c2\u00a0a long time ago). \u00c2\u00a0And for smaller surfaces or organic shapes, you&#8217;re pretty much done after applying.<\/p>\n<p><strong>Spray painting.<\/strong>\u00c2\u00a0I&#8217;m very new at this; I did it once in the past (again for\u00c2\u00a0<a title=\"Custom-fabricated tweeter pods - bitquill\" href=\"http:\/\/bitquill.net\/blog\/adventures-in-fiberglassing-custom-fabricated-tweeter-pods\/\">this project<\/a>) and, surprisingly, it had gone very smoothly. \u00c2\u00a0I still don&#8217;t know why (maybe too much false confidence?), but it&#8217;s always the <em>second<\/em> time that gets you burned, isn&#8217;t it? \u00c2\u00a0To cut the long story short, I learned about the difference between lacquers and enamels (simplifying, the first just dry by evaporation, the second cure by reacting with air), got distracted by paint chemistry (if you&#8217;re curious look, e.g., <a href=\"http:\/\/www.essentialchemicalindustry.org\/materials-and-applications\/paints.html\">here<\/a> or\u00c2\u00a0<a href=\"http:\/\/www.chemistryislife.com\/the\">here<\/a>, and if you&#8217;re <em>really<\/em> curious <a href=\"http:\/\/nzic.org.nz\/ChemProcesses\/polymers\/10D.pdf\">try this<\/a>), and found the following paint compatibility chart, which is worth it&#8217;s weight in gold:<\/p>\n<p><a href=\"https:\/\/i0.wp.com\/bitquill.net\/blog\/wp-content\/uploads\/2015\/09\/paint-compatibility.png\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" data-attachment-id=\"662\" data-permalink=\"http:\/\/bitquill.net\/blog\/esp8266-light-controller-clock\/paint-compatibility\/\" data-orig-file=\"https:\/\/i0.wp.com\/bitquill.net\/blog\/wp-content\/uploads\/2015\/09\/paint-compatibility.png?fit=305%2C480\" data-orig-size=\"305,480\" data-comments-opened=\"1\" data-image-meta=\"{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}\" data-image-title=\"paint-compatibility\" data-image-description=\"\" data-image-caption=\"\" data-large-file=\"https:\/\/i0.wp.com\/bitquill.net\/blog\/wp-content\/uploads\/2015\/09\/paint-compatibility.png?fit=305%2C480\" class=\"alignnone wp-image-662 size-full\" src=\"https:\/\/i0.wp.com\/bitquill.net\/blog\/wp-content\/uploads\/2015\/09\/paint-compatibility.png?resize=305%2C480\" alt=\"paint-compatibility\" width=\"305\" height=\"480\" srcset=\"https:\/\/i0.wp.com\/bitquill.net\/blog\/wp-content\/uploads\/2015\/09\/paint-compatibility.png?w=305 305w, https:\/\/i0.wp.com\/bitquill.net\/blog\/wp-content\/uploads\/2015\/09\/paint-compatibility.png?resize=191%2C300 191w\" sizes=\"auto, (max-width: 305px) 100vw, 305px\" \/><\/a><br \/>\n(original <a href=\"http:\/\/www.rcgroups.com\/forums\/showthread.php?t=1140128\">credit<\/a> and <a href=\"http:\/\/static.rcgroups.net\/forums\/attachments\/6\/3\/9\/3\/8\/a2868077-38-comp%20chart.JPG\">image<\/a>)<\/p>\n<p>Furthermore, in the past I had used Krylon, which is not available at big box stores\u00c2\u00a0(we have one two blocks from home)\u00c2\u00a0so I decided to try Rustoleum instead. \u00c2\u00a0Although people are often happier with Rustoleum (and, these days, they&#8217;re also cheaper), for the life of me I couldn&#8217;t get an even spray with their nozzles. Maybe they work well on large items like chairs and tables, or maybe it&#8217;s my (lack of) technique, but on this small enclosure I couldn&#8217;t get even coverage, and always got spots with too much paint (not enough to cause drips, but enough to affect the surface finish). More importantly, Rustoleum takes forever to dry and, if you&#8217;re doing your spraying in all sorts of weird places with temporary setups (we live in an apartment), that&#8217;s an issue.<\/p>\n<p>So, I wiped it all off (tip perhaps worth sharing: I found that, at least if the paint hasn&#8217;t completely cured, white spirit works well and it doesn&#8217;t attack the plastic at all), went to an auto parts store, and got some Krylon. \u00c2\u00a0I think their newer non-rotating nozzles spray a bit more like a firehose (just have to live with overspray), but other than that, the second attempt\u00c2\u00a0went pretty well.<\/p>\n<p>I chose a satin finish both because I like it, and also because it&#8217;s a bit more forgiving with improper spraying distance (you can err on keeping the nozzle too far from the surface, and it won&#8217;t have an ill effect, within reason). Skipping the intermediate steps (nothing to be proud of :), here is the end result &#8212; not bad for a rookie:<\/p>\n<p><a href=\"https:\/\/i0.wp.com\/bitquill.net\/blog\/wp-content\/uploads\/2015\/09\/paint3.jpg\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" data-attachment-id=\"650\" data-permalink=\"http:\/\/bitquill.net\/blog\/esp8266-light-controller-clock\/paint3\/\" data-orig-file=\"https:\/\/i0.wp.com\/bitquill.net\/blog\/wp-content\/uploads\/2015\/09\/paint3.jpg?fit=1721%2C1936\" data-orig-size=\"1721,1936\" data-comments-opened=\"1\" data-image-meta=\"{&quot;aperture&quot;:&quot;2.4&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;iPad Air&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;1441616936&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;3.3&quot;,&quot;iso&quot;:&quot;32&quot;,&quot;shutter_speed&quot;:&quot;0.041666666666667&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;1&quot;}\" data-image-title=\"paint3\" data-image-description=\"\" data-image-caption=\"\" data-large-file=\"https:\/\/i0.wp.com\/bitquill.net\/blog\/wp-content\/uploads\/2015\/09\/paint3.jpg?fit=910%2C1024\" class=\"alignnone wp-image-650\" src=\"https:\/\/i0.wp.com\/bitquill.net\/blog\/wp-content\/uploads\/2015\/09\/paint3.jpg?resize=384%2C432\" alt=\"paint3\" width=\"384\" height=\"432\" srcset=\"https:\/\/i0.wp.com\/bitquill.net\/blog\/wp-content\/uploads\/2015\/09\/paint3.jpg?resize=910%2C1024 910w, https:\/\/i0.wp.com\/bitquill.net\/blog\/wp-content\/uploads\/2015\/09\/paint3.jpg?resize=267%2C300 267w, https:\/\/i0.wp.com\/bitquill.net\/blog\/wp-content\/uploads\/2015\/09\/paint3.jpg?w=1721 1721w\" sizes=\"auto, (max-width: 384px) 100vw, 384px\" \/><\/a> <a href=\"https:\/\/i0.wp.com\/bitquill.net\/blog\/wp-content\/uploads\/2015\/09\/paint4.jpg\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" data-attachment-id=\"652\" data-permalink=\"http:\/\/bitquill.net\/blog\/esp8266-light-controller-clock\/paint2\/\" data-orig-file=\"https:\/\/i0.wp.com\/bitquill.net\/blog\/wp-content\/uploads\/2015\/09\/paint2.jpg?fit=1199%2C1349\" data-orig-size=\"1199,1349\" data-comments-opened=\"1\" data-image-meta=\"{&quot;aperture&quot;:&quot;2.4&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;iPad Air&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;1441616916&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;3.3&quot;,&quot;iso&quot;:&quot;32&quot;,&quot;shutter_speed&quot;:&quot;0.033333333333333&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;1&quot;}\" data-image-title=\"paint2\" data-image-description=\"\" data-image-caption=\"\" data-large-file=\"https:\/\/i0.wp.com\/bitquill.net\/blog\/wp-content\/uploads\/2015\/09\/paint2.jpg?fit=910%2C1024\" class=\"alignnone wp-image-652\" src=\"https:\/\/i0.wp.com\/bitquill.net\/blog\/wp-content\/uploads\/2015\/09\/paint2.jpg?resize=384%2C432\" alt=\"paint2\" width=\"384\" height=\"432\" srcset=\"https:\/\/i0.wp.com\/bitquill.net\/blog\/wp-content\/uploads\/2015\/09\/paint2.jpg?resize=910%2C1024 910w, https:\/\/i0.wp.com\/bitquill.net\/blog\/wp-content\/uploads\/2015\/09\/paint2.jpg?resize=267%2C300 267w, https:\/\/i0.wp.com\/bitquill.net\/blog\/wp-content\/uploads\/2015\/09\/paint2.jpg?w=1199 1199w\" sizes=\"auto, (max-width: 384px) 100vw, 384px\" \/><\/a><\/p>\n<p><a href=\"https:\/\/i0.wp.com\/bitquill.net\/blog\/wp-content\/uploads\/2015\/09\/paint4.jpg\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" data-attachment-id=\"653\" data-permalink=\"http:\/\/bitquill.net\/blog\/esp8266-light-controller-clock\/paint1\/\" data-orig-file=\"https:\/\/i0.wp.com\/bitquill.net\/blog\/wp-content\/uploads\/2015\/09\/paint1.jpg?fit=1544%2C1737\" data-orig-size=\"1544,1737\" data-comments-opened=\"1\" data-image-meta=\"{&quot;aperture&quot;:&quot;2.4&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;iPad Air&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;1441616909&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;3.3&quot;,&quot;iso&quot;:&quot;32&quot;,&quot;shutter_speed&quot;:&quot;0.041666666666667&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;1&quot;}\" data-image-title=\"paint1\" data-image-description=\"\" data-image-caption=\"\" data-large-file=\"https:\/\/i0.wp.com\/bitquill.net\/blog\/wp-content\/uploads\/2015\/09\/paint1.jpg?fit=910%2C1024\" class=\"alignnone wp-image-653\" src=\"https:\/\/i0.wp.com\/bitquill.net\/blog\/wp-content\/uploads\/2015\/09\/paint1.jpg?resize=384%2C432\" alt=\"paint1\" width=\"384\" height=\"432\" srcset=\"https:\/\/i0.wp.com\/bitquill.net\/blog\/wp-content\/uploads\/2015\/09\/paint1.jpg?resize=910%2C1024 910w, https:\/\/i0.wp.com\/bitquill.net\/blog\/wp-content\/uploads\/2015\/09\/paint1.jpg?resize=267%2C300 267w, https:\/\/i0.wp.com\/bitquill.net\/blog\/wp-content\/uploads\/2015\/09\/paint1.jpg?w=1544 1544w\" sizes=\"auto, (max-width: 384px) 100vw, 384px\" \/>\u00c2\u00a0<img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" data-attachment-id=\"651\" data-permalink=\"http:\/\/bitquill.net\/blog\/esp8266-light-controller-clock\/paint4\/\" data-orig-file=\"https:\/\/i0.wp.com\/bitquill.net\/blog\/wp-content\/uploads\/2015\/09\/paint4.jpg?fit=1605%2C1806\" data-orig-size=\"1605,1806\" data-comments-opened=\"1\" data-image-meta=\"{&quot;aperture&quot;:&quot;2.4&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;iPad Air&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;1441616924&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;3.3&quot;,&quot;iso&quot;:&quot;40&quot;,&quot;shutter_speed&quot;:&quot;0.041666666666667&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;1&quot;}\" data-image-title=\"paint4\" data-image-description=\"\" data-image-caption=\"\" data-large-file=\"https:\/\/i0.wp.com\/bitquill.net\/blog\/wp-content\/uploads\/2015\/09\/paint4.jpg?fit=910%2C1024\" class=\"alignnone wp-image-651\" src=\"https:\/\/i0.wp.com\/bitquill.net\/blog\/wp-content\/uploads\/2015\/09\/paint4.jpg?resize=384%2C432\" alt=\"paint4\" width=\"384\" height=\"432\" srcset=\"https:\/\/i0.wp.com\/bitquill.net\/blog\/wp-content\/uploads\/2015\/09\/paint4.jpg?resize=910%2C1024 910w, https:\/\/i0.wp.com\/bitquill.net\/blog\/wp-content\/uploads\/2015\/09\/paint4.jpg?resize=267%2C300 267w, https:\/\/i0.wp.com\/bitquill.net\/blog\/wp-content\/uploads\/2015\/09\/paint4.jpg?w=1605 1605w\" sizes=\"auto, (max-width: 384px) 100vw, 384px\" \/><\/a><\/p>\n<p><strong>Putting it together.<\/strong>\u00c2\u00a0The last bits were easy: soldering headers on the Thing (whatever fits in the enclosure, some straight and some raised right-angle pins) and on the display module. \u00c2\u00a0Also, the right-angle JST header soldered onto the Thing wouldn&#8217;t work in this enclosure (the LiPo wire collides with the endcap), so I desoldered it and replaced it with a vertical JST header. \u00c2\u00a0Finally, I had to solder a wire to the reset pads on the Digole module (the reset signal is not broken out, but it&#8217;s accessible through an unpopulated reset pushbutton).<\/p>\n<p><a href=\"https:\/\/i0.wp.com\/bitquill.net\/blog\/wp-content\/uploads\/2015\/09\/digole.jpg\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" data-attachment-id=\"654\" data-permalink=\"http:\/\/bitquill.net\/blog\/esp8266-light-controller-clock\/digole\/\" data-orig-file=\"https:\/\/i0.wp.com\/bitquill.net\/blog\/wp-content\/uploads\/2015\/09\/digole.jpg?fit=1890%2C1063\" data-orig-size=\"1890,1063\" data-comments-opened=\"1\" data-image-meta=\"{&quot;aperture&quot;:&quot;2.4&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;iPad Air&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;1441617000&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;3.3&quot;,&quot;iso&quot;:&quot;32&quot;,&quot;shutter_speed&quot;:&quot;0.041666666666667&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;1&quot;}\" data-image-title=\"digole\" data-image-description=\"\" data-image-caption=\"\" data-large-file=\"https:\/\/i0.wp.com\/bitquill.net\/blog\/wp-content\/uploads\/2015\/09\/digole.jpg?fit=1024%2C576\" class=\"alignnone wp-image-654\" src=\"https:\/\/i0.wp.com\/bitquill.net\/blog\/wp-content\/uploads\/2015\/09\/digole.jpg?resize=768%2C432\" alt=\"digole\" width=\"768\" height=\"432\" srcset=\"https:\/\/i0.wp.com\/bitquill.net\/blog\/wp-content\/uploads\/2015\/09\/digole.jpg?resize=1024%2C576 1024w, https:\/\/i0.wp.com\/bitquill.net\/blog\/wp-content\/uploads\/2015\/09\/digole.jpg?resize=300%2C169 300w, https:\/\/i0.wp.com\/bitquill.net\/blog\/wp-content\/uploads\/2015\/09\/digole.jpg?w=1890 1890w\" sizes=\"auto, (max-width: 768px) 100vw, 768px\" \/><\/a><\/p>\n<p>&nbsp;<\/p>\n<p>After fiddling with the screws (long nose pliers and balldrive Allen keys FTW!) and wires, the mechanical assembly was done &#8212; whewww!<\/p>\n<p><strong>Epic fail(s).<\/strong>\u00c2\u00a0So far I&#8217;ve omitted an epic fail from the story. \u00c2\u00a0The enclosure shown above is actually the second attempt. \u00c2\u00a0The first one ended up in disaster, all within a couple of hours. \u00c2\u00a0The first attempt was printed in PLA. \u00c2\u00a0First fail and lesson: PLA really does melt under the sun, and it takes less than you&#8217;d think. \u00c2\u00a0I sprayed the endcaps first and temporarily set them down on a cardboard on top of a metal\u00c2\u00a0outdoor\u00c2\u00a0table under the sun. \u00c2\u00a0In the few minutes it took me to spray the first coat on the main enclosure, the encaps had seriously warped! \u00c2\u00a0You can see this in the picture on the left (and that is after I spent half an hour re-shaping them with a temperature-controlled hot air gun at low heat!). \u00c2\u00a0The second fail was even worse: when I did the first attempt, I did not have an M2 tap, so I decided to use M2 screws\u00c2\u00a0(and oversize tap diameter). \u00c2\u00a0Unfortunately, this does not cut the threads properly, and the screws still meet substantial resistance. \u00c2\u00a0Since the nuts will never be\u00c2\u00a0<em>perfectly<\/em> aligned, when inserting the screws from the inside what happened was what you see on the left photo. Doh!<\/p>\n<p><a href=\"https:\/\/i0.wp.com\/bitquill.net\/blog\/wp-content\/uploads\/2015\/09\/fail2.jpg\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" data-attachment-id=\"656\" data-permalink=\"http:\/\/bitquill.net\/blog\/esp8266-light-controller-clock\/fail1\/\" data-orig-file=\"https:\/\/i0.wp.com\/bitquill.net\/blog\/wp-content\/uploads\/2015\/09\/fail1.jpg?fit=1493%2C1680\" data-orig-size=\"1493,1680\" data-comments-opened=\"1\" data-image-meta=\"{&quot;aperture&quot;:&quot;2.4&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;iPad Air&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;1441718954&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;3.3&quot;,&quot;iso&quot;:&quot;50&quot;,&quot;shutter_speed&quot;:&quot;0.041666666666667&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;1&quot;}\" data-image-title=\"fail1\" data-image-description=\"\" data-image-caption=\"\" data-large-file=\"https:\/\/i0.wp.com\/bitquill.net\/blog\/wp-content\/uploads\/2015\/09\/fail1.jpg?fit=910%2C1024\" class=\"alignnone wp-image-656\" src=\"https:\/\/i0.wp.com\/bitquill.net\/blog\/wp-content\/uploads\/2015\/09\/fail1.jpg?resize=384%2C432\" alt=\"fail1\" width=\"384\" height=\"432\" srcset=\"https:\/\/i0.wp.com\/bitquill.net\/blog\/wp-content\/uploads\/2015\/09\/fail1.jpg?resize=910%2C1024 910w, https:\/\/i0.wp.com\/bitquill.net\/blog\/wp-content\/uploads\/2015\/09\/fail1.jpg?resize=267%2C300 267w, https:\/\/i0.wp.com\/bitquill.net\/blog\/wp-content\/uploads\/2015\/09\/fail1.jpg?w=1493 1493w\" sizes=\"auto, (max-width: 384px) 100vw, 384px\" \/>\u00c2\u00a0<img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" data-attachment-id=\"655\" data-permalink=\"http:\/\/bitquill.net\/blog\/esp8266-light-controller-clock\/fail2\/\" data-orig-file=\"https:\/\/i0.wp.com\/bitquill.net\/blog\/wp-content\/uploads\/2015\/09\/fail2.jpg?fit=1721%2C1936\" data-orig-size=\"1721,1936\" data-comments-opened=\"1\" data-image-meta=\"{&quot;aperture&quot;:&quot;2.4&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;iPad Air&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;1441718971&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;3.3&quot;,&quot;iso&quot;:&quot;50&quot;,&quot;shutter_speed&quot;:&quot;0.041666666666667&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;1&quot;}\" data-image-title=\"fail2\" data-image-description=\"\" data-image-caption=\"\" data-large-file=\"https:\/\/i0.wp.com\/bitquill.net\/blog\/wp-content\/uploads\/2015\/09\/fail2.jpg?fit=910%2C1024\" class=\"alignnone wp-image-655\" src=\"https:\/\/i0.wp.com\/bitquill.net\/blog\/wp-content\/uploads\/2015\/09\/fail2.jpg?resize=384%2C432\" alt=\"fail2\" width=\"384\" height=\"432\" srcset=\"https:\/\/i0.wp.com\/bitquill.net\/blog\/wp-content\/uploads\/2015\/09\/fail2.jpg?resize=910%2C1024 910w, https:\/\/i0.wp.com\/bitquill.net\/blog\/wp-content\/uploads\/2015\/09\/fail2.jpg?resize=267%2C300 267w, https:\/\/i0.wp.com\/bitquill.net\/blog\/wp-content\/uploads\/2015\/09\/fail2.jpg?w=1721 1721w\" sizes=\"auto, (max-width: 384px) 100vw, 384px\" \/><\/a><\/p>\n<p>So, definitely use a tap to properly cut threads (or, make the holes <em>really<\/em> oversize, and make sure you clean any molten plastic if you use a soldering iron). Furthermore, measuring your fastener lengths twice and hand-tightening them is not a bad idea either.<\/p>\n<p>You may also notice that the finish here is a little glossier; that&#8217;s what happens when you over-apply paint and\/or spray from too close.<\/p>\n<p>Finally, to top it all off, I hadn&#8217;t realized that the standoffs for the RTC module where on the wrong side (double-doh!) and when test-fitting it also turned out that the wires I had crimped were a couple of cm too short. Oh well, it had been a while since I had an epic fail like this! :)<\/p>\n<p><strong>Protocol sniffing.<\/strong>\u00c2\u00a0On to the software part. \u00c2\u00a0First thing was to reverse-engineer the WiFi bulbs&#8217; protocol. \u00c2\u00a0It appears that, although there are several variants of the hardware that look identical, not all of them run the same protocol (e.g., see links in sniffing notes on GitHub). \u00c2\u00a0I&#8217;m not even sure all are made my the same OEM (FWIW, MAC vendor lookup on my bulbs says\u00c2\u00a0<a href=\"http:\/\/www.hi-flying.com\/\">Hi-flying Electronics<\/a>). Of course, none of these protocols are published, but all of them are very similar and quite simple. \u00c2\u00a0In my case, since I&#8217;m running OpenWRT on our router, I just installed <code>ngrep<\/code> and sniffed the iOS app&#8217;s traffic. \u00c2\u00a0<del>I&#8217;m pretty sure it&#8217;s possible to sniff traffic even if you don&#8217;t have access to the router (but I didn&#8217;t have to find out).<\/del> \u00c2\u00a0<strong>Edit:<\/strong> Root access on the router makes sniffing much easier (otherwise you&#8217;ll probably need a sniffer on your tablet\/phone).<\/p>\n<p>For on and off commands, I can just copy them verbatim. \u00c2\u00a0For commands to set color, the structure is easy to figure out. \u00c2\u00a0First is an opcode byte, followed by RGBW values (the bulbs have both RGB as well as warm-white LEDs, and it seems you can turn on either one or the other), a constant(?), and a checksum byte. Nothing too fancy.<\/p>\n<p>The iOS app uses UDP broadcast for bulb discovery (that protocol is also easy to figure out). \u00c2\u00a0This step does take some time (and was one of the annoyances with the user experience, since this information is not cached by the iOS app). \u00c2\u00a0However, after that, all communication happens over TCP. \u00c2\u00a0To keep things simple, I decided to skip the device discovery step (at least for now), and just assign fixed hostnames\/IPs to the bulbs.<\/p>\n<p><strong>Firmware.<\/strong>\u00c2\u00a0 The firmware is fairly standard stuff. It&#8217;s written using the <a title=\"esp8266\/Arduino - GitHub\" href=\"https:\/\/github.com\/esp8266\/Arduino\">ESP port of Arduino<\/a> (many thanks, <a title=\"igrr - GitHub\" href=\"https:\/\/github.com\/igrr\">@igrr<\/a> et al!), and it currently occupies about 70% of the Thing&#8217;s flash.<\/p>\n<p>First, the display driver and UI code. Touch handling uses a combination of interrupts to detect the first touch, and then polling and debouncing to detect finger down\/move\/up events, and update the UI accordingly (this is probably the most complex bit here, and it&#8217;s actually pretty simple). \u00c2\u00a0While at it, I did a <a title=\"spapadim\/Digole - GitHub\" href=\"https:\/\/github.com\/spapadim\/Digole\">gratuitous rewrite<\/a> of the Digole library, inspired by a <a title=\"PDQ_GFX optimzed AVR LCD graphics - Hackaday.io\" href=\"http:\/\/hackaday.io\/project\/6038\">very cool hack<\/a> I had seen. \u00c2\u00a0Then NTP client, WiFi bulb client, and a webserver for configuring the device over a web browser. \u00c2\u00a0Settings are stored in &#8220;EEPROM&#8221; (which, on the ESP, is just a sector of the flash memory). \u00c2\u00a0The web UI is pretty simple for now:<\/p>\n<p><a href=\"https:\/\/i0.wp.com\/bitquill.net\/blog\/wp-content\/uploads\/2015\/09\/web-screen.png\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" data-attachment-id=\"657\" data-permalink=\"http:\/\/bitquill.net\/blog\/esp8266-light-controller-clock\/web-screen\/\" data-orig-file=\"https:\/\/i0.wp.com\/bitquill.net\/blog\/wp-content\/uploads\/2015\/09\/web-screen.png?fit=800%2C733\" data-orig-size=\"800,733\" data-comments-opened=\"1\" data-image-meta=\"{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}\" data-image-title=\"web-screen\" data-image-description=\"\" data-image-caption=\"\" data-large-file=\"https:\/\/i0.wp.com\/bitquill.net\/blog\/wp-content\/uploads\/2015\/09\/web-screen.png?fit=800%2C733\" class=\"alignnone wp-image-657\" src=\"https:\/\/i0.wp.com\/bitquill.net\/blog\/wp-content\/uploads\/2015\/09\/web-screen.png?resize=768%2C704\" alt=\"web-screen\" width=\"768\" height=\"704\" srcset=\"https:\/\/i0.wp.com\/bitquill.net\/blog\/wp-content\/uploads\/2015\/09\/web-screen.png?w=800 800w, https:\/\/i0.wp.com\/bitquill.net\/blog\/wp-content\/uploads\/2015\/09\/web-screen.png?resize=300%2C275 300w\" sizes=\"auto, (max-width: 768px) 100vw, 768px\" \/><\/a><\/p>\n<p>Arduino on ESP has <a href=\"https:\/\/github.com\/esp8266\/Arduino\/tree\/esp8266\/hardware\/esp8266com\/esp8266\/libraries\">a great set of libraries<\/a> for networking stuff, which makes all this quite easy! I&#8217;m using basic Bootstrap and Knockout.js to make it look a little pretty. I decided to write a proper HTML5 frontend and a simple REST API (using the excellent <a title=\"bblanchon\/ArduinoJson - GitHub\" href=\"https:\/\/github.com\/bblanchon\/ArduinoJson\">ArduinoJson library<\/a>).\u00c2\u00a0However, upon first boot, the device has no Internet access. \u00c2\u00a0If it fails to connect to WiFi, the firmware will switch the device to AP mode, so initial configuration can be done over WiFi. \u00c2\u00a0Since the flash chip is not large enough to store Bootstrap and Knockout locally, there is a separate, minimal UI (not shown) that uses regular HTML forms (no AJAX) and just allows setting the SSID and password.<\/p>\n<p>One problem\u00c2\u00a0(that I eventually worked around, rather than solved) was getting the Digole module to talk back to the ESP. \u00c2\u00a0I2C was a fail (and it wasted me a couple of days; still not sure if the problem is on the display&#8217;s end or with the Arduino&#8217;s clock stretching implementation, or something else) and SPI I didn&#8217;t really try. I finally got UART to work (except that you <a href=\"http:\/\/www.esp8266.com\/viewtopic.php?f=24&amp;t=2822\">can&#8217;t turn off<\/a> the ESP&#8217;s 78Kbaud boot messages, hence the need for accessing the reset signal on the Digole). \u00c2\u00a0The downside is that now reflashing the firmware is a PITA (I have to fiddle inside the case, to disconnect the display and connect my FTDI), but that happens relatively infrequently (the display stuff is mostly done, and the network stuff I test on a spare Thing first).<\/p>\n<p><strong>Conclusion.<\/strong>\u00c2\u00a0After all this, I think the result is\u00c2\u00a0not bad for a completely home-made device. Could I have gotten a used Chumby for a comparable price (they go for about <a title=\"The Chumby Store\" href=\"http:\/\/www.thechumbystore.com\/\">$60 used<\/a>), or just used an old\/cheap Android tablet (and perhaps just 3D print a stand)? \u00c2\u00a0Aside from the Chumby service&#8217;s <a title=\"Chumby - History - Wikipedia\" href=\"https:\/\/en.wikipedia.org\/wiki\/Chumby#History\">ups and downs<\/a>&#8230; sure, but where&#8217;s the fun in that? :) \u00c2\u00a0Also, there is no way to reduce the cost of these alternatives down to $13.<\/p>\n<p>What&#8217;s next? Well, you may have noticed there is a zipcode setting. That&#8217;s for weather information (planning to use OpenWeatherMaps, which returns reasonably-sized responses &#8212; parsing anything more than 1KB, <em>maybe<\/em> 2KB, is probably a bit iffy). \u00c2\u00a0Also, a web UI to control the lamps would be nice (the REST API endpoints are there, just need to get around to writing and refactoring the HTML bits). \u00c2\u00a0Maybe adapt the whole thing to a\u00c2\u00a0cheaper display module (as discussed in the beginning; I&#8217;ve already started a port of the\u00c2\u00a0ucglib library to the ESP, but need an actual device to finish it). Finally,\u00c2\u00a0one could perhaps\u00c2\u00a0re-write it in Lua (<a title=\"nodemcu\/nodemcu-firmware - GitHub\" href=\"https:\/\/github.com\/nodemcu\/nodemcu-firmware\">NodeMCU<\/a>?) with support for pluggable modules (a-la true Chumby). That probably won&#8217;t be me, though; by that time, I&#8217;m pretty sure a new hack will have &#8220;distracted&#8221; me. :)<\/p>\n","protected":false},"excerpt":{"rendered":"<p>A couple of months ago I picked up cheap\u00c2\u00a0WiFi-controlled LED bulbs (one\u00c2\u00a0among\u00c2\u00a0dozens\u00c2\u00a0of very similar devices), after seeing them at a friend&#8217;s place. \u00c2\u00a0This turned out to be an excuse to play with the\u00c2\u00a0ESP8266, which has inspired several hacks. I was overall very happy with these bulbs: decent Android and iOS apps and, compared to fancier [&hellip;]<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_monsterinsights_skip_tracking":false,"_monsterinsights_sitenote_active":false,"_monsterinsights_sitenote_note":"","_monsterinsights_sitenote_category":0,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_publicize_message":"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":false,"jetpack_social_options":{"image_generator_settings":{"template":"highway","default_image_id":0,"font":"","enabled":false},"version":2},"jetpack_post_was_ever_published":false},"categories":[67,45],"tags":[69,85,83,84,68,82],"class_list":["post-624","post","type-post","status-publish","format-standard","hentry","category-make","category-scitech","tag-3d-print","tag-arduino","tag-embedded","tag-esp8266","tag-hacks","tag-make"],"jetpack_publicize_connections":[],"jetpack_featured_media_url":"","jetpack_shortlink":"https:\/\/wp.me\/p7x9xm-a4","jetpack-related-posts":[],"jetpack_sharing_enabled":true,"_links":{"self":[{"href":"http:\/\/bitquill.net\/blog\/wp-json\/wp\/v2\/posts\/624","targetHints":{"allow":["GET"]}}],"collection":[{"href":"http:\/\/bitquill.net\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/bitquill.net\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/bitquill.net\/blog\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"http:\/\/bitquill.net\/blog\/wp-json\/wp\/v2\/comments?post=624"}],"version-history":[{"count":37,"href":"http:\/\/bitquill.net\/blog\/wp-json\/wp\/v2\/posts\/624\/revisions"}],"predecessor-version":[{"id":676,"href":"http:\/\/bitquill.net\/blog\/wp-json\/wp\/v2\/posts\/624\/revisions\/676"}],"wp:attachment":[{"href":"http:\/\/bitquill.net\/blog\/wp-json\/wp\/v2\/media?parent=624"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/bitquill.net\/blog\/wp-json\/wp\/v2\/categories?post=624"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/bitquill.net\/blog\/wp-json\/wp\/v2\/tags?post=624"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}