Wednesday, July 11, 2018

Nixie Tube Clock

My brother bought me some nixie tubes for my birthday a while back. They sat in my desk drawer for a long time, until I finally got around to building this clock.

The nixie tubes are driven by four SN74141 IC's and a 180v power supply, hanging off the back:

I control it with an Arduino and a DS1307 RTC module, keeping battery backup. The button on the side can adjust minutes or hours with short or long presses.

This was the first time using 3D printing in a custom electronics project. I sketched the model using Blender. The PCB's slide into their respective sleds, and a front gate locks the main PCB in place. The enclosure is designed to be replaceable.

Soldering this beast took a few weeks. I'm going to try printing my own PCB next time.

I resurrected my old Printrbot Simple from five years ago. With a ton of tweaking and calibration, I was able to print the rear sled and bracket, but it was unable to finish the full 10cm base.
So, I finished the base and front gate using an Ultimaker from work. What a beaut

Code and enclosure model:
Help from:

Saturday, July 15, 2017

Live Sectional Map

A polished and well-crafted variant of this project was featured on HomebuiltHELP's Tip of the Week

The Live Sectional Map is a small cylinder showing the aeronautical sectional chart around Sea-Tac. Seven airports are illuminated with colored LEDs. When the cylinder is plugged in, it will download the METARs for these airports every minute, and update the color for each airport depending on the conditions.

Just like ForeFlight, VFR is green, MVFR is blue, and IFR is red. LIFR flashes red.

The map was super glued around an old Quaker oats can. I wrapped it in rubber bands for a day to let the glue settle.

I drilled holes for each airport and hot-glued common cathode RGB LEDs to each airport.

After experimenting with an Arduino like I did with Thinking Man, I decided Arduinos are a pain to connect to WiFi, and Raspberry Pis are much more robust. I SSH'ed onto a RPi running Raspbian on headless mode while developing. The RPi's GPIO ports control each LED anode.

I used a simple GPIO breakout along with female-female jumpers to connect each LED. The cathodes were strung along this awkward extension, shown below. I used a 200 ohm resistor on ground for the whole circuit. Later I found out the red LEDs ate a lot more power, and would dim rival blue LEDs when in use. Rather than put 21 resistors on all of these anodes, I just balanced the color using pulsewidth modulation through the RPi.GPIO library. Code:

Sunday, February 28, 2016

This project is as awesome as it is dumb. A website where you can order a robot to flip a coin for you, and watch the outcome on streaming video.

Note that mobile users probably won't be able to see the live video.

I used a combination of ServoBlaster, VLC, and good old CGI + Bash to make this work.

The robot, sitting on my kitchen counter
View from the camera, which is live streamed to the website

Powered by a Raspberry Pi

Sunday, February 7, 2016

Alexa-Connected Speakers

This is a follow-up to my last post, Internet Connected Speakers

The speaker-controlling widget
I finally got around to building an Alexa skill to control my speakers. Now I can control my TV's volume hands-free with my Amazon Echo, and the commercial skip feature works great.

All code hosted on Bitbucket here

If you'd like to build your own:

1. Make the IR blaster device as explained in the last post.

2. Program it using the sketch in my Bitbucket repository. You will have to modify the WiFi SSID and password variables.

3. Set up your home router so that your IR blasting server is hosted on a port other than 80.

4. Sign up for an AWS account and create an AWS Lambda function to control your speakers. The Lambda code is also in my repository; you will have to modify the host and port variables. Use "Alexa Skills Kit" as the event source. Note the ARN of the lambda that you create.

5. Set up an Alexa skill using the Alexa Skills Getting Started Guide. Creating your own Alexa skill requires many steps. If you follow the getting started guide, you will set up an example skill. You can replace the intents and hints from the example with those hosted in my git repository. Then, use the Lambda ARN as the skill endpoint.

Note that this project is terribly insecure. If someone knew my home IP address, they could very easily gain control over my speakers. The ESP8266 is currently limited in that it does not support TLS when hosting a server. If TLS were supported, the device could use a secret password only known to the Lambda invoking the function. But without TLS, that password would be transmitted publicly. Until secure servers are supported on the ESP8266, I can't recommend this project for anything serious.

Sunday, December 13, 2015

Internet-Connected Speakers

Finished product

When I watch TV, I find certain commercials to be very annoying. Usually I try to mute them myself before the rage sets in. Unfortunately I can't always find the remote, and sometimes I forget to un-mute the TV and I'll miss actual programming.

Jeep commercials are particularly bad for me

