<?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:media="http://search.yahoo.com/mrss/"><channel><title><![CDATA[ChrisParton.net]]></title><description><![CDATA[The elation and frustration of building software and electronics.]]></description><link>https://chrisparton.net/</link><image><url>https://chrisparton.net/favicon.png</url><title>ChrisParton.net</title><link>https://chrisparton.net/</link></image><generator>Ghost 2.9</generator><lastBuildDate>Mon, 21 Oct 2019 10:14:44 GMT</lastBuildDate><atom:link href="https://chrisparton.net/rss" rel="self" type="application/rss+xml"/><ttl>60</ttl><item><title><![CDATA[Rescuing empty JSON arrays in Micronaut]]></title><description><![CDATA[The Micronaut rewrite went great and everything's been running smoothly, but I came across a weird issue last night. When I hit an API endpoint that has an empty array, the array is omitted from the JSON response.]]></description><link>https://chrisparton.net/rescuing-empty-json-arrays-in-micronaut/</link><guid isPermaLink="false">Ghost__Post__5dad7c030d051e04f8aebbee</guid><category><![CDATA[java]]></category><category><![CDATA[programming]]></category><dc:creator><![CDATA[Chris Parton]]></dc:creator><pubDate>Mon, 21 Oct 2019 10:05:00 GMT</pubDate><media:content url="https://chrisparton.net/content/images/2019/10/No-empty-arrays.jpg" medium="image"/><content:encoded><![CDATA[<img src="https://chrisparton.net/content/images/2019/10/No-empty-arrays.jpg" alt="Rescuing empty JSON arrays in Micronaut"/><p>A while back I rewrote the <strong><a href="https://sparkled.io">Sparkled</a> </strong>backend with Micronaut. The backend was a hodge-podge of libraries that worked well enough, but had some nasty glue code that I wasn't too proud of.</p><p><a href="https://micronaut.io">Micronaut</a> is a Spring-like framework from the creators of Grails. Micronaut's raison d'être is to reduce the startup time and memory footprints of microservices by doing some heavy lifting at compile time instead of reflecting at runtime.</p><h3 id="o-wherefore-art-thou-">O <code>[]</code>, <code>[]</code>! Wherefore art thou <code>[]</code>?</h3><p>The Micronaut rewrite went great and everything's been running smoothly, but I came across a weird issue last night. When I hit an API endpoint that has an empty array, the array is omitted from the JSON response.</p><p>This isn't ideal. My frontend code is built on the assumption that the array will always be provided, which is reasonable since I have full control over the API.</p><p>I tried breakpointing the endpoint and serialising the object out using a plain Jackson mapper. Lo and behold, the empty array was there. Time to do some Jackson API sleuthing...</p><h3 id="where-are-the-docs-at">Where are the docs at?</h3><p>Jackson is a great library, but its documentation really isn't great. The <a href="https://github.com/FasterXML/jackson">GitHub readme</a> has dozens and dozens of links, with one documentation link tucked away towards the end. Hitting that link takes you to another markdown file with some third-party tutorials and a link to the <a href="https://github.com/FasterXML/jackson-docs">jackson-docs</a> repository.</p><p>Finally I found the <a href="https://github.com/FasterXML/jackson-docs/wiki/Finding-Javadoc">Finding Javadoc</a> page, which tells me to construct my own URL to get access to the Javadoc for a given Jackson version. That's fine, but it's quicker for me to just look at the source via IntelliJ.</p><h3 id="the-solution">The solution</h3><p>After looking through the docs and going on a couple of wild goose chases, I ended up setting a breakpoint on the <code>ObjectMapperFactory</code> Jackson class. I hit my endpoint and then stepped through the huge <code>objectMapper</code> method.</p><p>I stepped through each line, and used the local mapper object to serialise an empty array at every step. This revealed the culprit pretty quickly:</p><!--kg-card-begin: code--><pre><code class="language-java">objectMapper.setSerializationInclusion(include);</code></pre><!--kg-card-end: code--><p>By default, Micronaut sets the <code>serializationInclusion</code> value to <code><a href="http://fasterxml.github.io/jackson-annotations/javadoc/2.9/com/fasterxml/jackson/annotation/JsonInclude.Include.html#NON_EMPTY">JsonInclude.NON_EMPTY</a></code>, which omits empty objects/arrays from JSON to save space.</p><p>To remedy this, I changed the value to <code><a href="http://fasterxml.github.io/jackson-annotations/javadoc/2.9/com/fasterxml/jackson/annotation/JsonInclude.Include.html#ALWAYS">JsonInclude.ALWAYS</a></code> in <code>application.yml</code>:</p><!--kg-card-begin: code--><pre><code class="language-yml">jackson:
  serializationInclusion: ALWAYS # Include empty arrays in JSON output</code></pre><!--kg-card-end: code-->]]></content:encoded></item><item><title><![CDATA[Finding The Fun In A Boring Task]]></title><description><![CDATA[As part of a recent contract job, I was tasked with creating around 150 distinct icons to represent trains in various statuses on an interactive map. This was a task that nobody was keen to pick up, as it involved long hours in an image editor.]]></description><link>https://chrisparton.net/finding-the-fun-in-a-boring-task/</link><guid isPermaLink="false">Ghost__Post__5d60adf85655c53c345c80ad</guid><category><![CDATA[java]]></category><category><![CDATA[programming]]></category><category><![CDATA[software]]></category><dc:creator><![CDATA[Chris Parton]]></dc:creator><pubDate>Mon, 24 Sep 2018 02:27:00 GMT</pubDate><media:content url="https://chrisparton.net/content/images/2019/08/Train-Icons.png" medium="image"/><content:encoded><![CDATA[<img src="https://chrisparton.net/content/images/2019/08/Train-Icons.png" alt="Finding The Fun In A Boring Task"/><p>As part of a recent contract job, I was tasked with creating around 150 distinct icons to represent trains in various statuses on an interactive map. This was a task that nobody was keen to pick up, as it involved long hours in an image editor.</p><p>I volunteered for the task to free up the full-time devs who have deeper domain knowledge of the product and are therefore better suited to some of the more nitty-gritty logic problems. I quite enjoy tinkering in image editors, but I knew I'd quickly get bored of this particular task regardless.</p><h3 id="the-boring-task">The boring task</h3><p>As I settled in and started reading the requirements, I learned that the icons are mapped to a 4 character status code, and each of the digits (sometimes a combination) dictate various features of the icon. For instance, a certain character in the code being 'E' means a train is late, and a corresponding indicator is present in the icon.</p><p>Armed with this knowledge, I realised I could turn this menial task into a fun one by generating the icons on the fly based on a provided status code. At the same time, this approach would likely be faster to implement than manually creating the icons, and make icon changes much easier in the future.</p><h3 id="making-the-task-fun">Making the task fun</h3><p>It proved to be quite simple to implement the icon generation. I couldn't avoid an image editor entirely; I had to create the unique components that can make up an icon (as transparent PNGs). Fortunately, these were mostly simple shapes.</p><p>Ultimately, the icon generation code looks something like this:</p><!--kg-card-begin: code--><pre><code class="language-lang=java">/**
 * @param iconType the type of icon to generate, which includes width and height in px
 * @param trainCode a 4 character code representing a train's status
 * @return the generated icon
 */
