The GPS error experiment

GPS error isn't random, particularly for cost-optimized receivers like the ones in cell phones. This writeup involves heading up to the roof to build a horizon profile, then tracking each satellite over time to match observed inaccuracies.

The laundry room datacenter

eBay makes it possible to build a very powerful home computing setup on a small budget. This writeup covers some of the issues I ran into building a datacenter from used rackmount equipment.

ni for audio

ni includes all the basic tools required to stream compressed audio into a binary reader, export samples, and stream batches of those into NumPy for windowed FFT processing. Those can be visualized directly in the web UI.

Saying "ni" to big data

I wanted a data analysis tool that leveraged UNIX process pipelines, could install itself using an SSH connection, and that could visualize arbitrarily large data and remain responsive. So far I'm quite enamored with the result.

Sonar positioning for cell phones

You've got a dozen cell phones from ebay, and you want each one to continuously know its 3D location down to about a centimeter. This project goes through a sonar transmitter design, how to code it on an Arduino, and the engineering required to optimize the carrier frequencies for maximum accuracy.

A quick JIT compiler tutorial

A lot of people assume that JIT compilers are complicated, but the core mechanics of writing one are surprisingly straightforward. I wrote up a short tutorial that covers the basics in C.

Self-modifying Perl scripts: objects for your filesystem

This was a terrible idea that ended up being really cool. I used a bunch of these objects as data containers for various projects before finally switching to a more traditional development style years later.

Building an indoor bouldering wall

I missed the climbing wall at Google, so I got a bunch of lumber and built one in the living room.

Deriving camera angles from ISS time-lapse videos

A hackathon project with Chris Bleakley that involved tracking the satellite's position, correcting for drift, and using the Factual dataset to match bright spots with real-world places to figure out the exact camera angles. Writeup pending...

BrowserPower: using browsers as compute nodes

This was years ago, but still a cool project and simple to implement. It's based around a node.js server that sends work to clients, collects the results, and returns them to the job-runner page. May be of interest if you need to write a raytracer in Javascript for some reason.

How geohashes work: a fast encoder/decoder

A lot of the overhead of geohash encoding can be eliminated using Morton encoding and some float/int casts.

Driving an alternator as a motor

Have you ever had too many alternators lying around? Me neither, but I did notice that many were way cheaper than corresponding brushless motors for the wattage ratings. So I hooked up a relay H-bridge to a very unhappy bench power supply to build a synchronous motor driver. Writeup and solid-state driver pending...

A better "cd" for bash

sshfs, encfs, and FUSE in general are great tools, but managing the mountpoints is more trouble than it could be. I wrote a new cd function for bash that does this for you, and supports custom overloading so you can add your own extensions.

"Uncommon uses for angle grinders," part 1

Actually, I suspect a lot of unwise people use angle grinders this way, but I was pretty stoked not to have to shell out for a lathe.

Writing a JIT in machine code

This is an old project, but a lot of fun. I was interested in writing a simple concatenative language based on Joy that had enough expressiveness to build up to something like Lisp or Scheme. On a minimalistic streak, I decided to write it in x86-64 machine code using a not-quite-assembler I had written in Perl. The reader has a bug that prevents it from working, but the design is workable and does some interesting stuff like using machine code to represent data structures; that way eval is simply a jump instruction.

Cheloniidae: overengineered 3D turtle graphics in Java

This started as a weekend replacement for a proprietary library about ten years ago, but ended up accumulating a bunch of interesting features like turtle forking, 3D coordinate systems, triangle rendering, etc.

Fixing the Gould DSO 610

I found it on eBay for $35, untested and "probably not working." It turned out to be in unexpectedly good shape: two channels worked normally and the other two were partially working but had some major attenuation and distortion going on. The problem was a shorted surface-mount capacitor that fried one of the diodes on the acquisition board. After that fix it works flawlessly. (More details pending...)

Fast indirect sorting in Java

An interesting way to sort a list of objects by a list of doubles, without using any custom comparators or value boxing. A good hack to know about if you're writing performance-sensitive code.

The Octopipe: the world's ugliest fireplace heat exchanger

Wood stoves may be elegant, but they're a lot more expensive than iron pipe, sheet metal, and a mini Shop-Vac. They're also a lot quieter. Writeup pending...

Javascript in ten minutes

The now-infamous guide I wrote years ago, and which I'm sure is no longer current. I can't vouch for its quality or brevity, but it's my most popular Github project to date.

Caterwaul: Lisp-style macros in Javascript

Javascript functions provide a .toString() method that returns their source code in string form. Caterwaul uses this to parse, transform, and recompile your code, adding arbitrary Lisp-style macros as well as its own standard library.

An awful two-channel, 12-bit function generator

This was one of my first Arduino projects. It used an R2R DAC and split each of three port registers across both channels so there would be no timing difference. That's where its virtues ended though; because you can only write to one port register per cycle, the signal contained 125ns distortions and it could only emit about 1MS/s. It also had clipping issues due to the op-amp voltage margins. Postmortem pending...

Using the Fourier transform for data forensics

This one completely surprised me. I was looking for the exact spacing being applied to some data and started seeing all kinds of interesting stuff in the high-frequency range: spikes at 217 and 218 indicating single-precision truncation, powers of ten indicating digit truncation, and in another (not yet published) analysis, 1/60 and 1/3600 from truncated DMS encoding.

DIY table saw sled

Not the best design, but cheap and precise after some tuning. I used a circle saw and router to cut the plywood, then 3/16" aluminum bar stock for the guides. Writeup pending...

Quickdupe: fast duplicate file detection

I used to use sha256sum on every file to find duplicates, but it turns out to be a very slow approach for most real-world filesystems. Quickdupe uses the fastest accurate algorithm I know of, in many cases avoiding file reads altogether.

Evaporative control with an Arduino

New Mexico has a desert climate that makes it possible to use evaporative, rather than refrigerated, air conditioning. The energy efficiency is awesome, but the control system leaves something to be desired: because it's continuous-duty during the daytime, most houses just have wall switches instead of a thermostat.

I decided to solve this by rewiring it to a relay board and using a wireless Arduino controller. Joyce then wrote timer logic into a web UI so we could program it. Writeup and code pending...

Clojure in Bash (including GC)

The big idea behind this project was to replace things like Hadoop with something hosted in bash, using SSH and other UNIX tools to process big data in a distributed way. Predictably, it never reached that level of utility; but I think this is still the only concurrent garbage collector written in bash.

Conky compiler: absolute positioning

Conky is great, but by default it lays everything out using text flow rather than absolute coordinates. I wrote a Perl script to let you insert absolute and relative offsets into your conkyrc to get arbitrary positioning for each element.

The Safety Ladder

Evaporative coolers require a lot of maintenance, and I like having roof access in general. So rather than dragging out the regular ladder, I built one onto the side of the house using some old deck wood and carriage bolts. Nothing is permanently mounted; the top is held in place with a wooden lever clamp and the weight is transferred straight to the ground. Writeup pending...

Right-handed prompt indicators for bash

zsh users are understandably fond of right-hand prompt indicators, but it turns out that you can do the same thing in bash with a bit of escape character trickery.