Ideally, I could train a system to pick up on sounds from certain commercials and mute them automatically. I think this is too large of a scope for me and I would lose interest. The next best thing is to have an Alexa skill to control my TV. (If you're not familiar with Alexa skills, they are essentially apps you can install on your Amazon Echo.) "Alexa, mute this commercial," might mute the speakers for exactly 30 seconds, solving both the can't-find-the-remote problem and the accidentally-muted-real-programming problem. If I built this skill, I would also be able to control any aspect of my speakers or TV, like "Alexa, channel up."

My goal was to build an IR blaster (basically a smart remote) that would be connected to my Amazon Echo. In this post I'll show how the IR blaster is assembled and programmed, and later on I'll show the Alexa skill to control it.

The heart of the project is an ESP8266 chip in an ESP-01 breakout.
We'll program this chip to host a webserver and control the infrared LED, which will control the speakers.

Materials needed:
  • ESP8266 controller with ESP-01 breakout
  • USB cable
  • USB-B breakout (or any USB breakout)
  • AMS1117 3.3v voltage regulator
  • 22uF and 10 uF capacitors (for the voltage regulator)
  • 10k ohm and 200 ohm resistors
  • On/off switch (optional)
  • Infrared LED
  • Jumper wires and solder
  • Small PCB
  • 2N2222 transistor
If you're keeping track, the most expensive thing on here is the ESP-8266, which retails for about $7. After it's all said and done, this internet-connected IR blaster can easily be put together for about $20, and could be mass produced for far less.

Tools needed:
  • Dremel for shaping the PCB
  • FTDI controller to program the ESP chip
  • Soldering iron
  • Benchtop power supply and breadboard (Recommended for prototyping)
  • Regular LED for prototyping
First, I wanted to re-flash my ESP chip to get a simple LED blinking. Alasdair Allan has an awesome article demonstrating how to flash your ESP8266 chip using an FTDI controller. You can follow these instructions to get an LED blinking.

When you're comfortable programming the ESP-8266 chip, you can start experimenting with Mark Szabo's IRRemoteESP8266 Arduino library. Specifically, I worked from the IRServer example. I had to make three important changes:

1. For this build, I used the RX pin to control the LED. There is a specific reason why I chose not to use GPIO. Therefore you need to intitialize the IRsend object like so:

  IRsend irsend(3);

2. Using the MDNSResponder object caused my program to run into heap overflows very quickly, so I used static routing instead. I commented out all mention of MDNSResponder.

3. I added the codes for the Audioengine A5+ powered speakers. I discovered them listed here, but not in the format we need. I had to translate them to raw NEC hex codes by hand. If you've stumbled here from Google looking for A5+ codes, here they are:
  Power = 0xBF807F = 12550271
  Mute = 0xBFC03F = 12566591
  Vol- = 0xBFE01F = 12574751
  Vol+ = 0xBF906F = 12554351

Now let's verify that the webserver is running and functional. You'll need to discover the IP address of the IR blaster. You can do this by setting it yourself with static routing, or looking at your router's DHCP table, or through a separate sketch that outputs the IP address to serial. If you go to this IP address in your browser, you should see the landing page from Mark's example.

To verify that the blaster is blasting, let's wire up the circuit on a breadboard.

The ESP-01 breakout for reference
Circuit diagram for the IR blaster.
After uploading the sketch, you can keep the power and CH_PD hooked up to your FTDI controller. Connect the transistor, resistors and a regular (non-IR) LED according to the circuit above. Opening the IRServer website and sending commands should make your LED flash.

After verifying that the server works, you can prototype the rest of the circuit, including the voltage regulator and USB power, on a breadboard.

Here is my server on PCB:
IR blaster partially disassembled

Underside of the server

The IR blaster connected to my speakers
Luckily my Audioengine A5+ speakers had a built-in USB port, so I simply connected my server there and taped it to the side of the speakers. Using a modified IRServer example, I can send volume control and mute commands over the internet. With these ingredients, an Alexa sketch is not too far away.

Tuesday, August 25, 2015

The Pendulum Clock

If you've ever rode the Link Light Rail in Seattle to the airport, you may have glanced out of the window while traveling through a tunnel and seen playing cards illuminated on the walls. These images are not made from two dimensional screens. Each display is just a row of lights that changes rapidly as the train drives by, giving the illusion of a two-dimensional picture.

The University Street station also has rows of lights blinking on the walls on the mezzanine floor. I always point out the artwork whenever I walk through the station with someone. At first glance the displays just appear to be red lines, but if you move your eyes rapidly from side to side, there are images hidden in how the lights blink.

That was the inspiration for the Pendulum Clock.

Hint: Stare at the cord; don't follow the pendulum with your eyes.

You might not see it at first, but it is showing an analog clock face that reads 2:40. Usually it takes a couple swings to see the picture. Once you see it, it becomes very easy to read the time.

The Pendulum Clock has a row of 64 white LEDs that change based on the position of the pendulum. I've used it to display an analog clock face, but it can be used to display any 2D image. The motion of the clock is not powered; you have to manually push the pendulum to one side to start it moving.

It's powered by a simple Arduino Uno, a DS1307 RTC for keeping time, a MAX7219 LED controller, and a bad ass rotary encoder. The case is a Hammond box, which fit all of the components with just the right amount of room. The face is a 4"x24" piece of basswood.

Finished product

I knew I wanted to display a 2D image using a 1D set of LEDs. I had a few different designs laid out: a rotating set of LEDs driven by a motor, or a row of LEDs that would move laterally. I finally decided on the pendulum because motor-driven displays have been done before, and I wanted to make something new.

There were a couple challenges here that thankfully were easy to overcome. At first I looked at NeoPixels for the line of LEDs. This probably wouldn't work because NeoPixels introduce a small delay as the pixel is propagated down the line. I didn't know if the MAX7219 controller would be fast enough to drive the LEDs; if there was too much of a delay, the image would be skewed or mangled. I started with the MAX7219. I also bought some shift registers just in case; the shift registers would be fast enough but would require more connections.

First I created the LED display.  Prefabricated 8x8 LED matrices were easy to find, but I could not find 1x64 matrices that used the digit/segment wiring scheme that the MAX7219 expects. With the MAX7219 powering a numeric display, a set of LEDs in one digit share a common cathode, and the Nth segment of every digit share a common anode. For the 8x8 matrix, each row shares a common cathode and each column shares a common anode. For my 1x64 matrix, every 8 LEDs share a cathode, while every N%8 LED shares a common anode.

To create the rows, I purchased three Breadboard-style PCBs from Adafruit and cut them in half down the center. I soldered an LED to every two rows. The rails running down the board would be used for cathodes. I cut the rails at every 16th row and soldered the cathodes to the rails.

I then started using some enamel-coated magnet wire to connect the anodes. With 64 connections this was the most time consuming part. Four of the "columns" were connected on the LEDs contacts and four were connected through the breadboard:

Connected the first few anodes

All of the anodes connected and Kragled to the wooden clock face

After all of the LEDs were strung together, I used some more magnet wire to connect the digits and segments to the MAX7219 breakout. I hooked up an Arduino, found some 8x8 example code, and got a pixel to bounce back and forth on the display. Sweet!

Now I needed a way to find the position of the pendulum. If I had used a stepper motor, this would have been trivial. I was thinking of breaking IR beams at the top of the swing, and interpolating the position through the middle. This would become less reliable as the pendulum slowed down. I discovered that a rotary encoder would be perfect for this.

Mounting the rotary encoder to the enclosure.

The encoder, Arduino and RTC mounted in the enclosure.

While the spec says the maximum load is 3N, the encoder seems to support the pendulum just fine with no noticeable resistance. The encoder came with a plastic nut that allowed me to attach a bolt for the clock face.

It's a tight fit, but it works!

You'll notice that the clock draws a perfect circle. In the arduino sketch, I have routines that draw the clock face and clock hands on the cartesian plane. Every time a pixel is set on the cartesian plane, it is transformed to polar coordinates and stored in a 2D array. As the pendulum rotates, the encoder triggers interrupts on the Arduino and updates a counter. The loop() routine updates the display based on the counter position, which is one dimension in the array. When the pendulum stops moving, the array is refreshed with the latest time, and the home position is recalibrated.

Anyway, I hope you enjoyed this project! Drop me a message if you'd like any more information.

Sunday, May 31, 2015

The Color of Umphrey's

If you've ever seen an Umphrey's McGee concert, you might notice that the light show is something else.  Jefferson Waful (the lighting guy) uses bright, complementary colors choreographed to the music.

Generally, there are certain parts of the songs that always have their own lighting.  For example, for the short satanic vocals in Resolution, the lights will always switch to dark red, then back to blue or green when they're over.

I wrote a program to scan Umphrey's videos and pick out the 1-3 most prominent colors.  Another script draws these data left from right, where each pixel is half a second of rock and roll.  The resulting diagram is a visual thumbprint of an Umphrey's song.  Here are two samples from All Good 2009:

40's Theme

The Floor

I'm currently scanning the rest of the All Good concert.  I plan to arrange a show poster with a thumbprint from each song.

The scanner uses JavaCV to interpret the video data.  I created a histogram of the colors in each frame.  I calculate the HSV coordinates for each pixel, and I tally the saturation, value and pixel count by the pixels' hues.  I only count pixels that are above a minimum value.  From the histogram, I pick out the most prominent color by finding the hues with the highest pixel counts.  I use the average recorded value and max out the saturation.

Then I use Python Imaging Library to plot the data in an image file.

Right now I'm really only plotting some parts of the true colors.  I maximize saturation, making the diagram as colorful as possible.  However, that removes white lights (as the color white has zero saturation).  So white lights can turn out yellow or brown on this plot  I'm still experimenting with the algorithm to see if I can capture white/grey lighting as well.

I'm pretty excited about how this is turning out.  I think I will place the colors as highlights on top of a black and white photo of the show.  Stay tuned for more updates as I arrange the poster.  If you have any requests for shows, please let me know.