public BufferedImage generateIcon(IconType iconType, String trainCode) {
  List&lt;BufferedImage&gt; iconComponents = Arrays.asList(
    getBodyBackgroundImage(iconType, trainCode),
    getBodyImage(iconType, trainCode),
    // more components...
  );

  BufferedImage result = new BufferedImage(iconType.getWidth(), iconType.getHeight(), 
      BufferedImage.TYPE_INT_ARGB);

  // Stack the components together to create the final image
  for (BufferedImage iconComponent : iconComponents) {
    result.getGraphics().drawImage(image, 0, 0, null);
  }

  return result;
}
</code></pre><!--kg-card-end: code--><h3 id="the-takeaway">The takeaway</h3><p>There's caching and some application-specific warts to contend with, but this blog post isn't really about the implementation of this feature.</p><p>At its essence, the icon generation was quick to implement and resulted in an elegant, fun solution to a boring problem. I put this post together to remind myself (and you, if you're reading!) that the "fun-ness" of a task can have very real implications for the quality and functionality of the end result. I've found that I'm vastly more productive when working on something I enjoy, and this solution saved time and delivered a better result in the end.</p><p>By transforming a boring task into a fun one, you can improve your productivity and have a good time along the way!</p>]]></content:encoded></item><item><title><![CDATA[Interactive Staircase]]></title><description><![CDATA[My third ChrisLights project is something I've been meaning to try for quite some time: building an interactive staircase. I reached the #1 spot on /r/arduino with over 600 upvotes and 11K views.]]></description><link>https://chrisparton.net/interactive-staircase/</link><guid isPermaLink="false">Ghost__Post__5d60ad315655c53c345c8092</guid><category><![CDATA[arduino]]></category><category><![CDATA[chrislights]]></category><category><![CDATA[electronics]]></category><dc:creator><![CDATA[Chris Parton]]></dc:creator><pubDate>Wed, 20 Jun 2018 08:16:00 GMT</pubDate><media:content url="https://chrisparton.net/content/images/2019/08/thumbnail.jpg" medium="image"/><content:encoded><![CDATA[<img src="https://chrisparton.net/content/images/2019/08/thumbnail.jpg" alt="Interactive Staircase"/><p>My third <a href="https://www.youtube.com/channel/UCG_ox3UgSRHj-m_zG_mJCUg">ChrisLights</a> project is something I've been meaning to try for quite some time: building an interactive staircase.</p><p>The main blocker I always faced was the task of accurately sensing where a person is on the staircase. I'd always imagined using an ultrasonic sensor for this, but the results were far too erratic when using them in the confined space around my staircase.</p><p>After realising that I could use an array of lasers and photoresistors instead, I ordered the components and started building.</p><p>It took a lot of work - especially on the wiring and soldering side of things - but I was really happy with the end result and the response I got from the video blew me away! I reached the #1 spot on <a href="https://www.reddit.com/r/arduino">/r/arduino</a> with <a href="https://www.reddit.com/r/arduino/comments/8s4msz/i_just_finished_making_this_interactive_led">over 600 upvotes and 11K views</a>, got over <a href="https://9gag.com/gag/adKoEjV/just-finished-making-these-interactive-led-stairs">900 upvotes on 9gag</a>, and I was <a href="https://twitter.com/arduino/status/1009159342048907264">retweeted by the official Arduino twitter</a>.</p><h3 id="the-results">The Results</h3><p>You can see the results (and more of an explanation) in the video below:</p><!--kg-card-begin: html--> <iframe src="https://www.youtube.com/embed/h5pk4Sp4jLw" frameborder="0" allowfullscreen=""/><!--kg-card-end: html--><p>I'm busy working on a Part 2 video, which will add more sophisticated effects to the staircase.</p>]]></content:encoded></item><item><title><![CDATA[Light Discs: An Experiment Gone Right!]]></title><description><![CDATA[I figured that, when combined with fast rotation, a high-density LED strip attached to my ceiling fan would create a neat persistence-of-vision effect.]]></description><link>https://chrisparton.net/light-discs-an-experiment-gone-right/</link><guid isPermaLink="false">Ghost__Post__5d60ac8c5655c53c345c807f</guid><category><![CDATA[arduino]]></category><category><![CDATA[chrislights]]></category><dc:creator><![CDATA[Chris Parton]]></dc:creator><pubDate>Mon, 23 Apr 2018 20:02:00 GMT</pubDate><media:content url="https://chrisparton.net/content/images/2019/08/ChrisLights_Disc_57.jpg" medium="image"/><content:encoded><![CDATA[<img src="https://chrisparton.net/content/images/2019/08/ChrisLights_Disc_57.jpg" alt="Light Discs: An Experiment Gone Right!"/><p>For <a href="https://www.youtube.com/channel/UCG_ox3UgSRHj-m_zG_mJCUg">ChrisLights</a> video #2, I decided to test out an idea I had whilst laying in bad, looking up at my ceiling.</p><p>I figured that, when combined with fast rotation, a high-density LED strip attached to my ceiling fan would create a neat persistence-of-vision effect.</p><p>I took a fan blade down and attached the LED strip using elastic bands. I added an Arduino Pro Mini to drive the LED strip and a LiPo battery to power it all. I used the <a href="https://github.com/FastLED/FastLED/blob/master/examples/DemoReel100/DemoReel100.ino">FastLED "100-line" demo reel</a> on the Arduino, which cycles through some awesome effects.</p><h3 id="the-results">The Results</h3><p>You can see the results (and more of an explanation) in the video below:</p><p>I've placed all the photos I took on the public domain. You can download them <a href="https://drive.google.com/drive/u/1/folders/1b-5UjHJj6ltql3JG7MDND21-EprUYES0">here</a>. No attribution is required, but I'd love to hear from you if you enjoy or use any of the photos!</p><p>This project has given me lots of cool ideas for future light painting projects, and I'm excited to pursue those in the not-too-distant future.</p>]]></content:encoded></item><item><title><![CDATA[Introducing ChrisLights!]]></title><description><![CDATA[I've launched a new YouTube channel called ChrisLights. It's devoted to my love of lights, sound, games and code, and to projects that combine these elements into something unique and fun.]]></description><link>https://chrisparton.net/introducing-chrislights/</link><guid isPermaLink="false">Ghost__Post__5d60ac2c5655c53c345c806a</guid><category><![CDATA[arduino]]></category><category><![CDATA[electronics]]></category><category><![CDATA[chrislights]]></category><dc:creator><![CDATA[Chris Parton]]></dc:creator><pubDate>Mon, 16 Apr 2018 21:43:00 GMT</pubDate><media:content url="https://chrisparton.net/content/images/2019/08/YouTube-Background.png" medium="image"/><content:encoded><![CDATA[<img src="https://chrisparton.net/content/images/2019/08/YouTube-Background.png" alt="Introducing ChrisLights!"/><p>I've launched a new YouTube channel called <a href="https://www.youtube.com/channel/UCG_ox3UgSRHj-m_zG_mJCUg">ChrisLights</a>. It's devoted to my love of lights, sound, games and code, and to projects that combine these elements into something unique and fun.</p><h3 id="doom-ii-gets-lit-up-">Doom II Gets Lit Up!</h3><p>For my first video, I wrote a Java application that analyses the ammo count pixels of a running Doom II game. It uses this information to detect when bullets are fired and sends this data wirelessly to an ESP32. The ESP32 controls an LED strip, and sends different effects through the strip to correspond with gunfire from different weapons.</p><p>It was a lot of fun to create, and you can check it out below:</p><!--kg-card-begin: html--><iframe src="https://www.youtube.com/embed/Uxh_LZPdhqI" frameborder="0" allowfullscreen=""/><!--kg-card-end: html-->]]></content:encoded></item><item><title><![CDATA[The LED Pixel Master Course]]></title><description><![CDATA[Today, I released The LED Pixel Master Course on Udemy! I've wanted to create a Udemy course for quite a while now, and I figured a course on LED pixels was the perfect place to start.]]></description><link>https://chrisparton.net/the-led-pixel-master-course/</link><guid isPermaLink="false">Ghost__Post__5d60abe55655c53c345c805b</guid><category><![CDATA[arduino]]></category><category><![CDATA[electronics]]></category><category><![CDATA[udemy]]></category><dc:creator><![CDATA[Chris Parton]]></dc:creator><pubDate>Wed, 11 Apr 2018 14:58:00 GMT</pubDate><media:content url="https://chrisparton.net/content/images/2019/08/Course-Image.jpg" medium="image"/><content:encoded><![CDATA[<img src="https://chrisparton.net/content/images/2019/08/Course-Image.jpg" alt="The LED Pixel Master Course"/><p>Today, I released The LED Pixel Master Course on Udemy! I've wanted to create a Udemy course for quite a while now, and I figured a course on LED pixels was the perfect place to start.</p><p>You can use <a href="https://www.udemy.com/the-led-pixel-master-course/?couponCode=LPMC10">this link</a> to get the course for $10 using a special coupon :)</p><p>I created the course because I had to build up my knowledge of LED pixels by cobbling together information (and misinformation) from multiple sources, including documentation, forums, online videos and lots of trial and error. I want the course to be a single place where people can get all of the information they need to learn all about LED pixels and how to use them.</p><p>The course focuses on safety and best practices throughout, whereas most video tutorials are more like step-by-step guides that don't explain <em>why</em> things are done the way they are.</p><p>I'm really proud of how the course turned out. I know that things can be improved (and they will be over time), but for my first course I think it's a solid effort.</p><p>I thought I'd jot down some notes on the things I learned whilst creating the course.</p><h3 id="camera">Camera</h3><p>I mainly used my Canon EOS M with an 18-55mm lens (set at around 24mm) to record the course. I made use of a macro lens for some closeup shots of LED pixels, and used my Galaxy S7 to record some of the soldering etc.</p><h3 id="lighting">Lighting</h3><p>I had never really recorded myself on camera for anything online before, and I didn't want cruddy video quality. I took a look at some lighting tutorials online and quickly realised I'd need to get my hands on some softboxes or umbrella lights. I ended up snagging a great bargain on Gumtree: three softboxes (one of them with a boom stand) and two umbrella lights with a carry case for $80.</p><h3 id="audio">Audio</h3><p>I was initially planning on investing in a Blue Yeti mic for my audio, but I ended up going with the Rode SmartLav+ lapel mic. They cost $58 but I got one for $36 through a friend at JB. The audio quality of the mic is really quite good, but the main downside is that the mic uses a TRRS connector, and needs a $15 adapter to work with a PC.</p><p>I ended up using the mic as-is with my phone to record videos where my face is being recorded, and bought the adapter to record straight into Audacity for screen recorded videos (which are the majority).</p><h3 id="software">Software</h3><p>I went with Camtasia Studio for putting my videos together. I have experience with Adobe After Effects, but I felt it'd be too heavyweight for putting together a course, and I was looking for productivity. Aside from a couple of bugs, Camtasia has been fantastic for quickly putting videos together.</p>]]></content:encoded></item><item><title><![CDATA[Christmas Lights 2017]]></title><description><![CDATA[I decided to temporarily shelve my game and throw myself back into Christmas lights. I dusted off Sparkled and got to work. I'm really proud of what I accomplished in the last three months of the year.]]></description><link>https://chrisparton.net/christmas-lights-2017/</link><guid isPermaLink="false">Ghost__Post__5d60ab455655c53c345c8049</guid><category><![CDATA[arduino]]></category><category><![CDATA[christmas lights]]></category><category><![CDATA[electronics]]></category><category><![CDATA[sparkled]]></category><dc:creator><![CDATA[Chris Parton]]></dc:creator><pubDate>Tue, 02 Jan 2018 07:53:00 GMT</pubDate><media:content url="https://chrisparton.net/content/images/2019/08/lights.jpg" medium="image"/><content:encoded><![CDATA[<img src="https://chrisparton.net/content/images/2019/08/lights.jpg" alt="Christmas Lights 2017"/><p>2017 was a year of many side projects for me. The majority of the year was focused on building my first game for GirtGames and I didn't think I'd have time to put anything together for Christmas. As is my way, however, I ran out of steam on my GirtGames project in September and felt myself being pulled back towards Christmas lights.</p><p>Not wanting to work on a project I wasn't interested in, I decided to temporarily shelve my game and throw myself back into Christmas lights. I dusted off Sparkled and got to work. I'm really proud of what I accomplished in the last three months of the year.</p><p>I started off by doing a huge refactor of the codebase. I changed the underlying database from Postgres to file-based H2 and completed loads of missing functionality. I was working away at this all through December, so I didn't have a lot of time to actually sequence the music.</p><h4 id="a-sneak-peek">A Sneak Peek</h4><p>Here's a sequence playing against a shortened, instrumental version of Coldplay's A Sky Full Of Stars:</p><!--kg-card-begin: html-->  <iframe src="https://www.youtube.com/embed/LjgJN3SzmT0" frameborder="0" allowfullscreen=""/><!--kg-card-end: html--><p>I put this together in around three hours total. I made some mistakes with the sequence and the music is a little off-sync because I hastily added a clean audio track over top of the recorded audio, but the video shows that Sparkled is capable of pulling off an awesome Christmas display.</p><h4 id="what-s-next">What's Next</h4><p>I'm feeling ready to jump back in to GirtGames and get my first game out to the world. I'll still be devoting lots of time to Sparkled throughout the year. I'll be adding new features and effects, rewriting the UI in React, and building a significantly better Christmas display.</p><p>I moved Sparkled to its own GitHub organisation and created some basic content for <a>sparkled.io</a> with the hope that a community will form around the software as it becomes more feature complete.</p>]]></content:encoded></item><item><title><![CDATA[My First Jack-O'-Lantern]]></title><description><![CDATA[Halloween isn't a traditional Australian holiday, but it is becoming more prevalent with each passing year. I thought it'd be neat to try my hand at making a jack-o'-lantern.]]></description><link>https://chrisparton.net/my-first-jack-o-lantern/</link><guid isPermaLink="false">Ghost__Post__5d60aac65655c53c345c8034</guid><category><![CDATA[arduino]]></category><category><![CDATA[electronics]]></category><category><![CDATA[halloween]]></category><dc:creator><![CDATA[Chris Parton]]></dc:creator><pubDate>Fri, 03 Nov 2017 05:35:00 GMT</pubDate><media:content url="https://chrisparton.net/content/images/2019/08/jack-o-lantern.jpg" medium="image"/><content:encoded><![CDATA[<img src="https://chrisparton.net/content/images/2019/08/jack-o-lantern.jpg" alt="My First Jack-O'-Lantern"/><p>Halloween isn't a traditional Australian holiday, but it is becoming more prevalent with each passing year.</p><p>I haven't really embraced the phenomenon myself, but when I found carving pumpkins at my local supermarket I thought it'd be neat to try my hand at making a jack-o'-lantern.</p><p>I downloaded a face template online and drew it on to my pumpkin, then carved it out using my Dremel and its <a href="https://www.dremel.com/en_US/products/-/show-product/accessories/561-multipurpose-cutting-bit">multipurpose cutting bit</a>. I also added a bit of old LED strip powered by a small LiPO battery and Arduino Nano running the <a href="https://github.com/FastLED/FastLED/blob/master/examples/Fire2012WithPalette/Fire2012WithPalette.ino">Fire2012WithPalette FastLED effect</a>.</p><p>I was really happy with the result, given that the whole exercise only took a couple of hours. You can see it in action below:</p><!--kg-card-begin: html--><iframe src="https://www.youtube.com/embed/BtMYZkRteZU" frameborder="0" allowfullscreen=""/><!--kg-card-end: html-->]]></content:encoded></item><item><title><![CDATA[Circular Arc Spritesheet Generator]]></title><description><![CDATA[Now, how to create a spritesheet that displays a 360 degree arc that progressively shrinks to a 0 degree arc? I almost cracked open Photoshop, but I had the idea to generate the spritesheet using an HTML5 canvas.]]></description><link>https://chrisparton.net/circular-arc-spritesheet-generator/</link><guid isPermaLink="false">Ghost__Post__5d60aa2a5655c53c345c801e</guid><category><![CDATA[game dev]]></category><category><![CDATA[javascript]]></category><dc:creator><![CDATA[Chris Parton]]></dc:creator><pubDate>Wed, 01 Mar 2017 03:16:00 GMT</pubDate><media:content url="https://chrisparton.net/content/images/2019/08/Spritesheet-1.png" medium="image"/><content:encoded><![CDATA[<img src="https://chrisparton.net/content/images/2019/08/Spritesheet-1.png" alt="Circular Arc Spritesheet Generator"/><p>In my spare time after work, I've been working on a game in Unity. Early days yet, but I plan on releasing it on Android and possibly iOS.</p><p>One thing I've been struggling with is creating an animated, circular arc that will be used to indicate the time left available to tap a sprite before it detonates.</p><p>This is really simple to do with a UI image, but not so easy with a sprite.</p><p>I've asked for help on the Unity forums but have received crickets so far, so I decided to go for the simplest approach: an animated spritesheeet.</p><p>Now, how to create a spritesheet that displays a 360 degree arc that progressively shrinks to a 0 degree arc? I almost cracked open Photoshop, but I had the idea to generate the spritesheet using an HTML5 canvas and rendering the result out to an image that can be saved.</p><p>I ended up implementing the generator on Codepen: <a href="http://codepen.io/chrisparton1991/pen/MpwRmv">http://codepen.io/chrisparton1991/pen/MpwRmv</a></p><p>It provides several config parameters, including:</p><ul><li>The diameter of the circle</li><li>The line width</li><li>The line colour</li><li>The number of frames to generate</li><li>Clockwise / anticlockwise progression</li><li>Forward / reverse (start circle full or empty)</li></ul><p>There's no fancy UI, the parameters are just sitting at the top of the Javascript section. Still, it's pretty easy to tweak and get some satisfying results!</p>]]></content:encoded></item><item><title><![CDATA[Christmas Lights 2016]]></title><description><![CDATA[I was really proud of myself for getting a display working with LED strips. I failed plenty of times along the way, but I got there in the end. I'm utilising the FastLED library, which does a lot of the heavy lifting for me.]]></description><link>https://chrisparton.net/christmas-lights-2016/</link><guid isPermaLink="false">Ghost__Post__5d60a8f85655c53c345c800a</guid><category><![CDATA[arduino]]></category><category><![CDATA[christmas lights]]></category><category><![CDATA[electronics]]></category><category><![CDATA[software]]></category><dc:creator><![CDATA[Chris Parton]]></dc:creator><pubDate>Wed, 21 Dec 2016 16:09:00 GMT</pubDate><media:content url="https://chrisparton.net/content/images/2019/08/xmas2016.jpg" medium="image"/><content:encoded><![CDATA[<img src="https://chrisparton.net/content/images/2019/08/xmas2016.jpg" alt="Christmas Lights 2016"/><p>My Christmas light display for 2016 is a definite improvement from what I had in 2015. I didn't meet my goal of having lights synchronised to music (which I'll explain below), but I succeeded in putting together a reliable animation sequence using LED strips powered by an Arduino.</p><p>You can see the video below:</p><!--kg-card-begin: html--><iframe src="https://www.youtube.com/embed/jXiJ57UzuP8" frameborder="0" allowfullscreen=""/><!--kg-card-end: html--><p>I was looking through an <a href="https://blog.arduino.cc/2016/12/19/12-dazzling-holiday-light-displays-with-arduino/">Arduino blog post</a> titled "12 Dazzling Holiday Light Displays With Arduino" one morning, and I was pleasantly surprised to find my lights included in the list!</p><h4 id="goals-accomplished">Goals Accomplished</h4><p>I was really proud of myself for getting a display working with LED strips. I failed plenty of times along the way, but I got there in the end. I'm utilising the <a href="https://fastled.io">FastLED</a> library, which does a lot of the heavy lifting for me.</p><p>My wiring is far from perfect, but it's a whole lot more robust than last year's efforts. I've learned a lot from this experience, and I think next year's lights will be even more reliable. I've had just one cable-related issue with this year's lights.</p><h4 id="goals-missed">Goals Missed</h4><p>I really wanted to have full sequencing working for this year's lights. I actually made a fair amount of progress down this road. I had my LED sequencing software essentially working, and I could drive LED strips just fine. The main thing I had to figure out was how to turn those bytes of data into a kickass show.</p><p>After some experimentation, I started down the path of using one Arduino Due to drive all of my LED strips. The Arduino would read the animation data from an SD card and spit it out as needed. There were some downfalls with this approach, but I didn't even get far enough to consider solving those.</p><h5 id="a-problem-of-distance">A Problem Of Distance</h5><p>My display is using cheap-and-nasty UCS1903 LED strips. They generally do the job fine, but the data signal does not handle long distances very well. Even with optimal placement of my Arduino Due (which would expose it to the elements), the distance between the Due and the farthest LED strips was so great that the signal degraded to the point that the LED strips didn't even recognise it.</p><h5 id="giving-up">Giving Up</h5><p>This issue stumped me, and extinguished the flame that was my enthusiasm for the project. I didn't touch it for quite some time. Eventually, I decided I still wanted <em>something</em> for this Christmas, and that something is what you can see in the video above.</p><h5 id="an-epiphany">An Epiphany</h5><p>Whilst I was building my compromise project, I came across the wonders of the <a href="https://www.sparkfun.com/products/13678">ESP8266</a>. The ESP8266 (more accurately, the ESP8266-based boards such as the ESP-01) are a Wi-Fi enabled microcontroller that pack quite a bit of processing power inside a tiny form factor for a very small price.</p><p>I ordered a few of these from eBay and played around with them. I realised that these chips could make my Christmas light dreams a reality. My sequencing software would contain a UDP server that could be polled by 8266 boards to get animation data and feed it to the LED strips. This approach works nicely for a few reasons:</p><ul><li>The 8266 controllers can be situated right next to the LED strips, so long as they're within range of the Wi-Fi signal.</li><li>The server design means that the 8266 chips don't need to worry about synchronising data, and can tolerate dropped packets and even a network dropout.</li></ul><p>This is what I'm working now, and will (hopefully) be the subject of various blog posts throughout the next year.</p><p>Until then, I'm happy with what I've been able to pull off for 2016.</p>]]></content:encoded></item><item><title><![CDATA[Wavesurfer.js: MultiCanvas Renderer]]></title><description><![CDATA[I implemented a MultiCanvas renderer for wavesurfer, which has since been accepted into the repository and released under version 1.1.0.]]></description><link>https://chrisparton.net/wavesurfer-js-multicanvas-renderer/</link><guid isPermaLink="false">Ghost__Post__5d5ddfb95655c53c345c7fc7</guid><category><![CDATA[software]]></category><dc:creator><![CDATA[Chris Parton]]></dc:creator><pubDate>Fri, 29 Apr 2016 00:11:00 GMT</pubDate><media:content url="https://chrisparton.net/content/images/2019/08/timeline.png" medium="image"/><content:encoded><![CDATA[<img src="https://chrisparton.net/content/images/2019/08/timeline.png" alt="Wavesurfer.js: MultiCanvas Renderer"/><p>This is my first blog post in quite a while. I've been busy working  away on my LED animation sequencing software and I'm really pleased with  the results so far (a future blog post will cover the software in  detail).</p><p>One feature of the software is an audio waveform that serves the dual  purpose of assisting with animation timings and facilitating navigation  of the animation timeline:</p><!--kg-card-begin: image--><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://chrisparton.net/content/images/2019/08/image-32.png" class="kg-image" alt="Wavesurfer.js: MultiCanvas Renderer"><figcaption>The Sparkled sequence timeline, including a waveform and synchronised effects</figcaption></img></figure><!--kg-card-end: image--><h2 id="wavesurfer-js">Wavesurfer.js</h2><p>To implement the timeline, I used the excellent <a href="https://web.archive.org/web/20160726051630/https://github.com/katspaugh/wavesurfer.js">wavesurfer.js</a>.  Out of the box, wavesurfer comes with navigation, audio playback,  waveform generation, and a bunch of other configurations and events to  hook into.</p><h2 id="browser-woes">Browser woes</h2><p>The one issue I encountered was that large waveforms wouldn't render. After some research, I found that this was a <a href="https://web.archive.org/web/20160726051630/http://stackoverflow.com/questions/6081483/maximum-size-of-a-canvas-element">browser limitation</a>.</p><h2 id="the-solution">The solution</h2><p>To work around this, I <a href="https://web.archive.org/web/20160726051630/https://github.com/katspaugh/wavesurfer.js/pull/679">implemented</a> a <code>MultiCanvas</code> renderer for wavesurfer, which has since been accepted into the repository and released under version <code>1.1.0</code>.  This was my first ever contribution to an open-source project, so I was  pretty stoked to have it accepted and receive feedback from others.</p><p>The MultiCanvas renderer works by stacking multiple adjacent canvases, the width of which can be controlled by the <code>maxCanvasWidth</code> wavesurfer property. The renderer itself can by used by setting the <code>renderer</code> wavesurfer property to <code>'MultiCanvas'</code>.</p><h2 id="challenges">Challenges</h2><p>Wavesurfer supports two modes of rendering: lines (a  traditional waveform) and bars (looks like a histogram, using average  frequency values for each bar).</p><p>The below image shows a wavesurfer timeline that uses bars. I've  added a red line to indicate a the end of one canvas and the beginning  of the next. Notice that a bar sits right on this line.</p><!--kg-card-begin: image--><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://chrisparton.net/content/images/2019/08/timeline-split-1.png" class="kg-image" alt="Wavesurfer.js: MultiCanvas Renderer"><figcaption>Sometimes, a bar needs to be rendered across two canvases</figcaption></img></figure><!--kg-card-end: image--><p>This complicates things, as the two parts of the bar need to be rendered in different canvases.</p><p>My solution for this was to wrap the canvas <code>fillRect</code> calls, and pass them through the following algorithm:</p><!--kg-card-begin: code--><pre><code>For each canvas:
  Calculate intersection between canvas bounds and waveform bar coordinates
  If an intersection exists, render the intersection to the canvas</code></pre><!--kg-card-end: code--><p>The implementation for the line waveform was similar. I simply  rendered the amplitude data for each canvas until I reached the end of  that canvas, then filled out the line and repeated with the next canvas.</p><p>After my initial implementation, I noticed some thin gaps between the  canvases. I solved this by adding a small overlap (<code>1px * device ratio</code>).</p>]]></content:encoded></item><item><title><![CDATA[A Home-made PCB Workstation On A Budget]]></title><description><![CDATA[As I began learning how to solder, I found the third hand quite useful for holding circuit boards and wires. However, as I progressed I grew more and more frustrated with the lack of manoeuvrability the third hand provided.]]></description><link>https://chrisparton.net/a-home-made-pcb-workstation-on-a-budget/</link><guid isPermaLink="false">Ghost__Post__5d5d37cb5655c53c345c7fa2</guid><category><![CDATA[electronics]]></category><dc:creator><![CDATA[Chris Parton]]></dc:creator><pubDate>Wed, 02 Mar 2016 00:20:00 GMT</pubDate><media:content url="https://chrisparton.net/content/images/2019/08/my-pcb-workstation.jpg" medium="image"/><content:encoded><![CDATA[<h2 id="third-hand">Third Hand</h2><img src="https://chrisparton.net/content/images/2019/08/my-pcb-workstation.jpg" alt="A Home-made PCB Workstation On A Budget"/><p>Back before I started tinkering with electronics, I bought a third hand. I didn't have any particular use for it, I just thought it was a nifty thing to have laying around.</p><p>As I began learning how to solder, I found the third hand quite useful for holding circuit boards and wires. However, as I progressed I grew more and more frustrated with the lack of manoeuvrability the third hand provided.</p><p>If you haven't seen one of these before, they look like this:<br/></p><!--kg-card-begin: image--><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://chrisparton.net/content/images/2019/08/image-24.png" class="kg-image" alt="A Home-made PCB Workstation On A Budget"><figcaption>A "third hand" tool, useful for holding wires and components when soldering</figcaption></img></figure><!--kg-card-end: image--><h2 id="third-hand-">Third Hand++</h2><p>The horizontal bar that connects the arms to the stands limits the usefulness of this tool. I looked online for alternatives, and found an Instructable for a home-made PCB workstation called <a href="http://www.instructables.com/id/Third-Hand-A-multi-use-helping-hand-for-electro/">Third Hand++</a>:<br/></p><!--kg-card-begin: image--><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://chrisparton.net/content/images/2019/08/image-25.png" class="kg-image" alt="A Home-made PCB Workstation On A Budget"><figcaption>Like a third hand, but more flexible</figcaption></img></figure><!--kg-card-end: image--><p>I liked this setup much more than the conventional third hand. Unfortunately, living in Australia, some of these materials aren't as easy or cheap to come by. Therefore, I decided to make my own clone of the Third Hand++, using cheap and/or readily available materials.</p><h2 id="my-pcb-workstation">My PCB Workstation</h2><p>Here's my workstation, in all its splendour:<br/></p><!--kg-card-begin: image--><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://chrisparton.net/content/images/2019/08/image-26.png" class="kg-image" alt="A Home-made PCB Workstation On A Budget"><figcaption>My take on the Third Hand++</figcaption></img></figure><!--kg-card-end: image--><h3 id="equipment-required">Equipment Required</h3><ul><li>Some kind of cutting device, e.g. circular saw, jigsaw, hacksaw (along with appropriate safety gear!)</li><li>Hot glue gun (I suspect a silicone gun would work too)</li><li>Blu-Tack</li><li>Electric drill</li><li>3mm bit</li><li>5mm bit</li><li>10mm bit</li></ul><h3 id="materials">Materials</h3><!--kg-card-begin: html--><table>
