SPI on FT232H

In a few days, my new OLED display should arrive in the post. In the meantime I’ve been brushing up on my understanding of SPI to control it. Rather than test via an embedded device, I’d like to confirm it’s working OK by driving it directly from my PC. I bought an FT232H board a while ago, so this is a good opportunity to try it out.


Household 3D Print – Bath Plug

My bath has – well, had – a push-action bath which would seal when pushed down and unseal when pushed again. Over-engineered crap like this is bugbear of mine. An old-fashioned plug or tap is intuitive to use, and very grabbable in a Gaudi-like way. My experience of modern ‘bathroom innovation’ is just bad UX. The prime example of this was a tap in a restaurant bathroom which had a plain cube on top. Should I turn it or push it? Nope, I tilt it. Naturally.

These designs just add entropy to the universe; they fuel consumer insanity and replace old wisdoms with trends. Case in point, the push-plug in my bathroom was a nightmare to clean and eventually broke off. My bachelor solution for the past week was to simply tape over the hole with gaffa, which works surprisingly well!

Today I thought it would be a good bit micro-DIY to make a new one and test my 3D printing skills. I cracked open a Jupyter notebook and wrote the following.

from solid import *
import math
import viewscad

def make_plug(
    top_diameter: float,
    base_diameter: float,
    height: float,
    ball_radius: float,
    handle_height: float,
    handle_diameter: float
    handle_top_radius = handle_diameter / 2
    handle_taper_radius = handle_top_radius / 2

    handle = translate((0, 0, 1))(

    top_radius = top_diameter / 2
    base_radius = base_diameter / 2
    ball_height = ball_radius + height / 2

    return union()(
            translate((0, 0, ball_height))(

# Bespoke just for my bath!
plug = make_plug(41, 38, 10, 40, 16, 20)

The radii were roughly measured and I did a very low-res print but I was surprised that the test came out really well. Here’s the initial draft.

And amazingly the test print is a perfect fit. A little PVC tape around it will make a good seal. I’ll iterate this a bit, the final print will be in white, higher res, and with bevelled edges.

Blog Code

Hypothetical Rust-ish Borrowing in C++

Last night I got into a insomniac code-spiral about replicating some of Rust’s borrowing warnings in C++. In place of Rust’s initial variable declararion of let I use wrapper Owner<T> in C++ that internally tracks ownership. Passing to another Owner<T> will take the ownership, or a Borrower<T> class can accept a properly owned value and reference it as a constant.

// Function borrowing a value can only read const ref
static void use(Borrower<int> v) {

// Function can mutate value via ownership which generates 'warnings' if used again incorrectly
static void use_mut(Owner<int> v) {
  *v = 5;

int main() {
  // Rather than just 'int', Owner<int> tracks the lifetime of the value
  Owner<int> x{3};

  // Borrowing value before mutating causes no problems

  // Mutating value passes ownership, has_been_moved set on original x

  // Uncomment for owner_already_borrowed = 1

  // Uncomment for owner_already_moved = 1

  // Uncomment for another owner_already_borrowed++
  //Borrower<int> y = x;

  //Uncomment for owner_use_after_move = 1;
  //return *x;

Miyazaki Film Title Generator

This code combines random components of words to produce silly Miyazaki-inspired film titles. Such classics as:

  • Tolo Pippi’s Marvellous Leaf
  • Being Onto
  • Chibot Pom’s Jolly Bramble
  • Poko Trollpi and Tombo Go’s Coat Pushing Whistle
  • Tolo Pom and Asbo Go
  • Chi Pop’s Flambuoyant Sponge Popping Service
  • Kabee Go’s Wandering Jelly
  • Tolopa Popyo’s Functional Castle Sniffing Service

Doodles for Lossless Compression of CV Data

I’ve been developing a few electronics ideas that require storing CV data. I thought for a first stab ‘keep it small’, so I’ll try it with an 8k or 16k AVR chip, and I am curious how many seconds of data, sampling at say 100Hz, that I could store in that space. Obviously it will get saturated at some point, but that’s a subject for a later doodle where I need to get into lossy compression (for example, make space by removing small deltas from it).

A friend recommended run length compression on deltas. I did some experiments with that in a jupyter session using smoothed random noise as test data. Here are those early experiments where, speaking very loosely, things compress to around 30%:

Blog Music

MIDI Responsive Qt

Challenge: get MIDI keyboard to update Qt controls for some live jam experimentation. Task list:

  • Use a particular channel for a controller. In future I could make a hardware device that changes channel on a button press, say.
  • Respond to dials changing to update Qt controls. Should be as simple as binding MIDI signal to Qt slot.

MidiJam Bootstrap

I had a moment of clarity on how to get my MIDI jamming tools working this morning. I made a sketch, it was all crystal clear in my mind, and had the typical ‘right, let’s do this!’ moment that all programmers experience, before having all joy boiled out of it by a cascade of tool and API issues.


Shopping List: The Zombie dash

For the past week I’ve been self-isolating whilst Covid-19 precautions are ramping up in the UK. I have asthma but it’s so mild that I’m probably not what the government would classify as vulnerable. Unfortunately this puts me between a rock and a hard place for supplies; shops have no slots for delivery or pick-up, and I don’t want to deprive someone genuinely vulnerable of that service. So in a week when I need food I may be facing a zombie hoard in Sainsbury’s, coughing might-be-Covid on the onions and lingering around the Easter eggs.

Blog Code Music

Reading MIDI

I have a few ideas I’d like to prototype for live performance using MIDI loopers rather than audio loopers. I have sketched early ideas but I’d like to experiment with the project in earnest. I’m tinkering with tools before mocking up some early designs.

Blog Code

Unrolling loops with templates

// Call the passed function object N times. This 'unrolls' the loop
// explicitly in assembly code, rather than creating a runtime loop.
template <unsigned int N, typename Fn>
void unroll(Fn&& fn) {
    if constexpr (N != 0) {
        unroll<N - 1>(fn);
        fn(N - 1);

// extern function ensures the loop is not optimised away
extern void somethin(unsigned int i);

// Call somethin 4 times, passing the count each time
void four_somethins() {
    unroll<4>([](unsigned int i) {