<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:cc="http://cyber.law.harvard.edu/rss/creativeCommonsRssModule.html">
    <channel>
        <title><![CDATA[Stories by Charlie Hoey on Medium]]></title>
        <description><![CDATA[Stories by Charlie Hoey on Medium]]></description>
        <link>https://medium.com/@flimshaw?source=rss-fb59f8f96e13------2</link>
        <image>
            <url>https://cdn-images-1.medium.com/fit/c/150/150/0*W1RVQfksEjf49N5c.png</url>
            <title>Stories by Charlie Hoey on Medium</title>
            <link>https://medium.com/@flimshaw?source=rss-fb59f8f96e13------2</link>
        </image>
        <generator>Medium</generator>
        <lastBuildDate>Sun, 15 Nov 2026 08:21:02 GMT</lastBuildDate>
        <atom:link href="https://medium.com/@flimshaw/feed" rel="self" type="application/rss+xml"/>
        <webMaster><![CDATA[yourfriends@medium.com]]></webMaster>
        <atom:link href="http://medium.superfeedr.com/" rel="hub"/>
        <item>
            <title><![CDATA[A Eulogy for the Headphone Jack]]></title>
            <link>https://medium.com/@flimshaw/a-eulogy-for-the-headphone-jack-aabda6c66cd8?source=rss-fb59f8f96e13------2</link>
            <guid isPermaLink="false">https://medium.com/p/aabda6c66cd8</guid>
            <category><![CDATA[headphones]]></category>
            <category><![CDATA[android]]></category>
            <category><![CDATA[data]]></category>
            <category><![CDATA[privacy]]></category>
            <category><![CDATA[apple]]></category>
            <dc:creator><![CDATA[Charlie Hoey]]></dc:creator>
            <pubDate>Sat, 20 Jan 2018 20:57:38 GMT</pubDate>
            <atom:updated>2018-03-12T11:04:24.446Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*dZT_Tw7dHidqWUCAFLqePg.jpeg" /></figure><p>Sometime in the mid-2000s, I was a freelance web developer in Philadelphia with some pretty crappy health insurance. I started having occasional heart palpitations, like skipped heart beats. My doctor said it was probably not serious, but she could do tests to rule out very unlikely potential complications for about $1,000. That seemed pretty expensive to rent a portable EKG for a single day, so I googled around for some schematics. Turned out you could build a basic three-lead EKG with about $5 worth of Radio Shack parts (I no longer have the exact schematic, but something <a href="https://4.bp.blogspot.com/-fFXip61E6lE/UKLj4huTUgI/AAAAAAAAAFs/1QhNdUMpp9s/s1600/Cathy+EKG+Schematic+Prototype+3.jpg">like this</a>). I didn’t really understand what the circuit did, but I followed the directions and soldered it together on some protoboard, connected a 9V battery, and used three pennies as electrodes that I taped to my chest. I hooked the output of the device to my laptop’s <em>line in </em>and pressed ‘record’.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*P5QuZYM_oFx6eEn1wAXlvw.png" /><figcaption>screenshot of my heartbeat in Audacity</figcaption></figure><p>Audacity displayed the heartbeat signal live as it recorded. Sure enough, I was having pretty common/harmless Premature Ventricular Contractions. There’s one on the right side of the screenshot above.</p><p>Calling the 1/8th inch connectors you’d find on pretty much every piece of consumer electronics until recently “audio jacks” does them a disservice. It’s like calling your car a “grocery machine”. Headphone and microphone ports are, at their most basic, tools for reading and producing voltages precisely and rapidly over time.</p><p>My homemade EKG is a voltage converter. Electrodes attached to points around my heart measure tiny differences in voltage produced by signals that keep it beating. Those measured signals are amplified to about plus or minus 2 volts. That new voltage travels through an audio cable to the “Line In” on my sound card.</p><p>Sound cards <em>happen</em> to carry sound most of the time, but they are perfectly happy measuring <em>any </em>AC voltage from -2 to +2 volts at 48,000 times per second with 16 bits of accuracy. Put another way, your microphone jack measures the voltage on a wire (two wires for stereo) every 0.02 milliseconds, and records it as a value between 0 and 65,535. Your headphone jack does the opposite, by <em>applying</em> a voltage between -2 and +2 to a wire every 0.02 milliseconds, it creates a sound.</p><p>To any headphone jack, all audio is raw in the sense that it exists as a series of voltages that ultimately began as measurements by some tool, like a microphone or an electric guitar pickup or an EKG. There is no encryption or rights management, no special encoding or secret keys. It’s just data in the shape of the sound itself, as a record of voltages over time. When you play back a sound file, you feed that record of voltages to your headphone jack. It applies those voltages to, say, the coil in your speaker, which then pushes or pulls against a permanent magnet to move the air in the same way it originally moved the microphone whenever the sound was recorded.</p><p>Smartphone manufacturers <a href="https://www.theverge.com/2018/1/18/16903516/headphones-wireless-analog-jack-future-ces-2018">are broadly eliminating headphone jacks</a> going forward, replacing them with wireless headphones or BlueTooth. We’re going to all lose touch with something, and to me it feels like something important.</p><p>The series of voltages a headphone jack creates is immediately understandable and usable with the most basic tools. If you coil up some copper, and put a magnet in the middle, and then hook each side of the coil up to your phone’s headphone jack, <em>it would make sounds</em>. They would not be pleasant or loud, but they would be tangible and human-scale and understandable. It’s a part of your phone that can read and produce electrical vibrations.</p><p>Without that port, we will forever be beholden to <em>device drivers</em> between our sounds and our speakers. We’ll lose reliable access to an analog voltage we could use to drive any magnetic coil on earth, any pair of headphones. Instead, we’ll have to pay a toll, either through dongles or wireless headphones. It will be the end of a common interface for sound transfer that survived more or less unchanged for a century, the end of plugging your iPod into any stereo bought since WWII.</p><p>Entrepreneurs and engineers will lose access to a nearly universal, license-free I/O port. Independent headphone manufacturers will be forced into a dongle-bound second-class citizenry. Companies like Square — which made brilliant use of the headphone/microphone jack to produce credit card readers that are cheap enough to just <a href="https://squareup.com/shop/hardware/us/en/products/free-credit-card-reader">give away for free</a> — will be hit with extra licensing fees.</p><p>Because a voltage is just a voltage. Beyond an input range, nobody can define what you do with it. In the case of the Square magstripe reader, it is powered by the energy generally used to drive speakers (harvesting the energy of a sine wave being played over the headphones), and it transmits data to the microphone input.</p><p>There’s also the <a href="https://web.eecs.umich.edu/~prabal/projects/hijack/">HiJack project</a>, which makes this whole repurposing process open source and general purpose. They provide circuits that cost less than $3 to build that can harvest 7mW of power from a sound playing out of an iPhone’s headphone jack. Because you have raw access to some hardware that reads and writes voltages, you can layer an API on top of it to do anything you want, and it’s not licensable or limited by outside interests, just some reasonably basic analog electronics.</p><p>I don’t know exactly <em>how</em> losing direct access to our signals will harm us, but doesn’t it feel like it’s going to somehow? Like we may get so far removed from how our devices work, by licenses and DRM, dongles and adapters that we no longer even <em>want</em> to understand them? There’s <em>beauty</em> in the transformation of sound waves to electricity through a microphone, and then from electricity back to sound again through a speaker coil. It is pleasant to understand. Compare that to understanding, say, the latest BlueTooth API. One’s an arbitrary and fleeting manmade abstraction<em>, </em>the other a mysterious and dazzlingly convenient property of the natural world.</p><p>So, if you’re like me and you like headphone jacks, what can you do? Well, you could only buy phones that have them, which I think you’ll be able to do for a couple years. Vote with your dollar!</p><p>You can also tell companies that are getting rid of headphone jacks that you don’t like it. That your mother did not raise a fool. That aside from <em>maybe</em> water-resistance, there’s not a single good reason you can think of to give up your headphone jack. Tell them you see what they’re up to, and you <em>don’t like it</em>. You can say this part slightly deeper, through gritted teeth, if you get to say it aloud. Or, just italicize it so they know you are <em>serious</em>.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=aabda6c66cd8" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Project Valiant]]></title>
            <link>https://medium.com/@flimshaw/project-valiant-7978ddf9bee?source=rss-fb59f8f96e13------2</link>
            <guid isPermaLink="false">https://medium.com/p/7978ddf9bee</guid>
            <category><![CDATA[virtual-reality]]></category>
            <category><![CDATA[storytelling]]></category>
            <category><![CDATA[vr]]></category>
            <category><![CDATA[gopro]]></category>
            <category><![CDATA[360-video]]></category>
            <dc:creator><![CDATA[Charlie Hoey]]></dc:creator>
            <pubDate>Sun, 18 Jun 2017 23:29:16 GMT</pubDate>
            <atom:updated>2025-09-10T11:43:38.757Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*OI7llZNJ2Ldt9NdaGKS-yw.png" /></figure><h4>Creating a 360° video from San Francisco to (not quite) Boston</h4><p>In the early 21st century, I took a road trip with about 11 friends from Philadelphia to San Francisco and back. My friend Tadge brought along a 4x5 camera, and a lens called a Apo-Lanthar 300mm f/9, which was radioactive enough to set off geiger counters. I asked him, “What do you take pictures of with a radioactive lens?” He replied: “<a href="http://tadge.net/america/">America.</a>”</p><p>A decade later in 2010, I was ready for another cross country jaunt. I was living in San Francisco with a 1964 Plymouth Valiant convertible, a car I’d always wanted, but that didn’t exist outside of junk yards in the salty rusty Northeast.</p><p>It was a magical car. It predated the moon landing. It had an ashtray for <em>every</em> <em>passenger</em>. It had an AM radio, incidentally the most electrically complex thing in the car. Everything else was mechanical, with a “can’t kill ‘em” Slant-6 engine. When I pressed down on the gas pedal, it pushed a lever that opened a little flap on the carburetor, which allowed air to gasp in, huffing atomized jets of gasoline with it down to the pistons, where a series of valves would close, and a spark would trigger an explosion in perfect time. No transistors or sensors or limiters anywhere along the way, just iron and fire and simple machines. The slant-6 is a clock that runs on explosions.</p><p>I’d driven it to Big Sur a half dozen times, whenever someone came to visit for more than a couple of days. In the Valiant, you got a totally unobstructed view. No roll bars or head rests or shoulder belts or other gizmos to get in your way. I wished I could take a picture that captured the feeling.</p><p>I tried a few things. First, I <a href="https://www.youtube.com/watch?v=PCELxXPV2Qo">stuck a GoPro on the bumper</a>, but it was too low to the ground, and kind of Mad Max-y. Then I tried suction-cupping my Canon 7D to the windshield with a fisheye lens. That was better, but even that didn’t give you a full sense of place. There were things to look at in all directions, no matter where I pointed it, you were missing something.</p><p>I did some googling and found a Canadian kid who’d taken <a href="http://www.edmontonjournal.com/degree+Video+World+record+dodgeball+game+Edmonton+Updated/4227720/story.html">360 video of the world’s largest dodgeball game</a>. I looked over <a href="http://punkoryan.com/2011/02/08/shooting-360-degree-video-with-four-gopro-hd-hero-cameras">his technical writeup</a> and started doing some research of my own. Turned out, the best way to do it was to sync up 5 cameras (with a clap, just like the old days), dump individual frames from each one (30 frames per second * 5, 150 images per second. Yeesh.) and then stitch them all together one by one with <a href="http://panotools.sourceforge.net/">Panotools</a>. Arduous work, but technically doable. There really wasn’t any info about 360 video at this time, only a handful of people were making it, and they were doing so by applying techniques from still photo stitching frame by frame to video.</p><p>So I set to work as I often do: I begged some free welding work from <a href="http://maurerwelding.com/">my friend Jule</a> and also borrowed two GoPro’s from him and my dad, and purchased an extra two myself. He overnighted me a square piece of aluminum with a tripod-compatible bolt on the bottom that I would use to mount all 5 GoPros. I also ordered 5 old-school iPod connectors, which GoPro used for their extension port, and soldered up the power connectors so I could power all the cameras externally while driving. These ran down to a small 5v power supply driven by a 7805 voltage regulator circuit I soldered together on some perfboard. It got piping hot, but it was outside the car on the windshield and so the rushing, free air of America’s highways kept it cool. I did burn myself on it a few times though.</p><p>Each camera had a 32GB SD card, which meant I could record about 4 hours of video at a time before all 5 were full. I bought 12 of them and when we stopped for gas I would rotate all 5 out with fresh cards, and Kat would copy and clear each of the old ones to an external hard drive on my laptop. By my calculations, the entire drive was going to take somewhere north of 400GB to store, and the hard drive I carried would write billions of 1’s and 0’s to a magnetically sensitive disk as we drove.</p><p>The first day was the longest drive I’d ever done in the car to date: 13 hours straight from San Francisco to Salt Lake City, through the mountains on the Nevada border and past the salt flats where they set land speed records. And the whole setup worked. We arrived dusty and exhausted and crashed hard that night, but the next morning I went through the hard drive and scanned through the footage and it had all worked!</p><p>That was the first and only successful day of the trip, video-wise. As we continued across the high plains of Wyoming and South Dakota, one or more of the cameras conked out during a leg, taking all the footage it had recorded with it. Deep scans and SD card recovery tools were no use, and a 360 degree video with a big gap on one side didn’t really work. I tried to narrow down which cards or cameras were bad, but it seemed to move around unconfined to any particular piece of hardware, and we eventually gave up trying once we hit heavy rain in South Dakota after an underwhelming trip to Mount Rushmore.</p><p>When I got home to Boston, I never quite figured out what to do with this huge pile of footage, still filling up a big chunk of a few hard drives on the shelf. I cobbled together a WebGL video player for 360° videos called <a href="http://flimshaw.github.io/Valiant360/">Valiant360</a> and published a 30 minute section of the road trip that did work, as we departed my garage and left San Francisco heading due east before the sun came up. It’s a project I felt a little guilty never saw the light of day in a big way, but also I never really figured out how to stitch such a huge pile of imperfect video with sections of video missing at random.</p><p>Now it’s easier to make 360 video, with lots of precision 3D printable brackets on Thingiverse, and a handful of commercial solutions. Someday, perhaps, someone may succeed in capturing the whole country end to end and all the way around. But in the end, you should probably just drive it yourself. The world’s smaller than you think, except for Nebraska.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=7978ddf9bee" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[A WebVR Workflow for A-Frame, from GearVR to Vive]]></title>
            <link>https://medium.com/@flimshaw/a-webvr-workflow-for-a-frame-from-gearvr-to-vive-2c47ae823810?source=rss-fb59f8f96e13------2</link>
            <guid isPermaLink="false">https://medium.com/p/2c47ae823810</guid>
            <category><![CDATA[virtual-reality]]></category>
            <category><![CDATA[webvr]]></category>
            <category><![CDATA[webgl]]></category>
            <category><![CDATA[html]]></category>
            <category><![CDATA[a-frame]]></category>
            <dc:creator><![CDATA[Charlie Hoey]]></dc:creator>
            <pubDate>Mon, 20 Mar 2017 14:32:52 GMT</pubDate>
            <atom:updated>2017-03-21T00:06:24.659Z</atom:updated>
            <content:encoded><![CDATA[<p>I’ve been working with <a href="https://aframe.io/">A-Frame</a> a lot recently, and I really can’t say enough about it. Imagine a clean and thoughtful javascript Entity-Component-System pattern with Three.js as its engine. Now imagine that it also pretty much automatically will run on any VR device on the planet from GearVR to to the mighty Vive. Now pinch yourself, because no, you’re not dreaming. You can have it today, and it’s <em>free</em>. Here’s some very brief notes about how I’ve been working with it on the Vive and GearVR.</p><p><strong>A-Frame ASAP<br></strong>Leaf through the <a href="https://aframe.io/docs/0.5.0/introduction/getting-started.html">thorough and readable documentation</a> on getting started in A-Frame. Then go to this <a href="https://codepen.io/mozvr/pen/BjygdO">Hello World</a> code example and note that there is no javascript code in it. You don’t need to know javascript to build a basic static scene, everything happens in markup by defining basic shapes with HTML-like tags. To make a pink cube that’s 2 meters on all sides, for example:</p><pre>&lt;a-box scale=&quot;2 2 2&quot; material=&quot;color: pink&quot;&gt;&lt;/a-box&gt;</pre><p>If the above line elicits an immediate distrust of libraries that <a href="https://www.youtube.com/watch?v=Gzj723LkRJY">make big promises about productivity and code brevity, but then crumble under the slightest variation in their creator’s original design in the real world</a>, don’t worry, I don’t think that A-Frame is one of them. Custom components are cheap and easy to construct, and give you access to a more or less vanilla ThreeJS scene you may already be familiar with. The composition over inheritance style ECS pattern will be familiar as well if you’ve worked with Unity or Unreal Engine 4. Nothing under the hood is hard to get at, and there isn’t a lot of overhead.</p><p><strong>On the Vive or Oculus<br></strong>If you’ve been developing on the Vive as I have, you’re almost certainly on a Windows machine, and so you’ll need a WebVR capable browser. These are not mainstream yet, but there are good, stable options out there. Your choices are Google’s <a href="https://www.chromium.org/Home">Chromium</a> or Mozilla’s Firefox <a href="https://www.mozilla.org/en-US/firefox/channel/desktop/">Nightly</a>. At this moment (March 2017), <em>definitely</em> go with Firefox Nightly, it has no noticeable latency penalty on the Vive for me. Chromium, on the other hand, definitely lags by several frames per second, which is way, <em>way</em> too many if you want to hold onto your breakfast.</p><p>Once you’re running in Nightly, <a href="https://aframe.io/examples/">go to any of the examples</a> and click the VR goggles icon in the bottom right, and it should launch to your headset (be sure SteamVR is running before you launch the browser if you’re having trouble). If it’s working and you have motion controllers, you must <em>immediately</em> try <a href="https://aframe.io/a-painter/">A-Painter</a>, which is Mozilla’s in-browser Tilt Brush clone. It’s a more or less exact functional clone, and is polished and impressive. <a href="https://github.com/aframevr/a-painter">The source code is of course available</a>, and is also a joy to read and fork as boilerplate for your own experiments.</p><p><strong>Developing on the GearVR<br></strong>While these demos will launch in Chrome on a mobile device today, the performance isn’t good enough to use. Oculus, however, has an optimized WebVR browser called Carmel that is already a viable option even in its current experimental state.</p><p>Install Carmel through the Oculus app on your phone. Then, any links that take the format “ovrweb:http://link.com/demo” will prompt the user to insert the phone into their GearVR, and then will load your scene into a low-latency WebVR instance. It’s honestly pretty seamless, and once users have the browser installed, you can link from your website to playable VR applications that run well and require no app installs. The metaverse is near!</p><p><strong>Dreamy Debugging on the GearVR<br></strong>The Carmel browser supports remote debugging with Chrome Dev Tools, which is <em>amazing</em>. You need to setup <a href="https://developers.google.com/web/tools/chrome-devtools/remote-debugging/">remote debugging over USB</a>, and then <a href="https://developer.android.com/studio/command-line/adb.html">setup wifi debugging with adb</a> because of some unknown issue when looping through the GearVR usb port to the computer. Then, you can be running a WebVR instance on your GearVR, and on your laptop have a live javascript console with breakpoints, live DOM access, and all your standard profiling tools at your disposal. If you use webpack-dev-server, the GearVR will even automatically refresh when changes are made. Because it’s javascript, you’ve got access to NPM and glslify and all your favorite tools. You can get a lot done pretty quickly.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=2c47ae823810" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[How to make a truly random password]]></title>
            <link>https://medium.com/@flimshaw/how-to-make-an-actually-random-password-5c0da8fc1f21?source=rss-fb59f8f96e13------2</link>
            <guid isPermaLink="false">https://medium.com/p/5c0da8fc1f21</guid>
            <category><![CDATA[passwords]]></category>
            <category><![CDATA[math]]></category>
            <category><![CDATA[entropy]]></category>
            <category><![CDATA[security]]></category>
            <dc:creator><![CDATA[Charlie Hoey]]></dc:creator>
            <pubDate>Thu, 23 Feb 2017 17:37:58 GMT</pubDate>
            <atom:updated>2017-02-23T17:43:44.036Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*7-SfeRh9FTnRdDzdGrtd6g.png" /></figure><p>Password managers like KeePass, 1Password, etc are all great and largely interchangeable, you should definitely use one and let it generate a different password for every site you visit. But know that it is only as secure as the master password you use to access it. You should be sure it is <em>quantifiably</em> random and unguessable, not just that it feels random or has a few numbers or exclamation marks in it. If we want true randomness, we’re going to need some custom hardware.</p><p>Luckily, you can buy inexpensive devices at any corner store that can generate about 3 bits of entropy at a time, without electricity, and which are reliable enough that hundreds of millions of dollars change hands every day based on the infallibility of their randomness.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*So4PbUaFhvEvdXy8ztHvuw.jpeg" /></figure><p>Rolling a die produces a random number between 1 and 6, which you can represent with 2.58 bits. There’s no partial bits in reality, so we always round up to the nearest bit. In this case, we need 3 bits to store a number up to 6, and in fact we can store 0 and 7 too:</p><pre>000 - 0<br>001 - 1<br>010 - 2<br>011 - 3<br>100 - 4<br>101 - 5<br>110 - 6<br>111 - 7</pre><p>The number of combinations of 1’s and 0’s available determines how large a number you can store for a given number of bits. Every time you add another bit, you double the number of combinations you had before. This is easy enough to follow: if you throw another bit on a binary number, you now have all the combinations you had before with a 0 to the left of them, and again with a 1. For <em>n</em> bits, you can store 2^n values. So 2 bits can hold 4 values, and 8 bits can hold 255 values. This is why you could only have 255 rupees in Zelda: they only used an 8-bit variable.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/176/1*oftUhsWuc1gBCnsoQQul3Q.png" /></figure><p>I wanted at least 128 bits for my password. By most accounts, cracking 128 bit encryption <a href="https://stackoverflow.com/questions/4376751/is-it-possible-to-break-a-128-bit-key">is pretty much impossible through brute force methods</a> in fewer than several billion years. Using our 2^n equation, we can store up to 3.4*10³⁸ different values using 128 bits. If you could test 100 billion values per second, it would still take tens of trillions of years to guess the correct one. So, I’m calling that good enough! A solid 128 bit password will almost certainly not be the weak link in your online security.</p><p>If each of our dice produces 2.58 bits of entropy per roll, then rolling 5 of them makes 12.9 bits. If we roll 5 of them 10 times, then we’ve created 129 bits of entropy. <em>Yahtzee!</em> But how do we turn that into a secure but memorable password?</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*5xHLTjpixBVY-Sey-yuksQ.jpeg" /></figure><p>I used <a href="http://world.std.com/~reinhold/diceware.html">Diceware</a>, which is a dictionary of words indexed by the 5-dice rolls. Each time you roll 5 dice (or 1 die 5 times), the numbers that come up correspond to a word in the list. For example, if 5 dice came up 1-4-2-6-3, you’d turn to the page with all the 14xxx words and find that 14263 is “blab”. Do this ten times, and you will get a string of ten words. Those ten words — including spaces! — are your password. Use a mnemonic device like a <a href="https://en.wikipedia.org/wiki/Mnemonic_link_system">linked list</a> to memorize the ten words by making a story that links each word to the next. It feels kinda silly to do it, but it works, and you’ll be surprised how quickly you can memorize things this way.</p><p>If this all seems overkill, remember that this is the password behind which your entire financial and online life resides. It’s worth going overboard for this one thing. Just make an afternoon of it! Go down to the comic shop and buy some dice. Print out the diceware list at work or the library. Once you’re home, make your favorite warm beverage and go into a room where there are no cameras or phones or computers. Roll some dice and write the words you get down on a piece of paper (I rolled for 15 words so I could eliminate a few if I didn’t know them). Then pick ten words and <a href="https://en.wikipedia.org/wiki/Mnemonic_link_system">memorize</a> them. That’s your password. Keep your notes locked away for a few days until you’re sure you have the password memorized. This is what you use to log into your password manager</p><p>Congratulations! You now have a password you know is <em>truly and provably </em>random, that was not monitored or generated for you by a third party, and which exists securely in your mind alone. You can use it for a few years and it’s the only one you need to know. Even if someone knows you used 10 words, and knows what list you used, they still would have to brute force their way through 129 grueling bits of entropy, and if they are capable of doing that, there are almost certainly juicier targets than you.</p><p>Take off your tinfoil hat and go about your life. It’s okay to put it on once in a while.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=5c0da8fc1f21" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Torrenting the galaxy]]></title>
            <link>https://medium.com/@flimshaw/torrenting-the-galaxy-extracting-2-million-3d-stars-from-180gb-of-csvs-457ff70c0f93?source=rss-fb59f8f96e13------2</link>
            <guid isPermaLink="false">https://medium.com/p/457ff70c0f93</guid>
            <category><![CDATA[stars]]></category>
            <category><![CDATA[javascript]]></category>
            <category><![CDATA[programming]]></category>
            <category><![CDATA[space]]></category>
            <category><![CDATA[astronomy]]></category>
            <dc:creator><![CDATA[Charlie Hoey]]></dc:creator>
            <pubDate>Tue, 20 Sep 2016 22:24:53 GMT</pubDate>
            <atom:updated>2016-10-31T14:32:47.479Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*Ic3FUnc3KqabADqiFoxXsA.jpeg" /></figure><p>This is the story of how a bunch of 1’s and 0’s on a satellite got into a <a href="http://charliehoey.com/threejs-demos/gaia_dr1.html">3D simulation of our Milky Way</a> I constructed that shows the positions of over <strong>two million stars</strong> around our sun.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*Pg_IvVwWfhf2WiZwPVdLlg.jpeg" /><figcaption>Image source: <a href="http://sci.esa.int/gaia/55638-artist-impression-of-gaia/">ESA/ATG medialab</a></figcaption></figure><h3>Gaia</h3><p>The European Space Agency’s Gaia satellite is currently twirling about 1.2 million kilometers beyond the moon. As it spins, it dutifully <a href="https://www.youtube.com/watch?v=bbfb8VhH7L0">records the position of every point of light it sees</a>. On September 14th, 2016, the first of many scheduled public releases of that data occurred, in the form of a <a href="https://www.youtube.com/watch?v=5pAjvQ5uu7I">press conference</a> and about 5200 40MB gzipped CSV files. And that’s <strong>compressed </strong>CSVs, the total size of the data is 532GB, and over a billion rows, each one another sun.</p><p>Each row looks more or less like this:</p><pre>,,,,,,,0.35475,,,,,,,,,,115,0,115,0,0,0,,0.6696595881966159,1.4008253634028593,false,1.2046634,0.3231782,,2,25,false,0.33076313,0.15289937,0.3994712,0.3902733,-96.040985,-9.364204,-10.255349,-21.1315,120,645.2563508174401,2.6361056560487532,18.500439344588465,NOT_AVAILABLE,59.27191935938144,3.8225596506032447,299.3146621937641,46.346717555917245</pre><p>And Gaia is <em>accurate</em>. For the brightest stars, their positions will be measured to 5 microarcseconds, which is the equivalent of a dime on the moon as viewed from earth. It’s <em>bananas</em>.</p><p>Its release garnered little fanfare in the media, 2016 being what it is. Also, despite the miraculous nature of the work being done by this satellite, the main image they released doesn’t really impress at newsfeed-scales.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*tjGXrdX3aVabjNCpW7yRoQ.jpeg" /></figure><p>It’s black and white, and it’s kind of glitchy, and it really belies the amount of information this brave little toaster has gathered for us. One thing this image fails to convey in particular: the fact that over 2 million of these stars now have known 3D coordinates in space, with many more to come. Here’s how I extracted that data from a small ocean of CSV files.</p><h3>Determining a star’s distance with parallax</h3><p>Once I’d downloaded all the data, I had to find a way extract just the stars with 3D positions. The data doesn’t actually contain the x,y,z coordinates for the stars, I would have to calculate those. But about 2% of the stars had measurements performed to find their <strong>parallax</strong>, which is the measurement that allows us to determine a star’s distance from us. Remember that “camera 1, camera 2” part in Wayne’s World?</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/403/1*44q2kWPJkTlsB49vhgrcPw.gif" /><figcaption><a href="https://media.giphy.com/media/l0G17xQB3uNJrwv4Y/giphy.gif">or from the star’s perspective</a></figcaption></figure><p>That’s parallax. If you look at the same thing from two different locations, how much it moves tells you how far away it is.</p><p>As the earth (and the Gaia satellite) go around the sun, the stars move a little bit depending on how far away from us they are. The earth is about 150 million km from the sun, so if you took a picture of some stars on June 1st, and then the same exact picture on January 1st, you’d be seeing the stars from two different points, separated by about 300 million km.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/796/1*I_9DXtmhdMo65T2n3HXNtQ.gif" /><figcaption>image courtesy of <a href="http://spiff.rit.edu/classes/phys301/lectures/parallax/parallax.html">Michael Richmond</a></figcaption></figure><p>By very carefully measuring the locations of stars at the two extremes of its orbit around the sun, Gaia can measure the change in the star’s position and use that change to determine the star’s distance. I wanted to calculate those positions and use that data to render these stars in a 3D simulation I could spin around and view from any angle.</p><h3>In the weeds with a few hundred gigs of CSV files</h3><p>My task was pretty simple: filter through all 1 billion rows of data and look at each row to see if it contains a parallax measurement. If it does, let that row through to a new datafile, otherwise skip it.</p><p>When you have to process a whole bunch of data, the best way to do it is with <a href="https://en.wikipedia.org/wiki/Standard_streams">streams</a>. Though they’ve been around since before the <a href="https://github.com/substack/stream-handbook">dawn of unix time</a>, I only recently added them to my metaphorical programming toolbox. Doug McIlroy described them this way back in 1964:</p><blockquote>We should have some ways of connecting programs like garden hose — screw in another segment when it becomes necessary to massage data in another way. This is the way of IO also.</blockquote><p>When designing software for streams, it’s best to think about your data in discrete chunks or packets, and design a flow that each packet goes through to become the kind of data you want at the end. In my case, on one end I had a directory full of compressed CSV files, and on the other end I wanted to have a single much smaller CSV file that contained only the rows I was interested in. Here’s how I did it:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/3a8cdcccec4435df834d5e8969327e78/href">https://medium.com/media/3a8cdcccec4435df834d5e8969327e78/href</a></iframe><p>If you have no programming background, you can still get the gist of what’s going on with a little explanation. If I hide a bit of code, here are the hoses in my data stream and what they are doing:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/08efdb9246215c845e72e23aceef87e8/href">https://medium.com/media/08efdb9246215c845e72e23aceef87e8/href</a></iframe><p>The initial createReadStream reads a compressed data file from the ESA and starts emitting packets of it as they are ready downstream. They are <em>piped</em> through a series of functions that operate on each packet one at a time, and emit new data at the other end. Here’s the command I run that takes a compressed file and emits a filtered uncompressed one.</p><pre>node processStars.js GaiaData_000.csv.tar.gz &gt; GaiaData_000.processed.csv</pre><p>And this is the end of the stream. Gzipped CSV goes in, filtered uncompressed CSV with some calculations performed comes out.</p><p>This took a super long time to run. Even when I spread it across my rendering rig and a couple laptops, multithreaded across every core (<a href="http://unix.stackexchange.com/questions/197352/how-to-start-multi-threaded-grep-in-terminal">using this handy bash util</a>) it still took most of the day. And, it turned out later, as it so often does, that I had made an error in my calculation and needed to run the whole thing again. This was a successful proof of concept, but I needed a better way to run it in parallel.</p><h3>How to throw a few dozen computers at the problem</h3><p><em>(*Note: I used Amazon’s stuff for everything, but that’s not an explicit endorsement of Amazon and their technologies or to say that’s the only way to do it. You could do this same work on a pile of Raspberry Pi’s if you wanted to with minimal modification, but I happened to use Amazon’s cloud and it worked pretty well.)</em></p><p>I knew if I wanted to really be able to painlessly work with this much data going forward, I’d need to have it in a place lots of computers could access. Amazon S3 data transfer is free when it stays within Amazon’s data centers, so if I could get the ESA data to S3, then I could use EC2 to throw lots of servers at the problem pretty cheaply.</p><p>Downloading all the data to S3 concurrently seemed like a good starter project to get the hang of Amazon’s container service and docker clustering stuff. Using JS streams again, I made a little docker container who’s only job was to download a file from the ESA, and stream it straight back up to S3 as it came in.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/50abd14b3c7260f1f89638e645bfbc71/href">https://medium.com/media/50abd14b3c7260f1f89638e645bfbc71/href</a></iframe><p>This worked pretty well, and I could pretty easily start 20 copies of this process, each one getting a different file url to retrieve, across an arbitrary number of servers without really worrying about the IO part. Within a couple hours I’d downloaded the entire 180GB dataset straight to to my own private S3 bucket. Then I re-ran my original calculation script, but this time instead of running around with usb hard drives in my house, I just clicked a few buttons and suddenly had 5 octocore servers somewhere working on the problem for me. This took only 2–3 hours to complete the whole set, and the result was 5000 or so CSV files again, though this time much smaller, a total of about 2 million rows of information. I downloaded these, concatenated them into a single CSV, and imported them into a local sqlite3 database so I could easily query, sort, and manipulate the data in preparation for the next step.</p><h3>Packing 2 million stars for a trip to your GPU</h3><p>CSVs are nice formats because they’re easy to understand. If worse comes to worse, you can query a dataset with the <em>find</em> command in any reliable text editor, and copy and paste data you need into spreadsheets. But whenever you’re dealing with several million of something, every bit of data you can save counts. For example, here’s a single coordinate for a star in CSV format:</p><pre>111.236031,111.369408,0.646683</pre><p>Straightforward enough. That’s three numbers, each representing a position in space in X, Y, and Z dimensions in parsecs. This star is 111 parsecs to the right, 111 parsecs up, and about half a parsec forward from the sun. How much memory and storage does that information require?</p><p>CSV files are strings, and so the smallest unit of storage is a character. If we count, that row of data has 29 characters, comprised of 2 commas, three decimal points, and a bunch of digits between 0 and 9. In a plaintext <a href="https://en.wikipedia.org/wiki/ASCII">ASCII</a> file, each character is stored as a <em>byte</em>, or 8 <em>bits</em>. For each of those 29 characters, there is 1 byte, or 8 1’s and 0’s in a certain combination representing it in a long list in the computer’s memory and on its disk. So for example, a capital A is actually the number 65 in binary, or 01000001, and the number 1 is actually stored as the number 49, or 00110001. When you write a capital A into a text editor, it’s actually flipping 8 transistors somewhere in the machine to represent that value. The letter A is just one way the computer has of representing the number 65.</p><p>This all may seem like indulgent neckbeard nonsense, but <em>really</em> knowing how much data your computer is moving around and operating on is a universally useful tool to diagnose bugs and performance issues. Follow the bits! If you can use fewer of them, things will generally be better.</p><p>CSV files aren’t terribly efficient from a computer’s perspective. If you’re storing numbers, then converting those numbers into letters that your computer converts back into numbers, it adds a lot of work and overhead to the process. It would be best if we could store the data already in whatever format that the computer will eventually be using.</p><p>Computers can process lots of different kinds of information, but it all ends up as bits in the end. Because the information I am dealing with is numbers that have decimal points, I’m using a 32bit floating point value for each coordinate. If we really want to know our data, it’s worth going into how those work a little bit.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*oUo7esF0dJblzTcY8_jUSg.png" /></figure><p>32 bit floats are packed like this. The first bit determines if they’re positive or negative. The next 8 bits determine an exponent, and the last 23 bits represent the “significand”. It’s all a bit mysterious, but the short version is this: you’re storing a big integer number in the significand space, and then applying a positive or negative exponent to it to get the final value with a decimal point. It’s <em>definitely</em> <a href="https://en.wikipedia.org/wiki/Single-precision_floating-point_format">more complicated than that</a> and I don’t fully understand it. Suffice it to say, each x, y, and z value for our star ends up as 32 bits in the format above when it is written to memory or mathematically operated upon by the computer. Using bits to store data in Float32 format, the 3 numbers from our CSV above end up like this:</p><pre>              byte0    byte1    byte2    byte3<br>              -------- -------- -------- --------<br>111.23603   = 01000010 11011110 01111000 11011001<br>111.36941   = 01000010 11011110 10111101 00100011<br>0.646683    = 00111111 00100101 10001101 00000100</pre><p>By cleverly using the number of combinations of bits available to us in groups of 32 (2³² ~ 4.3 billion-ish), we can store data much more efficiently than as a list of individual characters. We also can store data in a <em>pre-formatted</em> way. Meaning that later on when we retrieve these bytes straight from a file, we can immediately use them as numbers without needing to parse through a string and run a conversion. Compare that to the amount of space required for the CSV in plaintext format:</p><pre>              byte0    byte1    byte2    byte...n<br>              -------- -------- -------- --------<br>111.23603,  = 00110001 00110001 00110001 00101110<br>              00110010 00110011 00110110 00110000<br>              00110011 00101100<br>111.369408, = 00110001 00110001 00110001 00101110<br>              00110011 00110110 00111001 00110100<br>              00110000 00111000 00101100<br>0.646683    = 00110000 00101110 00110110 00110100<br>              00110110 00110110 00111000 00110011</pre><p>With the floating point version, the numbers will always contain the exact same number of bits no matter how big they are. This means that you can just count bits as they come in, and you’ll know exactly how many stars you have received just by the count. You can also start using that data as soon as it is available because you know exactly when each value starts and ends with some simple division. With a string, it’s unclear how much information you are waiting for and the amount changes row to row.</p><p>To make a binary file, I again use streams to dump the 32 raw bits of each float32 number directly to a file with no additional formatting. At this point, I’m working with a local database that I derived from the 2 million or so rows I extracted from the CSV files in a previous section, so I can just query it for values with valid parallax. It looks like this:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/94ab0002e189e452a568e041fabb3ed2/href">https://medium.com/media/94ab0002e189e452a568e041fabb3ed2/href</a></iframe><p>The file I am using contains an x,y and z coordinate in float32 format for two million stars. So each star requires 12 bytes (96 bits) of data to determine its position. You can’t really get any smaller than that without giving up precision. We are outside the realm of media meant for human consumption, where clever algorithms can throw away data our meat can’t sense. We’re in the realm of pure information now, and you can’t really trick data into being smaller here.</p><p>All told, stars.bin is 24,313,140 bytes. So, knowing that each star is exactly 12 bytes, dividing by 12 that should contain exactly <strong>2,026,095</strong> stars.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/284/1*a4RTzfGg3GW4RAntgy5hTA.png" /><figcaption>Damnit, close enough.</figcaption></figure><h3>Torrenting the galaxy</h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*NCsydc9tepgSMEYbAAzmDA.png" /></figure><p>Because the binary file produced above is just one long list of groups of 12 bytes, I can process it however I want, including in pieces as it downloads. The simplest way would be an HTTP request, the same way you download an image or video. Using streams yet again I can <a href="https://gist.github.com/flimshaw/0446885d687f3c14a09684465b805b6d">process the data as it downloads</a> in discrete chunks as they arrive.</p><p>All of this combines to be a pretty resilient method for data storage, and one that lends itself to being easily shared via a flat file over http, or even using <a href="https://webtorrent.io/">webtorrent.js</a>. By default when you arrive at <a href="http://charliehoey.com/threejs-demos/gaia_dr1.html">Gaia 3D</a>, you download the star data peer to peer over a torrent. This means that while you are using the simulation, you’re also serving data to other people who are using it. So, if this were to be a viral sensation ten minutes from now, theoretically the load increase on my servers would not include the 24 megabyte data file full of star positions. The more people are using the simulation, the more people are <em>serving</em> the data it requires.</p><p>Regardless of how it gets downloaded, the data is passed to the graphics card in the same way. I use <a href="http://threejs.org/">Three.js</a> to render a list of coordinates as points in three dimensions in a browser window. This code snippet runs in an update loop every time a frame is rendered, and if a new chunk of data has been downloaded, it passes its data to an array the graphics card will treat as a 3D point cloud. The chunk comes in as an unformatted list of bytes.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/06b8d91b1b8280abc8b15b8d7dc9c6a1/href">https://medium.com/media/06b8d91b1b8280abc8b15b8d7dc9c6a1/href</a></iframe><p>Because we stored our bits directly as Float32 values, there is no processing required, and data from the network buffer can be shuttled <em>directly</em> to the GPU, already in its final floating point form. This has huge performance benefits, and lets you scale graphical applications right to the edge of what the metal can do. It also lets you run a simulation like this, with big data files and lots of geometry even on mobile devices.</p><h3>The Final Result</h3><p>At the end of it all, the bits end up somewhere in your graphics card. When I copy numbers to a portion of the GPU’s memory, it takes them to represent a point in 3D space where it will render a white dot exactly 1 pixel in size.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*HjaMwMfiWjWKcowz81JxyA.jpeg" /></figure><p>Stars load in groups, sequentially in the order they were originally packed by the Gaia team. The mission is still going on, so black parts of the image are parts of the sky Gaia has yet to scan completely. More and more information will arrive over the next few years to fill in this picture. And, because of a meticulous data workflow, stars can download progressively while the frame rate stays usable even on older mobile devices, and I am (theoretically) prepared for a big spike in interest by distributing the data file peer to peer with webtorrents. There’s something nice about sharing the stars with other people.</p><p>I hope this was a useful journey for someone. Please do <a href="http://charliehoey.com/threejs-demos/gaia_dr1.html">try the simulation</a> itself if you haven’t, the screenshots don’t do it justice. Every single dot you see is a whole other sun, and we know just where it is. If you’re feeling generous, leave your browser window open and you’ll share the stars with any other strangers that happen by. The scripts I use to create files from Gaia are <a href="https://github.com/flimshaw/gaia-tools">up on github</a>, please feel free to use them on your own projects.</p><p>Many thanks to the Gaia team and the ESA for their beautiful and awe-inspiring work. We’re mapping the galaxy in a way that was science fiction ten years ago. I can’t wait for the next batch of data to come in.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=457ff70c0f93" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Conway’s Game of Light]]></title>
            <link>https://medium.com/@flimshaw/conway-s-game-of-light-2db2dbb8bfdb?source=rss-fb59f8f96e13------2</link>
            <guid isPermaLink="false">https://medium.com/p/2db2dbb8bfdb</guid>
            <category><![CDATA[mathematics]]></category>
            <category><![CDATA[3d-printing]]></category>
            <category><![CDATA[design]]></category>
            <dc:creator><![CDATA[Charlie Hoey]]></dc:creator>
            <pubDate>Mon, 25 Jan 2016 14:41:26 GMT</pubDate>
            <atom:updated>2016-01-25T14:52:28.351Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*fo8_aNW3oh-qC3CBTUm-Ag.jpeg" /></figure><p>This is a short piece about a nightlight I designed and constructed for some of my friends this Christmas. It is based on an ancient algorithm (circa 1970) by British mathematician John Conway called Conway’s Game of Life. It’s an elegant example of <em>emergent behavior</em>. If you have some graph paper and a pencil, you can play it by hand:</p><ol><li>Color some random cells on graph paper black.</li><li>Go through each cell and count how many neighbors it has that are black (min is 0, max is 8). Write the number down in the cell.</li><li>Go through each cell again, and turn all white cells marked 3 black.</li><li>Leave all black cells that are between 2 and 3 alone.</li><li>Turn any black cell greater than 3 or less than 2 white.</li></ol><p>That’s it. If you run these simple rules, provably devoid of intention or complex behavior, on a grid of data, interesting patterns emerge.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/121/1*pT0yugOppUuDiNoDs2WfgA.gif" /></figure><p>This pattern is called a ‘Glider’. It predictably repeats and travels down and to the right over successive generations. There is no mention of Gliders in the game’s ruleset, no specifics on how fast they travel or how to form repeating patterns. But this particular pattern, processed through the rules above, produces an ‘organism’. Is biological life a vastly more complex version of this idea? Just a very complex repeating pattern borne without intention from the rules of chemistry?</p><p>Anyways, it’s interesting to think about is what I’m saying. But also not something you want to be thinking about 24/7. It’s something that’s nice to think about <em>every so often</em>. And so it seemed like the perfect idea to bring to the oft overlooked artistic medium of the nightlight. I’ve got a 3D printer, whose purchase I often seek to justify. And I love browsing around on Adafruit and listening to Boards of Canada and soldering things, and Christmas was coming, so why not?</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*Cf2v4s39LxCzZL5uchRxeg.jpeg" /></figure><h4>On My Process with 3D Printers</h4><p>I have my Microcenter-brand Replicator Dual clone pretty well-tuned to match my model dimensions, but it is not perfect. I go through dozens of iterations for my designs. Each iteration, I design something that will let me test as many aspects as I can without them interfering with each other, then I print it out. Next, I test it for fit and with calipers and screws, and make adjustments here and there in my 3D model based on the print. Then I print it again and repeat the process. If you are really moving, sometimes you can be tweaking one aspect of your design while a test print for a <em>different</em> design problem is printing and really iterate like woah. In my case, each nightlight enclosure takes about 45–60 minutes to print, so I would generally spend about that long making revisions to my 3D model during a session, and then retrieve the previous round’s print and immediately start the next.</p><p>When you’re really moving, and your printer is working well, this is a very rewarding creative process. I was fortunate and had a very low failure rate, only one out of probably more than 40 test prints failed. It was not always so.</p><p>Like any craft, 3D printing tools each have their own idiosyncrasies, and you can only master them through experience, repetition, and a complete understanding of the tools themselves. I started out in 3D printing by fixing up a Cupcake CNC back in the day, and my struggles to tune/rebuild nearly every part of the machine rewarded me with a pretty complete understanding of it. That experience really proved invaluable for troubleshooting and designing 3D prints. I’m only recently reaching a point where I’m <em>usually</em> able to go from idea to 3D print without too much back peddling. It’s been a long road to get here. But let me — a person to whom Blender appeared as an impenetrable riot of grey squares and chaos three years ago — stand as testament: <em>you can do it</em>. It Gets Better.</p><p>(Also: AquaNet (unscented). I’m serious. I spray a sensible mist of AquaNet on my heated print bed every 25 prints or so, and things almost never curl.)</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*3nh3vySc1wNYutSE1WALGw.jpeg" /></figure><h4>Designing the Nightlight</h4><p>For the Game of Life Nightlight, I wanted to use parts that were easy to come by. The Apple Cube USB power supplies are cheap and ubiquitous, they put out a respectable 1 amp of current, and have a nice, sharp-edged shape. I wanted to design an enclosure I could snap one of these in and out of without any fasteners. If I could do that, then the hardest and pretty much only potentially dangerous aspect of this project, connecting with mains voltage, would have been left in the experienced, supple hands of an Apple engineer I’ll never meet, with far more experience and liability insurance than me.</p><p>The processor and display module are both from <a href="http://adafruit.com/">Adafruit</a>, coming in at about $6 and $10 respectively. The processor is an <a href="https://www.adafruit.com/product/1501">Adafruit Trinket</a>, the display module is an <a href="https://www.adafruit.com/products/871">LED Matrix w/ i2c Controller</a>. I could have saved some money by designing my own boards, but I wanted to make something that I could eventually publish on Thingiverse for others to build, and I had a schedule to keep.</p><h4>The Code</h4><p>Zillions of versions of the Game of Life algorithm have been written. I derived my code from a handful of different sources (<a href="http://brownsofa.org/blog/2010/12/30/arduino-8x8-game-of-life/">esp this one</a>) I found through some Googling. The Trinket has just 5KB of usable program space, and I used very nearly all of it. There is definitely room for optimization, and I am including a rather large LED Display library I’m barely using. But again, I had a deadline, so once it worked and fit on the Trinket, I called it good enough to ship. I let the Game of Life simulation run until 125 generations have gone by, or all the cells are dead, whichever comes first, and the display shows the state of the game array.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*AM4-pRsP6rGYkdU-1f-8sw.jpeg" /></figure><h4>The Construction</h4><p>I tried several different construction methods until I settled on the one that felt best balance of efficient and hard to mess up. First, I stripped and tinned all the wires I would need to use for each nightlight and set them aside. Then mounted the Trinket and display module in the 3D printed enclosure with some 4–40 screws. I then put healthy blobs of solder on all the pads to which I would connect wires (power, ground, and two data lines on both modules). Next, I soldered the wires that would carry power to the USB connector on one side, then to the power connection points on both the Trinket and the display module. I soldered the Trinket first and worked my way up, as it was the harder one to reach with the soldering iron. Because I wasn’t able to access the back of the board once things were mounted, these wires are soldered kind of surface-mount style. I would rest them on the connection point and then heat the wire and the point with the soldering iron, then pull the iron away away and hold the wire in place until it cooled. Next, after all the wires had been connected, I would program the firmware onto the trinket, then plug the dangling USB connector into an Apple USB cube to test it. If everything worked, I would see the screen light up, with a glider in a leisurely crawl across it. Finally, I gingerly snapped the USB cube into place and plugged it in, and then we were done.</p><p>I constructed a bit more than twenty nightlights in this way, usually 2 or 3 at a time. I got to a point where I could assemble one start to finish in about 20 minutes. I’d always plug them in and leave them afterwards to run for a few days, just to be safe. Navigating the house at night during this period of my life was a <em>breeze</em>.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*uNvORme8KP5iNyOz9SHkaA.jpeg" /><figcaption>Hudson, as cute as he is unhelpful.</figcaption></figure><h4>The Packaging</h4><p>Really, if I’m honest, I’ve always wanted to have a <em>product</em>. I like imagining that something I designed and built is being used by someone somewhere else. Occasionally, when I’m walking to the subway or grinding my morning coffee by hand for some reason, I wonder if anybody’s looking at something I’ve made. At its best, it’s like being in two places at once, and at its worst it feels sort of vain and needy. But, there it is. Deep cut.</p><p>It wasn’t until all the nightlights were constructed and ready to be shipped that I realized they needed some kind of context. I couldn’t just send my friends some hunk of plastic with wires hanging out of it that blinked randomly. That’s asking for trouble. Also, I wanted to share something with them that I found elegant and beautiful, but it required a little explanation. A user’s guide seemed like the right choice.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*8KVqV7aJ6g-bigowKs7pbw.jpeg" /></figure><p>I opened the manual with a letter of holiday greeting / technical explanation. Also a few notes about children and pets, and the annotated source code. My wife Ashley whipped up a corporate logo, a field guide to various repeating patterns you might encounter, and a mysterious Ashley’s Corner section. Once the manual was done, it felt instantly completed, and much less like a suspicious package from some weirdo. A little polish goes a long way, and adding some documentation helps you present your work the way you’d like it to be seen. We boxed them up with copies of the manual and lots of padding, and shipped them off. Some of them even arrived in time for Christmas.</p><iframe src="https://cdn.embedly.com/widgets/media.html?src=https%3A%2F%2Fvine.co%2Fv%2FiiADqVKnJU5%2Fembed%2Fsimple&amp;url=https%3A%2F%2Fvine.co%2Fv%2FiiADqVKnJU5&amp;image=https%3A%2F%2Fv.cdn.vine.co%2Fr%2Fthumbs%2F1AE42BDE091303050373388533760_SW_WEBM_1453645630955_image.jpg%3FversionId%3Dk21dC2ptx2zb7bID9Y_yMl8xJSInkDHm&amp;key=d04bfffea46d4aeda930ec88cc64b87c&amp;type=text%2Fhtml&amp;schema=vine" width="600" height="600" frameborder="0" scrolling="no"><a href="https://medium.com/media/3678b8d15967cd725cd238425daf0198/href">https://medium.com/media/3678b8d15967cd725cd238425daf0198/href</a></iframe><p>If you’d like to make one of your own, you can find all the information you need on <a href="http://www.thingiverse.com/thing:1290362">the Thingiverse project page</a>. I’ve also released the designs just for the <a href="http://www.thingiverse.com/thing:1290842">Apple USB clip</a> separately, for any other IoT projects you’ve been thinking about, but weren’t sure how you’d power/mount on the wall. Now you can do both with a $5, 1 cubic inch part, that you probably already have kicking around in a junk drawer at your house.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=2db2dbb8bfdb" width="1" height="1" alt="">]]></content:encoded>
        </item>
    </channel>
</rss>