<tr>
  <th>Item</th>
  <th>Price (AUD)</th>
</tr>
<tr>
  <td><a href="http://www.bunnings.com.au/projecta-alligator-clips-6-pack_p6330687" target="_blank">Projecta Alligator Clips - 6 Pack</a></td>
  <td>$2.50 (Bunnings)</td>
</tr>

<tr>
  <td><a href="http://www.bunnings.com.au/customwood-mdf-900-x-450-x-12mm-standard-mdf-panel_p0590092" target="_blank">CustomWood MDF 900 x 450 x 12mm Standard MDF Panel</a></td>
  <td>$8.15 (Bunnings)</td>
</tr>

<tr>
  <td><a href="http://www.bunnings.com.au/fiddly-bits-250g-flat-black-spray-paint_p1580054" target="_blank">Fiddly Bits 250g Flat Black Spray Paint</a></td>
  <td>$2.95 (Bunnings)</td>
</tr>

<tr>
  <td><a href="http://www.jaycar.com.au/Electromechanical-Components/Fasteners-%26-Hardware/Fasteners/20mm-x-3mm-Steel-Screws---Pk-25/p/HP0410" target="_blank">20mm x 3mm Steel Screws - Pk.25</a></td>
  <td>$3.50 (Jaycar)</td>
</tr>

<tr>
  <td><a href="http://www.jaycar.com.au/Electromechanical-Components/Fasteners-%26-Hardware/Fasteners/3mm-Steel-Nuts---Pk-25/p/HP0425" target="_blank">3mm Steel Nuts - Pk.25</a></td>
  <td>$2.95 (Jaycar)</td>
</tr>

<tr>
  <td><a href="http://www.bunnings.com.au/madico-19mm-clear-round-vinyl-surface-protection-bumper-pads-6-pack_p3979349" target="_blank">Madico 19mm Clear Round Vinyl Surface Protection Bumper Pads - 6 Pack</a></td>
  <td>$4.25 (Bunnings)</td>
</tr>

<tr>
  <td>2 mini tripods (search eBay for "Mini Octopus Flexible Tripod", lowest price first)</td>
  <td>Approx. $7.50 for 2 tripods (eBay)</td>
</tr>
<tr>
  <th style="text-align: right">Total:</th>
  <th>$31.80</th>
</tr>
</table><!--kg-card-end: html--><p>It's worth noting that all of the above materials, apart from the tripods and (optional) foot stickers, are enough to make at least two of my PCB workstations. If you can find a smaller MDF board and smaller packs of screws and nuts, you will be able to significantly reduce the price to create one workstation.</p><h2 id="construction">Construction</h2><h3 id="step-1-measure-and-cut-mdf">Step 1: Measure and Cut MDF</h3><p>You can make your workstation any size you like, but there are multiple variables to consider, such as:</p><ul><li>The weight of the base</li><li>Ease of portability</li><li>The size of the PCBs you want to work on</li><li>The number of anchor points you want</li><li>The strength and flexibility of the arms</li></ul><p>The last one is important. If your arms are too long, they won't be able to hold much weight at all. However, if they are too short, they won't be flexible enough to be particularly useful.</p><p>I settled on making my board 25x25 cm with 8 anchor points, which I'm happy with in retrospect.</p><p>So, the first task is to cut your board to size.</p><h3 id="step-2-mark-the-holes">Step 2: Mark the Holes</h3><p>I made my four corner anchor point holes 2.5cm from each side of the board. The middle four anchor points are simply the midpoints between the others.</p><p>My resized MDF board with marked anchor point holes:</p><!--kg-card-begin: image--><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://chrisparton.net/content/images/2019/08/image-27.png" class="kg-image" alt="A Home-made PCB Workstation On A Budget"><figcaption>The MDF with holes marked for drilling</figcaption></img></figure><!--kg-card-end: image--><h3 id="step-3-drill-the-holes">Step 3: Drill the Holes</h3><p>Using a 3mm drill bit, drill out all of your marked anchor points, the whole way through.</p><p>Using a 10mm drill bit, drill  shallow holes into the anchor points on the underside of the MDF (it doesn't matter which side, use the rougher/uglier side if there is one). The idea here is to provide a hole large enough for the nut to fit into so the MDF can sit flush on a surface.<br/></p><!--kg-card-begin: image--><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://chrisparton.net/content/images/2019/08/image-28.png" class="kg-image" alt="A Home-made PCB Workstation On A Budget"><figcaption>The MDF with holds drilled and countersunk</figcaption></img></figure><!--kg-card-end: image--><h3 id="step-4-spray-paint">Step 4: Spray Paint</h3><p>This is where you can let your inner artist blossom, or in my case, not. I opted for el cheapo matte black spray paint, which looks awful in the image below. This is largely because I don't have much experience spray painting, and also because the camera flash throws my inadequacies into sharp relief.</p><p>Still, my advice is to make several light passes over one side (and the edges), then flip and repeat once the paint is dry.</p><h3 id="step-5-attach-bumper-pads">Step 5: Attach Bumper Pads</h3><p>Nothing too exciting here, just flip your MDF over and stick on the rubber/vinyl bumper pads. This will prevent your workstation from scratching whatever it's sitting on as you move it around.</p><h3 id="step-6-attach-anchor-points">Step 6: Attach Anchor Points</h3><p>You know those tripods I told you to buy? This is where they start becoming useful. Yank off the three legs, and do what you wish with the holder section.</p><p>With a little force, these segmented legs come apart. Pull out as many individual segments as you have anchor points, and drill a hole down the middle of them using a 3mm bit. I used my <a href="https://www.dremel.com/en-au/attachments/pages/productdetail.aspx?pid=220-01">Dremel drill press</a>, but I imagine it can be done using a regular drill and. Be careful to get the hole in the centre, or you'll drill through the side of the anchor point.</p><p>If you've succeeded, you should now be able to attach the anchor points to your MDF using the 20mm screws. These screws were <em>just</em> long enough for me to attach with countersunk holes. I had to make a few of my countersinks a bit deeper to get them on. I put my screws in so that the nuts are on the underside of the board, and the screwheads are in the top of the anchor points.</p><p>Once your anchor points are attached, you should have something that looks roughly like this:</p><!--kg-card-begin: image--><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://chrisparton.net/content/images/2019/08/image-29.png" class="kg-image" alt="A Home-made PCB Workstation On A Budget"><figcaption>Nearly done! Anchor points attached and sprayed matte black</figcaption></img></figure><!--kg-card-end: image--><h3 id="step-7-make-tool-arms">Step 7: Make Tool Arms</h3><p>Now for the (relatively) tricky part: putting the alligator clips into segments to form tool arms. Start by figuring out how many clips you think will be useful. If you want lots of clips, you may have to purchase more tripods so you have more arm segments to work with. I decided to make four tool arms.</p><p>My alligator clips have a 5mm diameter at their base, so I drilled a 5mm hole into four segments (I actually used my <a href="https://www.dremel.com/en-au/Accessories/Pages/ProductDetail.aspx?pid=561">Dremel cutting bit</a> to hack a hole roughly 5mm, but a 5mm hole would be a bit cleaner. You can see my rough handiwork below:</p><!--kg-card-begin: image--><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://chrisparton.net/content/images/2019/08/image-30.png" class="kg-image" alt="A Home-made PCB Workstation On A Budget"><figcaption>A drilled segment, ready for an alligator clip</figcaption></img></figure><!--kg-card-end: image--><p>Now, get a blob of Blu-Tack about the size of a grape. Sit the anchor point on it, large side touching the tack. Push hard so that the tack fills up most of the large chamber in the segment.</p><p>Next, gently push an alligator clip through the top (small) hole, so that it's held in place by the tack. The clip should protrude from the segment just enough to allow the clip to be opened and closed without interference.</p><p>Finally, use a hot glue gun to pump glue in around the clip shaft, filling up the small chamber. Leave to solidify, then gently remove the tack. The large chamber should be mostly devoid of glue, as it needs to be empty to accommodate other segments being pushed into it.</p><p>If you want to tidy up the glue, you can carefully cut and scrape away excess using a sharp blade like a craft or X-Acto knife.</p><p>The end result should look something like this:</p><!--kg-card-begin: image--><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://chrisparton.net/content/images/2019/08/image-31.png" class="kg-image" alt="A Home-made PCB Workstation On A Budget"><figcaption>A segment with an alligator clip attached using hot glue</figcaption></img></figure><!--kg-card-end: image--><h3 id="step-8-pat-self-on-back">Step 8: Pat Self On Back</h3><p>Congratulations, you've created all of the components for your PCB workstation! All you have to do now is grab a chain of segments, plug them into an anchor point, and attach a tool arm to the end of the segment chain.</p><h2 id="future-enhancements">Future Enhancements</h2><p>There are a few things that could be done to this workstation to make it even niftier, such as:</p><ul><li>An LED tool arm, powered by 2xAA batteries attached to the board.</li><li>A small fan tool arm, to extract soldering fumes (maybe the fan could be held up like a diamond, with two anchor points for added stability. This would need to be powered from something beefier, like a 12V power supply.</li><li>Shrink wrapping the alligator clip jaws to help prevent wear and tear to PCBs.</li><li>Attaching a <a href="http://www.aliexpress.com/price/baku-pcb-holder_price.html">PCB Holder</a> to the base of the workstation.</li></ul>]]></content:encoded></item><item><title><![CDATA[Hacking A Remote Control Power Outlet]]></title><description><![CDATA[Messing around with 240V wiring isn't something I've ever been particularly eager to do, but I wanted a way to programmatically toggle one or more devices running on mains power.]]></description><link>https://chrisparton.net/hacking-a-remote-control-power-outlet/</link><guid isPermaLink="false">Ghost__Post__5d5d2f0d5655c53c345c7f7b</guid><category><![CDATA[arduino]]></category><category><![CDATA[electronics]]></category><dc:creator><![CDATA[Chris Parton]]></dc:creator><pubDate>Mon, 01 Feb 2016 01:16:00 GMT</pubDate><media:content url="https://chrisparton.net/content/images/2019/08/finished-1.jpg" medium="image"/><content:encoded><![CDATA[<img src="https://chrisparton.net/content/images/2019/08/finished-1.jpg" alt="Hacking A Remote Control Power Outlet"/><p>Messing around with 240V wiring isn't something I've ever been particularly eager to do, but I wanted a way to programmatically toggle one or more devices running on mains power.</p><p>If you've seen my <a href="http://chrisparton.net/2016/01/17/christmas-lights-2015/">2015 Christmas Light</a> post, you may have noticed that I have a bunch of traditional Christmas lights that aren't programmed in any way. I want to keep these for this year's display, but I have plans to make a display that synchronises to music. I want to turn the regular lights off when this display is active to maximise the impact.</p><h2 id="options-">Options...</h2><p>There are a few ways to achieve this.</p><h4 id="powerswitch-tail">PowerSwitch Tail</h4><p><a href="http://www.powerswitchtail.com/Pages/PowerSwitchTail240vackit.aspx">PowerSwitch Tail</a> is a range of kits that can be put together with two ends of a mains cable of your choosing. The kit has (low voltage) inputs that can be accessed by a microcontroller to effectively turn the power on and off.</p><p>The problem is, these kits are reasonably pricey and would presumably have to be ordered in from overseas. Also, there's still a degree of danger in wiring these things up.</p><h4 id="relay">Relay</h4><p>The cheaper option would be to simply chop a mains cable in half and stick an appropriately rated relay in there. This is even more dangerous, and I prefer my house when it's not on fire.</p><h4 id="remote-control-switches">Remote Control Switches</h4><p>At the FinoComp office, we've just ordered in some components to create a neat continuous integration light based on a pedestrian crossing light. We're using two <a href="http://zwave.com.au/index.php?_a=viewProd&amp;productId=30">Z-Wave Switch Plugin</a> units and a <a href="http://zwave.com.au/index.php?_a=viewProd&amp;productId=97">RaZberry</a> daughterboard to control them.</p><p>This is probably the most reliable and safe method to achieve what I want, but at $65 a pop for the switches and $95 for the RaZberry, it's much more costly than what I want.</p><h2 id="what-then">What, Then?</h2><p>There's one final option. Take a cheap, remote control power outlet and hack it to support input from a microcontroller. As you may have guessed, this is the approach I ended up taking.</p><p>I bought an <a href="http://www.bunnings.com.au/arlec-remote-control-power-outlet-_p4331239">Arlec Remote Control Power Outlet</a> from Bunnings for $13. The reason I chose this unit (apart from being cheap), is that it has separate "On" and "Off" buttons, which I assumed meant separate signals for turning the outlet on and off. This is very important, because the communication is typically unidirectional in these things.</p><!--kg-card-begin: image--><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://chrisparton.net/content/images/2019/08/image-20.png" class="kg-image" alt="Hacking A Remote Control Power Outlet"><figcaption>The outlet, complete with one unmolested controller</figcaption></img></figure><!--kg-card-end: image--><p>If the same signal is sent to toggle power and there's no way to know the state of the outlet, the state of the outlet may quickly become out of sync with what my software expects. Having separate signals means I can send the same signal a bunch of times to increase the likelihood of it being received.</p><p>I cracked open the controller to see what I was dealing with. The quality of the circuit board isn't stellar, but it's good enough for my purposes. The circuit itself isn't too complex. Basically a bunch of buttons attached to a <a href="http://www.holtek.com/pdf/consumer/4xR01T3v130.pdf">Holtek HT48R01T3 MCU</a>, which contains an RF transmitter.</p><!--kg-card-begin: image--><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://chrisparton.net/content/images/2019/08/image-21.png" class="kg-image" alt="Hacking A Remote Control Power Outlet"><figcaption>Inside the controller there are lots of buttons on a very plain PCB</figcaption></img></figure><!--kg-card-end: image--><!--kg-card-begin: image--><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://chrisparton.net/content/images/2019/08/image-22.png" class="kg-image" alt="Hacking A Remote Control Power Outlet"><figcaption>The underside of the PCB is a little more interesting, with a microcontroller and other components</figcaption></img></figure><!--kg-card-end: image--><p>Now, there are various blog posts around the place that detail ways to capture IR signals, send them through a PC microphone jack and analyse their waveforms in order to reproduce the signals.</p><p>Thing is, I'm too lazy to do all that if it can be avoided. I decided to simply rewire the "All On" and "All Off" buttons to allow me to control them from an Arduino Due.</p><h2 id="rewiring-the-controller">Rewiring The Controller</h2><p>I ended up adding four wires in total. Two of these wires were simply to allow the remote to be powered by my Arduino Due instead of using batteries. The remote ran from two 1.5V LR44 batteries in series. The Arduino Due works with 3.3V, which is close enough for me. Of course, I measured the current draw through the remote before trying this. It was only 8mA, which is a small enough amount to run through the Arduino without blowing it up.</p><p>The other two wires were added to the positive side of the "All On" and "All Off" buttons, respectively. I worked out which side of the buttons were the positive side using the DC voltage mode on my multimeter.</p><p>These pins are connected to the Arduino, and are kept high. When one of the pins is brought low, the button is effectively circumvented, completing the circuit and allowing the signal to be sent. The nice thing about my approach is that the buttons can still be used, even when the controller is connected to the Arduino.</p><p>I finished the job by applying hot glue to prevent the wires from moving about and breaking. It's ugly, but I don't need it to be pretty for what I'm doing.</p><!--kg-card-begin: image--><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://chrisparton.net/content/images/2019/08/image-23.png" class="kg-image" alt="Hacking A Remote Control Power Outlet"><figcaption>A crude wired connection with some hot glue to keep the wires in place</figcaption></img></figure><!--kg-card-end: image--><h2 id="the-code">The Code</h2><p>I've only written a basic test program to ensure the controller can turn the outlet on and off. Here it is for completeness:</p><!--kg-card-begin: code--><pre><code class="language-language-cpp">#define ON_PIN 22
#define OFF_PIN 23
#define TIME_BETWEEN_POWER_TOGGLE_MS 5000
#define MESSAGE_DURATION_MS 500

void setup() {
    pinMode(ON_PIN, OUTPUT);
    digitalWrite(ON_PIN, HIGH);
    
    pinMode(OFF_PIN, OUTPUT);
    digitalWrite(OFF_PIN, HIGH);
}

void loop() {
  turnOn();
  delay(TIME_BETWEEN_POWER_TOGGLE_MS);
  turnOff();
  delay(TIME_BETWEEN_POWER_TOGGLE_MS);
}

void turnOn() {
    sendMessage(ON_PIN);
}

void turnOff() {
    sendMessage(OFF_PIN);
}

void sendMessage(int pin) {
  digitalWrite(pin, LOW);
  delay(MESSAGE_DURATION_MS);
  digitalWrite(pin, HIGH);
}
</code></pre><!--kg-card-end: code--><h2 id="the-finished-product">The Finished Product</h2><p>Here's a video of the controller in action.</p><!--kg-card-begin: html--><iframe src="https://www.youtube.com/embed/YIEjqCMYpUQ" frameborder="0" allowfullscreen=""/><!--kg-card-end: html-->]]></content:encoded></item><item><title><![CDATA[Making The Perfect LED Spiral]]></title><description><![CDATA[As mentioned in my previous post, I have four pillars on the front of my house that are just begging to be covered in lights.]]></description><link>https://chrisparton.net/making-the-perfect-led-spiral/</link><guid isPermaLink="false">Ghost__Post__5d5d2d5a5655c53c345c7f42</guid><category><![CDATA[christmas lights]]></category><category><![CDATA[maths]]></category><dc:creator><![CDATA[Chris Parton]]></dc:creator><pubDate>Mon, 18 Jan 2016 01:07:00 GMT</pubDate><media:content url="https://chrisparton.net/content/images/2019/08/template-01.jpg" medium="image"/><content:encoded><![CDATA[<h2 id="2015-hack">2015: Hack</h2><img src="https://chrisparton.net/content/images/2019/08/template-01.jpg" alt="Making The Perfect LED Spiral"/><p>As mentioned in my previous post, I have four pillars on the front of my house that are just begging to be covered in lights.</p><p>My approach last year was to run around the pillars with a bunch of Christmas lights in my hand and let them wind themselves up. It was a quick and effective method, but the spacing and angle of the lights were far from perfect. It also made me quite dizzy.</p><h2 id="2016-craftsmanship-hopefully-">2016: Craftsmanship (Hopefully)</h2><p>This year the pillars will be pimped out with RGB LED strips, and I turned to the powers of mathematics to help me create the perfect LED spiral.</p><p>My goal here is to have all four pillars set up identically. To achieve this, I needed to learn a bit about how spirals work. After some Googling, I came across this <a href="https://www.math.nmsu.edu/~breakingaway/ebookofcalculus/HandsOnUnitsInvolvingIntegrals/StringAroundCan/StringAroundCanWebPage01.html">New Mexico State University page</a>.</p><h4 id="crunching-the-numbers">Crunching The Numbers</h4><ul><li>Pillars:</li><li>Height: 1890mm</li><li>Circumference: 395mm</li><li>LED Strips (1 per pillar):</li><li>Length: 5000mm</li><li>Width: 13mm</li></ul><p>The formula to describe the length of <code>n</code> spiral loops around a cylinder of height <code>h</code> and circumference <code>c</code> is as follows:</p><!--kg-card-begin: html--><math xmlns="http://www.w3.org/1998/Math/MathML"><mi>l</mi><mo>=</mo><mi>n</mi><mi>*</mi><mroot><mrow><msup><mi>c</mi><mn>2</mn></msup><mo>+</mo><msup><mfenced separators="|"><mfrac><mi>h</mi><mi>n</mi></mfrac></mfenced><mn>2</mn></msup></mrow><mn>2</mn></mroot></math><!--kg-card-end: html--><p>This is pretty neat formula, I recommend taking a look at the link above. Essentially, we solve for the length by using the height and circumference of the cylinder the base and hypotenuse of an isosceles triangle, respectively. If we have multiple loops, they each take up an equal proportion of the height of the cylinder, so we divide the height by the number of loops.</p><p>For example, take a cylinder with three loops:</p><!--kg-card-begin: image--><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://chrisparton.net/content/images/2019/08/image-16.png" class="kg-image" alt="Making The Perfect LED Spiral"><figcaption>Illustration of a cylinder with three loops, which is actually just three diagonal lines on a rectangle</figcaption></img></figure><!--kg-card-end: image--><!--kg-card-begin: image--><figure class="kg-card kg-image-card"><img src="https://chrisparton.net/content/images/2016/01/diagram.jpg" class="kg-image" alt="Making The Perfect LED Spiral"/></figure><!--kg-card-end: image--><p>However, the length of the LED strip is already known (5000mm). This means that we need to change the subject of the equation from <code>l</code> to <code>n</code>, since the number of loops is what we really care about here.</p><p>Now, my high school math skills are quite rusty, so instead I just plugged values into this formula until I arrived at something very close to 5000mm (Sorry, Mr. Clarke). The result ended up being that I could fit 11.72 loops onto each pillar.</p><p>Dividing the height of the pillar by the number of loops yields 164.3, which gives me the gap between each loop at any point in the spiral.</p><h4 id="a-consistent-angle">A Consistent Angle</h4><p>Ok great, I can fit 11.72 loops onto my pillar. This information gave me something to aim for, but it didn't really help me to make my work more accurate. I needed something more. I decided that "something" was a template I could use to guarantee consistent pitch and spacing of the strip:</p><h4 id="templates-make-everything-easier">Templates Make Everything Easier</h4><!--kg-card-begin: image--><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://chrisparton.net/content/images/2019/08/image-17.png" class="kg-image" alt="Making The Perfect LED Spiral"><figcaption>A couple of cardboard templates, based on the above measurements</figcaption></img></figure><!--kg-card-end: image--><p>I made two templates. The first one is a triangle shape, used for the bottom-most loop of the spiral. The dimensions of the template are as follows:</p><ul><li>Width: 395mm</li><li>Height: 151.3mm</li></ul><p>The width is simple enough at 395mm (the circumference of the pillar), but where does the 151.3mm height come from? Well, it's the gap between the spiral loops (as calculated previously), minus the width of the LED strip itself.</p><p>The second template is for the general case, where one spiral needs to sit atop another.</p><p>As with the previous template, the width is simply the circumference of the pillar. The height is 302.6mm, i.e. double the height of the first template. This is because we need a consistent gap, but the spiral itself is getting higher at the same time. Overlaying the templates on the previous flattened cylinder image makes this clearer:</p><!--kg-card-begin: image--><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://chrisparton.net/content/images/2019/08/image-18.png" class="kg-image" alt="Making The Perfect LED Spiral"><figcaption>Templates overlaid on the flattened cylinder</figcaption></img></figure><!--kg-card-end: image--><p>The red triangle is the first template, which has a flat bottom because it's sitting against the bottom of the cylinder. The blue quadrilateral is made up of two triangles with the same dimensions of the first template. All subsequent loops will use this template.</p><h2 id="finally-">Finally...</h2><p>I didn't wrap the pillar in its entirety, because I didn't have time to take it down again, but here are the first two loops of the spiral in all their glory:</p><!--kg-card-begin: image--><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://chrisparton.net/content/images/2019/08/image-19.png" class="kg-image" alt="Making The Perfect LED Spiral"><figcaption>An LED strip wrapped around my pillar, assisted by the cardboard templates</figcaption></img></figure><!--kg-card-end: image--><!--kg-card-begin: html--><script type="text/javascript" src="https://cdn.mathjax.org/mathjax/latest/MathJax.js?config=MML_CHTML"/><!--kg-card-end: html-->]]></content:encoded></item><item><title><![CDATA[Christmas Lights 2015: A First Attempt]]></title><description><![CDATA[This is what made me want to create my own Christmas light display; I wanted to create something that would give people that same feeling.]]></description><link>https://chrisparton.net/christmas-lights-2015-a-first-attempt/</link><guid isPermaLink="false">Ghost__Post__5d5cf1135655c53c345c7f15</guid><category><![CDATA[christmas lights]]></category><category><![CDATA[electronics]]></category><category><![CDATA[raspberry pi]]></category><category><![CDATA[software]]></category><dc:creator><![CDATA[Chris Parton]]></dc:creator><pubDate>Sat, 16 Jan 2016 22:28:00 GMT</pubDate><media:content url="https://chrisparton.net/content/images/2019/08/xmas-lights-2015-cover.jpg" medium="image"/><content:encoded><![CDATA[<img src="https://chrisparton.net/content/images/2019/08/xmas-lights-2015-cover.jpg" alt="Christmas Lights 2015: A First Attempt"/><p>I've always liked Christmas lights, but my house rarely saw itself decorated beyond the bare minimum of the Christmas tree during the festive season. Maybe a few silver baubles and a star on the tree, but never more than that.</p><p>In December 2014, my girlfriend and I went Christmas light hunting and wound up at <a href="http://jamiespages.net/photo-galleries/715-2/">Edgewood Estate</a>, where everybody seems to get into the spirit of Christmas. At the top of the estate, almost every single home was adorned with beautiful lights.</p><p>What struck me about this place was the atmosphere. So many families were out enjoying the lights with their children, and everybody was some combination of happy, excited and awestruck.</p><p>This is what made me want to create my own Christmas light display; I wanted to create something that would give people that same feeling. I also wanted to create something different, using my skills as a software engineer and, more recently, as an electronics hobbyist.</p><h2 id="the-lights">The Lights</h2><p>Here is my first Christmas light attempt (Apologies for the poor audio... and video... and random talking towards the end):</p><!--kg-card-begin: html-->  <iframe src="https://www.youtube.com/embed/YddNPKLF7d0" frameborder="0" allowfullscreen=""/><!--kg-card-end: html--><p>I was planning on blogging about the process I went through to build my lights, but the reality is that I did it all in less than a month, learning as I went. The result of such rushed work was a functional but hacky piece of work. As such, I'll stick to describing the project at a higher level.</p><h2 id="features">Features</h2><p>The Raspberry Pi controls the lights wrapped around each pillar of the house. The other lights are not interactive in any way and have nothing to do with the Pi.</p><p>There are three main features to the pillars:</p><ol><li>Instrument playing</li><li>Song playing</li><li>"Screensaver" effects</li></ol><p>The first two features are interactive, which isn't something I've seen a lot of, even in online videos. There are plenty of insane Christmas light displays (<a href="https://www.youtube.com/watch?v=8zyoMQ4Khts">Exhibit A</a>, <a href="https://www.youtube.com/watch?v=90oZ52M4IC0">Exhibit B</a>, <a href="https://www.youtube.com/watch?v=mejJRgHpdyE">Exhibit C</a>), but for the most part they lack the ability to be influenced by spectators.</p><h4 id="instrument-and-song-playing">Instrument and Song Playing</h4><p>The interactive elements of my Christmas lights are controlled by a little button box I made by etching my own PCB and mounting it in a box:</p><!--kg-card-begin: image--><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://chrisparton.net/content/images/2019/08/image-13.png" class="kg-image" alt="Christmas Lights 2015: A First Attempt"><figcaption>Button box</figcaption></img></figure><!--kg-card-end: image--><p>The coloured buttons are used to control the four house pillars. When a button is pressed, the corresponding pillar lights up and a musical sound is played. The pitch of the instrument increases from left to right. The white button changes the instrument between piano and violin.</p><p>The black button plays the chorus of one of four Christmas songs, and illuminates the pillars in sync with the music. This required using Audacity to find the timings of the notes, and mapping the notes to sheet music found online.</p><p>The screensaver effect is simply a series of alternating patters that are illuminated on the pillars when a button hasn't been pressed for a while.</p><h2 id="how-it-works">How It Works</h2><p>The Christmas lights on the four pillars are regular solar-powered LED strings. I cut the wires between the solar panel and the lights, and essentially ran each set of lights through a transistor. The transistors were then controlled using the GPIO pins on a Raspberry Pi using <a href="http://pi4j.com/">Pi4J</a>:</p><!--kg-card-begin: image--><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://chrisparton.net/content/images/2019/08/image-14.png" class="kg-image" alt="Christmas Lights 2015: A First Attempt"><figcaption>Buttons and lights wired up to a Raspberry Pi</figcaption></img></figure><!--kg-card-end: image--><h2 id="what-s-next">What's Next?</h2><p>I've already started working on my Christmas lights for 2016, and I plan to keep the blog updated as I progress. So, stay tuned!</p>]]></content:encoded></item><item><title><![CDATA[Got Parts?]]></title><description><![CDATA[Today was a good day. I've been ordering electronic components on eBay like crazy over the past few weeks, many of them from China. Today, the first of these arrived.]]></description><link>https://chrisparton.net/got-parts/</link><guid isPermaLink="false">Ghost__Post__5d5cef175655c53c345c7ed1</guid><category><![CDATA[arduino]]></category><category><![CDATA[electronics]]></category><dc:creator><![CDATA[Chris Parton]]></dc:creator><pubDate>Wed, 07 Oct 2015 22:44:00 GMT</pubDate><media:content url="https://chrisparton.net/content/images/2019/08/parts.jpg" medium="image"/><content:encoded><![CDATA[<img src="https://chrisparton.net/content/images/2019/08/parts.jpg" alt="Got Parts?"/><p>Today was a good day. I've been ordering electronic components on eBay like crazy over the past few weeks, many of them from China. Today, the first of these arrived.</p><p>It's amazing how cheap these parts are. Half of me is saying "these parts must be rubbish, they'll all die on you the moment you touch them", and the more optimistic side of me is saying that China simply has vast economies of scale, which drives down the price of mass produced components such as these.</p><p>I don't know how to use many of the components I've bought yet, but I plan to shortly, and I'll be providing updates on the quality of the components as I use them.</p><p>The rest of this article is devoted to the (interesting) parts that arrived, what they do, and how cheap they are compared to Australian prices. I'm going to use Jaycar for Australian pricing comparisons, as that's my go to place when I need something quickly.</p><!--kg-card-begin: hr--><hr><!--kg-card-end: hr--><h3 id="arduino-pro-minis">Arduino Pro Minis</h3><!--kg-card-begin: image--><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://chrisparton.net/content/images/2019/08/image-8.png" class="kg-image" alt="Got Parts?"><figcaption>Arduino Pro Mini</figcaption></img></figure><!--kg-card-end: image--><p>These little guys are a smaller version of the Arduino Uno, which is what I am using (a variant of one, anyway). Like their big brother, the <a href="https://www.arduino.cc/en/Main/ArduinoBoardProMini">Arduino Pro Mini</a> boards sport an ATmega328 microcontroller. Despite their diminutive dimensions, they pack 14 digital pins, 6 of which can be used for PWM.</p><h4 id="caveats">Caveats</h4><p>It's worth noting that neither of these are not official Arduino boards, they're both clones. It's also worth noting that the Australian version linked above has the header pins soldered on, whereas the Chinese board ships with detached header pins. The Chinese versions also need to be programmed with a UART, whereas the Australian one has a micro USB port built in.</p><h3 id="verdict">Verdict</h3><!--kg-card-begin: html--><table>  
  <tbody><tr>
    <th>Country</th>
    <th>Price (Incl. Shipping)</th>
  </tr>
  <tr>
    <td>
<a href="http://www.jaycar.com.au/Kits%2C-Science-%26-Learning/Science-Lab-Equipment/Glassware/DuinoTECH-Nano/p/XC4414">Australia</a>  
    </td>
    <td>$29.95</td>
  </tr>
  <tr>
    <td>
<a href="https://www.ebay.com.au/itm/311437193162">China</a>  
    </td>
    <td>$2.05</td>
  </tr>
  <tr>
    <td colspan="2">
      <b>14.6</b> times cheaper from China, but less user friendly that the Australian counterpart.
    </td>
  </tr>
</tbody></table><!--kg-card-end: html--><!--kg-card-begin: hr--><hr><!--kg-card-end: hr--><h3 id="usb-2-0-uarts-cp2102-">USB 2.0 UARTs (CP2102)</h3><!--kg-card-begin: image--><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://chrisparton.net/content/images/2019/08/image-9.png" class="kg-image" alt="Got Parts?"><figcaption>USB 2.0 UART (CP2102)</figcaption></img></figure><!--kg-card-end: image--><p>As mentioned above, the Chinese Arduino Minis don't have a USB port built in. A UART has to be used to transfer software to the Arduino.</p><!--kg-card-begin: html--><table>  
  <tbody><tr>
    <th>Country</th>
    <th>Price (Incl. Shipping)</th>
  </tr>
  <tr>
    <td>
<a href="http://www.jaycar.com.au/Kits%2C-Science-%26-Learning/Science-Lab-Equipment/Glassware/Arduino-Compatible-USB-to-Serial-Adaptor-Module/p/XC4464">Australia</a>  
    </td>
    <td>$17.95</td>
  </tr>
  <tr>
    <td>
<a href="https://www.ebay.com.au/itm/400565980256">China</a>  
    </td>
    <td>$2.01</td>
  </tr>
  <tr>
    <td colspan="2">
      <b>8.9</b> times cheaper from China, but the Australian model has mini USB.
    </td>
  </tr>
</tbody></table><!--kg-card-end: html--><!--kg-card-begin: hr--><hr><!--kg-card-end: hr--><h3 id="accelerometer-modules-mpu-6050-">Accelerometer Modules (MPU-6050)</h3><!--kg-card-begin: image--><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://chrisparton.net/content/images/2019/08/image-10.png" class="kg-image" alt="Got Parts?"><figcaption>MPU-6050 accelerometer module</figcaption></img></figure><!--kg-card-end: image--><p>These accelerometers work in three dimensions, and are surprisingly cheap in Australia. As seems to be a common theme here, the Australian module has its pins pre-soldered, the Chinese module does not.</p><!--kg-card-begin: html--><table>  
  <tbody><tr>
    <th>Country</th>
    <th>Price (Incl. Shipping)</th>
  </tr>
  <tr>
    <td>
<a href="http://www.jaycar.com.au/Kits%2C-Science-%26-Learning/Electronic-Project-Kits/Computer-%26-Programming/3-Axis-Accelerometer-Module-for-Arduino/p/XC4478">Australia</a>  
    </td>
    <td>$7.95</td>
  </tr>
  <tr>
    <td>
<a href="https://www.ebay.com.au/itm/201002005334">China</a>  
    </td>
    <td>$2.88</td>
  </tr>
  <tr>
    <td colspan="2">
      <b>2.8</b> times cheaper from China, but with detached header pins.
    </td>
  </tr>
</tbody></table><!--kg-card-end: html--><!--kg-card-begin: hr--><hr><!--kg-card-end: hr--><h3 id="joysticks">Joysticks</h3><!--kg-card-begin: image--><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://chrisparton.net/content/images/2019/08/image-11.png" class="kg-image" alt="Got Parts?"><figcaption>Joystick module</figcaption></img></figure><!--kg-card-end: image--><p>These joysticks support your typical up/down/left/right directional input, but can also be pushed in like a button, neat!</p><!--kg-card-begin: html--><table>  
  <tbody><tr>
    <th>Country</th>
    <th>Price (Incl. Shipping)</th>
  </tr>
  <tr>
    <td>
<a href="http://www.jaycar.com.au/Kits%2C-Science-%26-Learning/Science-Lab-Equipment/Specialty-Equipment/Arduino-Compatible-X-and-Y-Axis-Joystick-Module/p/XC4422">Australia</a>  
    </td>
    <td>$4.95</td>
  </tr>
  <tr>
    <td>
<a href="https://www.ebay.com.au/itm/311154090095">China</a>  
    </td>
    <td>$1.80</td>
  </tr>
  <tr>
    <td colspan="2">
      <b>2.8</b> times cheaper from China, no apparent differences at first glance.
    </td>
  </tr>
</tbody></table><!--kg-card-end: html--><!--kg-card-begin: hr--><hr><!--kg-card-end: hr--><h3 id="bluetooth-transceivers">Bluetooth Transceivers</h3><!--kg-card-begin: image--><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://chrisparton.net/content/images/2019/08/image-12.png" class="kg-image" alt="Got Parts?"><figcaption>Bluetooth transceiver</figcaption></img></figure><!--kg-card-end: image--><p><br>I was amazed to discover how cheap these things were, I was expecting to fork out $40+ for something like this. We live in an amazing time where awesome technologies are readily available to the masses.</br></p><!--kg-card-begin: html--><table>  
  <tbody><tr>
    <th>Country</th>
    <th>Price (Incl. Shipping)</th>
  </tr>
  <tr>
    <td>
<a href="http://www.jaycar.com.au/Kits%2C-Science-%26-Learning/Science-Lab-Equipment/Instruments/Arduino-Compatible-Bluetooth-Wireless-Module/p/XC4510">Australia</a>  
    </td>
    <td>$19.95</td>
  </tr>
  <tr>
    <td>
<a href="https://www.ebay.com.au/itm/200924726178">China</a>  
    </td>
    <td>$5.40</td>
  </tr>
  <tr>
    <td colspan="2">
      <b>3.7</b> times cheaper from China, no apparent differences at first glance.
    </td>
  </tr>
</tbody></table><!--kg-card-end: html--><!--kg-card-begin: hr--><hr><!--kg-card-end: hr--><h2 id="time-to-experiment">Time To Experiment</h2><p>Anyway, just wanted to record some of the cool stuff I'm getting. I'm really looking forward to figuring out how to use all of these parts and make something cool with them! I still have loads of other parts on the way too, exciting times ahead!</p></hr></hr></hr></hr></hr></hr>]]></content:encoded></item><item><title><![CDATA[Working With An 8x8 LED Matrix]]></title><description><![CDATA[Having nearly completed the Sparkfun Inventor's Kit guidebook, I went on a purchasing frenzy, acquiring loads of various electronic components online.

Amongst these was a Dual Colour 8x8 LED Matrix.]]></description><link>https://chrisparton.net/working-with-an-8x8-led-matrix/</link><guid isPermaLink="false">Ghost__Post__5d5cecc95655c53c345c7e9c</guid><category><![CDATA[arduino]]></category><category><![CDATA[electronics]]></category><category><![CDATA[led]]></category><dc:creator><![CDATA[Chris Parton]]></dc:creator><pubDate>Mon, 05 Oct 2015 00:46:00 GMT</pubDate><media:content url="https://chrisparton.net/content/images/2019/08/01.jpg" medium="image"/><content:encoded><![CDATA[<img src="https://chrisparton.net/content/images/2019/08/01.jpg" alt="Working With An 8x8 LED Matrix"/><p>Having nearly completed the Sparkfun Inventor's Kit guidebook, I went on a purchasing frenzy, acquiring loads of various electronic components online.</p><p>Amongst these was a <a href="https://littlebirdelectronics.com.au/products/led-matrix-dual-color-small">Dual Colour 8x8 LED Matrix</a>. I chose to work with this first because it looked like something I could tackle with difficulty, which I believe is conducive to <a href="https://en.wikipedia.org/wiki/Flow_(psychology)">Flow</a>. The fact that this was the first item to arrive in the mail also played a part in my decision.</p><p>I set out with a goal to make a scrolling message panel, albeit a small one. I'm pleased to say that I was able to achieve this, and I learned a lot along the way. I hope that by recording my projects in this blog that I'll further solidify my understanding of electrical theory.</p><p>The end result is this:</p><h2 id="step-1-what-are-all-these-pins-for">Step 1: What Are All These Pins For?</h2><p>The <a href="https://cdn.sparkfun.com/datasheets/Components/LED/YSM-1288CR3G2C2.pdf">Datasheet</a> for my LED matrix wasn't exactly clear to me the first time I read it. The pinout leaves a lot to be desired as far as clarity goes:</p><!--kg-card-begin: image--><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://chrisparton.net/content/images/2019/08/image.png" class="kg-image" alt="Working With An 8x8 LED Matrix"><figcaption>LED matrix wiring diagram</figcaption></img></figure><!--kg-card-end: image--><p>So the pinout tells us a few things:</p><ol><li>There are 24 pins in total (8 red anodes, 8 green anodes, 8 common cathodes)</li><li>The pins are in a crazy order.</li></ol><p>What the pinout <em>doesn't</em> tell us, is the physical location of the pins on the matrix. The matrix is perfectly square, with no indicator of which pin is pin 1. So, I had to deduce that through trial and error. I wired up all of the pins, then tested pins until I found the anode and cathode for a corner LED:</p><!--kg-card-begin: image--><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://chrisparton.net/content/images/2019/08/image-1.png" class="kg-image" alt="Working With An 8x8 LED Matrix"><figcaption>The LED matrix connected to a breadboard</figcaption></img></figure><!--kg-card-end: image--><p>So, we now know that two consecutive pins can be used to power a corner LED. Given the assumption that the pins are ordered sequentially on the LED matrix, those pins can only be the following:</p><ul><li>Pins 2 and 3</li><li>Pins 10 and 11</li><li>Pins 14 and 15</li><li>Pins 22 and 23</li></ul><p>By process of elimination, it turns out that none of the options are possible. The most correct option on that list is that the circuit is using pins 22 and 23. The only incorrect part is that the pinout states that pin 23 is connected to the anode for a <em>green</em> LED. It turns out that the datasheet is incorrect, the black anodes actually depict <em>red</em> LEDs (lesson learned: never take a datasheet for gospel).</p><p>Armed with this knowledge, it was possible to figure out what all of the other pins are for. The image below is using the same orientation as the image previous image:</p><!--kg-card-begin: image--><figure class="kg-card kg-image-card kg-width-full kg-card-hascaption"><img src="https://chrisparton.net/content/images/2019/08/image-2.png" class="kg-image" alt="Working With An 8x8 LED Matrix"><figcaption>Pin diagram for the LED matrix</figcaption></img></figure><!--kg-card-end: image--><h2 id="step-2-wiring-up">Step 2: Wiring Up</h2><p>Now that we know what on earth the pins are for, this step is pretty easy, if not a bit tedious. Since I'm using the <a href="https://www.sparkfun.com/products/12757">Sparkfun Redboard</a> (equivalent to the Arduino Uno), I only have 13 digital out pins. Obviously, this isn't enough to accommodate all of the pins on the matrix.</p><p>I decided to compromise and only use the red LEDs, which means I still need 16 pins. Fortunately, the analog in pins can also be used as digital output pins, so the final wiring looks like this:</p><!--kg-card-begin: image--><figure class="kg-card kg-image-card"><img src="https://chrisparton.net/content/images/2019/08/image-3.png" class="kg-image" alt="Working With An 8x8 LED Matrix"/></figure><!--kg-card-end: image--><p>As a convention, I used red and orange cables to connect to the red LED anodes, and green and blue cables to connect to the common cathodes. I placed 330Ω resistors in series with each anode connection (more on that later). The connections are as follows:</p><!--kg-card-begin: html--><table style="table-layout: fixed ; width: auto">  
  <tbody><tr>
    <th>Arduino Pin</th>
    <th>Matrix Pin</th>
    <th>Pin Type</th>
  </tr>
  <tr>
    <td>2</td>
    <td>11</td>
    <td>Red Anode</td>
  </tr>
  <tr>
    <td>3</td>
    <td>8</td>
    <td>Red Anode</td>
  </tr>
  <tr>
    <td>4</td>
    <td>5</td>
    <td>Red Anode</td>
  </tr>
  <tr>
    <td>5</td>
    <td>2</td>
    <td>Red Anode</td>
  </tr>
  <tr>
    <td>6</td>
    <td>14</td>
    <td>Red Anode</td>
  </tr>
  <tr>
    <td>7</td>
    <td>17</td>
    <td>Red Anode</td>
  </tr>
  <tr>
    <td>8</td>
    <td>20</td>
    <td>Red Anode</td>
  </tr>
  <tr>
    <td>9</td>
    <td>23</td>
    <td>Red Anode</td>
  </tr>
  <tr>
    <td>11</td>
    <td>13</td>
    <td>Common Cathode</td>
  </tr>
  <tr>
    <td>12</td>
    <td>10</td>
    <td>Common Cathode</td>
  </tr>
  <tr>
    <td>A0</td>
    <td>6</td>
    <td>Common Cathode</td>
  </tr>
  <tr>
    <td>A1</td>
    <td>3</td>
    <td>Common Cathode</td>
  </tr>
  <tr>
    <td>A2</td>
    <td>13</td>
    <td>Common Cathode</td>
  </tr>
  <tr>
    <td>A3</td>
    <td>16</td>
    <td>Common Cathode</td>
  </tr>
  <tr>
    <td>A4</td>
    <td>19</td>
    <td>Common Cathode</td>
  </tr>
  <tr>
    <td>A5</td>
    <td>22</td>
    <td>Common Cathode</td>
  </tr>
</tbody></table><!--kg-card-end: html--><h2 id="step-3-making-it-do-stuff">Step 3: Making It Do Stuff</h2><p>One hard truth I was hit with pretty early on is that making a legible picture show up on this thing wasn't going to be as simple as I had hoped.</p><p>There are 16 pins wired up, each with two possible states: On or Off. This equates to 2<sup>16</sup> possible voltage states that the pins can be in. However, there are 64 LEDs wired up (disregarding the green LEDs), which equates to 2<sup>64</sup> possible LED states. This means that it's impossible to make any pattern of LEDs light up at a given time (it's a violation of the <a href="https://en.wikipedia.org/wiki/Pigeonhole_principle">Pigeonhole Principle</a>).</p><p>My plan instead, then, was to only ever display one pixel at a time. That might sound like a pretty silly way to make an image scroller, but this actually isn't too dissimilar to the way old-fashioned CRT monitors work.</p><p>By turning single LEDs on for fractions of a second and repeating, we can trick the human eye into perceiving a still image. By feeding multiple images into this process, we can make it look like an image is moving.</p><p>The other advantage of this approach is that current will only be drawn for 0 or 1 LED at any given instance. This means that standard resistors can be used. If we were lighting up multiple pixels in a given column at the same time, a more sophisticated method would have to be used (and with my current skillset, I don't know what that would be).</p><h2 id="step-4-the-code">Step 4: The Code</h2><p>I've included comments in the code below to act as an explanation:</p><!--kg-card-begin: code--><pre><code class="language-language-cpp">// The number of LEDs in the matrix in one dimension.
#define LED_MATRIX_SIZE 8

// The width of each letter when displayed on the matrix, including one column for
// spacing between letters.
#define LETTER_WIDTH 6
#define REPAINT_COUNT 50

// Red pins, in left-to-right order.
// Physical pin attachments to LED matrix: 11, 8, 5, 2, 14, 17, 20, 23.
const byte RED_PINS[LED_MATRIX_SIZE] = {2, 3, 4, 5, 6, 7, 8, 9};

// Ground pins, in top-to-bottom order (skip pin 13 to avoid using the integrated LED).
// Physical pin attachments to LED matrix: 22, 19, 16, 13, 3, 6, 9, 12.
const byte GROUND_PINS[LED_MATRIX_SIZE] = {A5, A4, A3, A2, A1, A0, 12, 11};

/* Binary representation of each letter, where 1 indicates an "On" pixel and 0 indicates
 * "Off", e.g. the letter "A" is defined as 0b0111010001111111000110001. Split into 5
 * rows and columns, that binary value looks like:
 * 0 1 1 1 0
 * 1 0 0 0 1
 * 1 1 1 1 1
 * 1 0 0 0 1
 * 1 0 0 0 1
 * 
 * Notice that the "1" pixels form a pixel representation of the letter "A". The same holds
 * true for the other letters defined below.
 */
const long LETTERS[] = {
  0b0111010001111111000110001, // 'A'
  0b1111010001111101000111110, // 'B'
  0b0111010001100001000101110, // 'C'
  0b1111010001100011000111110, // 'D'
  0b1111110000111101000011111, // 'E'
  0b1111110000111101000010000, // 'F'
  0b0111010000101111001001110, // 'G'
  0b1000110001111111000110001, // 'H'
  0b1111100100001000010011111, // 'I'
  0b0011100010000101001001100, // 'J'
  0b1000110010111001001010001, // 'K'
  0b1000010000100001000011111, // 'L'
  0b0101010101101011000110001, // 'M'
  0b1000111001101011001110001, // 'N'
  0b0111010001100011000101110, // 'O'
  0b1111010001111101000010000, // 'P'
  0b0110010010101101001001101, // 'Q'
  0b1111010001111101001010001, // 'R'
  0b0111110000011100000111110, // 'S'
  0b1111100100001000010000100, // 'T'
  0b1000110001100011000101110, // 'U'
  0b1000110001100010101000100, // 'V'
  0b1000110001101011101110001, // 'W'
  0b1000101010001000101010001, // 'X'
  0b1000101010001000010000100, // 'Y'
  0b1111100010001000100011111  // 'Z'
};

// Set all pins to output, so we can change the potential difference between
// positive and negative pins. We also default the cathode pins to HIGH, which creates
// a negative potential difference that results in no LEDs turning on.
void setup() {
  for (byte i = 0; i &lt; LED_MATRIX_SIZE; ++i) {
    byte anodePin = RED_PINS[i];
    pinMode(anodePin, OUTPUT);
    
    byte groundPin = GROUND_PINS[i];
    pinMode(groundPin, OUTPUT);

    digitalWrite(GROUND_PINS[i], HIGH);
  }
}

void loop() {
  renderMessage();
}

void renderMessage() {
  // The message to display on the screen, with some space for padding
  // when displaying the message.
  char message[] = " I AM ALIVE ";

  int messageIndex = 0;
  char messageChar = message[messageIndex];

  while (messageChar != '\0') {
    char nextChar = message[messageIndex + 1];
    if (nextChar == '\0') {
      nextChar = ' ';
    }

    renderFrame(messageChar, nextChar);

    ++messageIndex;
    messageChar = message[messageIndex]; 
  }
}

// 2 characters are always present on the screen. This function handles the drawing of those two
// characters in such a way that they scroll off the screen to the left. As soon as the first
// character is invisible, the function exits and is called again with a new secondChar,
// while the previous secondChar is passed in as the new firstChar.
void renderFrame(char firstChar, char secondChar) {
  for (byte i = 0; i &lt; LETTER_WIDTH; ++i) {
    for (byte j = 0; j &lt; REPAINT_COUNT; ++j) {
      boolean frame[LED_MATRIX_SIZE][LED_MATRIX_SIZE] = {};
      
      renderCharacter(frame, firstChar, -i);
      renderCharacter(frame, secondChar, 6 - i);

      renderFrame(frame);
      delay(1);
    }
  }
}

// Draws a pixel representation of a single letter to the frame buffer.
void renderCharacter(boolean frame[LED_MATRIX_SIZE][LED_MATRIX_SIZE], char character, int offset) {
  for (int row = 0; row &lt; 5; ++row) {
    for (int col = 0; col &lt; 5; ++col) {
      int bitCount = (row * 5) + col;

      long displayCharacter;
      if (character == ' ') {
        displayCharacter = 0; // All spaces.
      } else {
        displayCharacter = LETTERS[character - 'A'];
      }

      // This is where the magic happens. The left shift and binary AND operations are used
      // together to effectively iterate over each bit of the character as defined in the
      // LETTERS array. This results in a 1 or 0, which is used to dictate whether a pixel
      // should be turned on or off for a given point.
      boolean isOn = displayCharacter &amp; (1L &lt;&lt; (24 - bitCount));

      // Only render the visible parts of the letter (part of the letter is likely to have
      // scrolled off the screen.
      int offsetCol = col + offset;
      if (offsetCol &gt;= 0 &amp;&amp; offsetCol &lt; LED_MATRIX_SIZE) {
        frame[row][offsetCol] = isOn;
      }
    }
  }
}

// Converts the in-memory frame buffer into an actual image. This is achieved by rapidly
// turning on single LEDs that correspond to "true" values in the frame buffer, then turning
// them off after a short delay.
// A single pixel is turned on by bringing the anode pin HIGH and the corresponding cathode pin
// LOW. Remember that all cathodes were brought HIGH earlier in the setup() function.
void renderFrame(boolean frame[LED_MATRIX_SIZE][LED_MATRIX_SIZE]) {
  for (byte row = 0; row &lt; LED_MATRIX_SIZE; ++row) {
    for (byte col = 0; col &lt; LED_MATRIX_SIZE; ++col) {
        // Turn pixel on or off as required.
        digitalWrite(RED_PINS[row], frame[row][col]);
        digitalWrite(GROUND_PINS[col], !frame[row][col]);

        // Turn pixel back off.
        digitalWrite(RED_PINS[row], LOW);
        digitalWrite(GROUND_PINS[col], HIGH);
    }
  }
}
</code></pre><!--kg-card-end: code--><h2 id="that-s-all-there-is-to-it">That's All There Is To It</h2><p>If you've made it to the end of this article, thanks for your patience. This is my first blog post of substance, and I'd love to hear any feedback or constructive criticism in the comments section below. Cheers!</p>]]></content:encoded></item><item><title><![CDATA[A Blog Is Born]]></title><description><![CDATA[Hi there, nice to meet you. This is my first ever blog post.]]></description><link>https://chrisparton.net/a-blog-is-born/</link><guid isPermaLink="false">Ghost__Post__5d5ce55d5655c53c345c7e83</guid><category><![CDATA[electronics]]></category><category><![CDATA[software]]></category><dc:creator><![CDATA[Chris Parton]]></dc:creator><pubDate>Tue, 29 Sep 2015 02:29:00 GMT</pubDate><media:content url="https://chrisparton.net/content/images/2019/08/Profile-Photo-1.jpg" medium="image"/><content:encoded><![CDATA[<img src="https://chrisparton.net/content/images/2019/08/Profile-Photo-1.jpg" alt="A Blog Is Born"/><p>Hi there, nice to meet you.</p><p>This is my first ever blog post. I've been meaning to do this for quite some time, but I've struggled with motivation and ideas for content.</p><p>I'm a software engineer by trade, but recently I've been getting into electronics. I picked up the <a href="https://www.sparkfun.com/products/12060">Sparkfun Inventor's Kit</a> and now I'm hooked. I'm kind of exploiting my newfound motivation for Making to kickstart my blog.</p><p>My plans for the blog aren't set in stone yet, but content will include:</p><ul><li>Electronics projects, which will hopefully increase in complexity and interestingness (that's a real word, I googled it) as I learn more.</li><li>Programming tidbits and grievances.</li><li>Reviews of software and tools that I use for the above.</li></ul><p>Anyway, this is it for now. I already have something to write about for my first electronics blog post, so exciting times ahead!</p><p>Cheers,<br>Chris</br></p>]]></content:encoded></item></channel></rss>