Here's my five latest blog posts - or you can browse a complete archive of all my posts since 2008.

Locking Down & Levelling Up, Part 1: New Computer Time

One of the nice things about this whole weird lockdown situation is that for the first time in a long, long while, I know exactly what my travel plans are going to be for the next few months: none. Zip. Zilch. Nada. The likelihood of being asked to throw some things in a bag and jump on a plane tomorrow is… zero. Which kinda sucks, because I love travelling, but, hey – here I am. I’m at home, it looks like I’m gonna be here for a long while, and that means I have time, and incentive, to turn my home office into an ideal workspace.

Now, I have a bit of a head start here, because I do actually have a dedicated room in my house for “work”. Which means it was already a combination of office, recording studio, library and very occasional spare room, but when the lockdown hit and so many conferences and events started going online, I really wanted a proper setup for livestreaming and recording video, complete with greenscreens, studio lightning, all that kind of stuff. (Yes, buying hardware is a coping strategy for me. This is OK.)

Plus, with everything going online, I kept getting invited to join Slack workspaces. Compiling the .NET Framework from source while running Adobe Premiere and Far Cry simultaneously and livestreaming the whole lot to Twitch in 1080p in real time is one thing, but being in 15 Slack workspaces at the same time requires some serious processing power…

It’s been a long while since I’ve had a proper workstation. Like most nerds of a certain age, I spent the 1990s and 2000s constantly tinkering with big PCs, adding RAM, upgrading CPUs and graphics cards - y’all remember 3Dfx and the Voodoo chipset? Some time back in 2015 the graphics card in my last one failed. I just copied everything across to my laptop and used that as my main machine until I got it fixed… and then never got it fixed. So step 1 of this process was to get a proper computer. I wanted to switch back to running Windows 10 as my main day-to-day operating system (and keep macOS on the laptop for music stuff); I wanted something that could drive a stupid number of external monitors and peripherals, and I wanted something that was blazing fast and whisper quiet.

(Did I mention the bit about how buying hardware is a coping strategy? Cool. Glad we’ve cleared that up.)

Enter the lovely people at QuietPC. A few hours poking around their website, and one very, very helpful phone call, and I had my ideal machine spec’ed out. After having a few too many recordings ruined by the sound of the fans on my Macbook firing up halfway through a take, I wanted something completely fanless. I got pretty close: the system I ended up with has a passive-cooled power supply and CPU cooler, I ended up adding a single 140mm BeQuiet case fan, and there’s a fan on the GPU that only starts up when you drive it hard. Most of the time it’s completely silent.

Here’s the spec I went with:

I need to take a moment here to mention how awesome the folks at QuietPC are, because when I first placed the order, I picked a different CPU cooler – and they actually rang me up, explained that the cooler I’d ordered wouldn’t fit in the case I’d ordered, offered an alternative, and sorted the whole thing out. That’s some absolutely first-class customer service. And sure enough, a few days later, a large pile of exciting cardboard boxes arrived.

IMG_3955

A large pile of exciting cardboard boxes.

Building computers is great fun. It’s like the best Lego ever, and this one was no exception. Getting everything to fit on this system was a tiny, tiny bit fiddly… the Streacom DA2 chassis is a wonderful piece of engineering, based around an open chassis with mounting rails you can move to wherever you need them, but there’s really not a whole lot of space inside. It all fit in the end – mainly thanks to the M.2 hard drives, which aren’t really drives at all, they’re SSD chips on their own circuit boards that mount directly onto the motherboard. I also had no idea just how big the fanless CPU cooler would actually be.

IMG_3977

The CR-80EH Copper IcePipe 80W Fanless CPU Cooler is... not small

I got it all put together, fired it up, installed Windows 10, everything ran beautifully - and absolutely silent. Like, ZERO MOVING PARTS silent. This worked great until I got Visual Studio and Adobe AfterEffects installed and starting putting it through its paces, at which point it crashed hard… turns out that a completely fanless PC is ever so slightly prone to overheating.

IMG_3983

Oops.

So I compromised, and ordered one very big, very quiet fan – it doesn’t take a whole lot of airflow to keep things cool, and there’s an ASUS utility called Fan Xpert that I used to create a fan profile, so it’ll monitor the CPU temperature and automatically spin up the fan when required.

image-20200519105650432

Creating a fan control profile using Asus Fan Xpert

That seems to have done the trick – it’s been running stable for 6 weeks now; I’ve been using the rather good Open Hardware Monitor (which, by the way, is written in C# and .NET!) to keep track of all the various temperatures and things, and haven’t had any more crashes or CPU temperature errors.

image-20200519112125667

Temperature readings over a typical 24 hour cycle. The CPU is the blue one.

In the next post, I’ll talk you through how – and why – I’m using it to drive six monitors, four cameras and four microphones, and how I ended up building a bespoke computer desk to put it all on.

"Locking Down & Levelling Up, Part 1: New Computer Time" was posted by Dylan Beattie on 28 May 2020 • permalink

Running Jekyll on WSL2

Back in August last year, I migrated this site, including 12 years worth of blog posts, from Blogger to Jekyll, primary so that I could host it on Github Pages. At the time, my main system was a Macbook Pro running macOS, I was doing a lot of work with Ruby and had a full Ruby dev environment set up, so running Jekyll locally was trivial.

I’ve recently switched back to Windows as my main OS, and Windows is still very much a second-class citizen in the wonderful world of Ruby web development. It’s a lot better than it used to be, and almost everything now works out of the box, but because the vast majority of Ruby devs (and sites) are running on macOS or Linux, Windows still isn’t quite as slick, or as fast, when it comes to running tools like Jekyll.

But this is 2020, and that doesn’t matter, because you can run Linux on Windows! Thanks to the Windows Subsystem for Linux (WSL), you can boot a full Linux kernel environment on your Windows PC and run native Linux apps and toolchains. I’ve been running Jekyll under WSL 1 for a long while to run my sites locally, and it works great, but it’s a little slow; spinning up a local copy of this site would take around 30 seconds, compared to 10–12 seconds on my old Macbook Pro.

I’d heard good things about performance improvements in WSL2, so last night I took the plunge, enabled the Windows Insider Program on my main PC, and ran a rather hefty Windows Update.

image-20200519114222214

Now, by way of establishing a baseline, here’s running bundle exec jekyll serve on WSL 1. This is what I’ve been using to run my site locally and test things for the past few months.

image-20200519114816853

30 seconds to build the site from scratch. Not great, not terrible.

This is on a the Ubuntu-20.04 LTS Linux kernel that’s available from the Windows Store. Having upgraded Windows 10 to the 2004 build, I could now upgrade this in-situ to use WSL2 instead of WSL1:

C:\Users\dylan>wsl -l -v
  NAME            STATE           VERSION
* Ubuntu-20.04    Running         1

C:\Users\dylan>wsl --set-version Ubuntu-20.04 2
Conversion in progress, this may take a few minutes...
For information on key differences with WSL 2 please visit https://aka.ms/wsl2
Conversion complete.

C:\Users\dylan>

Ooh. Shiny. OK, let’s see what this thing can do:

image-20200519115505666

155 seconds. Gosh. That’s… not quite what I was expecting, and certainly not something I’d claim was a “performance improvement”. So I did a little digging, and found this article from scotch.io, which includes a “Gotchas with WSL 2” section that specifically says:

To take advantage of all the new speed improvements in WSL 2, our files will need to be moved into the Linux filesystem.

Until now, I’d just kept everything on my Windows D: drive and used /mnt/d/ under WSL to run everything. Apparently that’s not a good idea any more… so I did a fresh git clone of my blog code into ~/dylan/github/dylanbeattie.net/ under WSL2 and ran it again:

image-20200519120012376

TWO POINT ONE TWO NINE SECONDS! HOLY BATFISH CATMAN! THAT’S FAST!

For the sake of comparison, running the same thing natively on Windows, using the Windows distribution of Ruby 2.6, takes about 21 seconds:

image-20200519163007957

So, running Jekyll on the Linux native filesystem is an order of magnitude faster than the same thing running natively on Windows, and around two orders of magnitude faster than running the same thing on WSL with a mounted Windows filesystem. That’s quite an astonishing difference.

Of course, this means that all my code now has to reside on the Linux filesystem, so it isn’t quite so easy to get to it from Windows any more. But the Linux filesystem is shared via a network path, so I was able to go:

C:\Users\dylan>net use u: \\wsl$\Ubuntu-20.04\
C:\Users\dylan>u:
U:\home\dylan>cd github\dylanbeattie.net\
U:\home\dylan\github\dylanbeattie.net>

And having got this far, I couldn’t resist running two more tests just to round the whole thing out. First, the same thing but on a full Ubuntu 20.04 desktop VM running under HyperV:

image-20200519191303146

That’s 2.45 seconds – marginally slower than the WSL2 version with the native FS. And finally, just for the hell of it, here’s the Windows native port of Ruby and Jekyll, against the repo checked out onto the Linux native FS, mounted as a network drive in Windows:

image-20200519163357415

618.84 seconds… just a tiny bit slower than the WSL2 native Linux result, wouldn’t you agree?

Here’s how the six different scenarios end up:

image-20200519191518846

Conclusions:

I was genuinely surprised at the orders of magnitude of difference seen here. I expected a factor of maybe 2-3 times – I did not expect the slowest (albeit rather silly) option to be nearly 300 times slower than the fastest. But clearly whatever the WSL team has done in WSL2 has made a substantial difference when it comes to performance – as long as you’re working with a native Linux filesystem.

  • If your base operating system is Windows, running WSL2 with the Linux filesystem is actually faster than any of the other options – including running Linux in a full VM.
  • If you need Windows/Linux interop across the same filesystem, you’re probably better off sticking with WSL1. The Linux kernel in the WSL2 system is significantly slower when dealing with files stored on the Windows filesystem than it was in WSL1.
  • For simple Jekyll sites, using the Windows native versions of Ruby and Jekyll is probably fine.
  • If performance is a big deal, go for WSL2 and clone your repo onto the Linux FS

Usual caveats apply, that one guy running one Jekyll site and writing a blog post about it is not a rigorous scientific analysis. I did this because I wanted to work out what solution worked best for my specific scenario. Your mileage, as the saying goes, may vary. But it’s definitely worth trying out a few different options and seeing what works best for your particular workload - and hey, when you do, publish the results. I’m curious to see just how good WSL2 is across different scenarios, but early indicators are it’s very, very good indeed.

"Running Jekyll on WSL2" was posted by Dylan Beattie on 19 May 2020 • permalink

Piedroit: A Raspberry Pi-powered USB Footpedal (Part 2)

In part 1 of this post, I described the software and config required to use a Raspberry Pi Zero W to create a bank of footswitches that the host computer thinks is a USB keyboard. So far, so good: a little Python hacking, some Linux modules, a bit of GPIO and USB HID programming. All nice and friendly and revision-controlled.

That’s only half the problem, though. The main reason I’m building this thing is that I want a way to control the computer by stamping on things. When I’m playing the guitar and doing live shows, on stage or streaming via Twitch or YouTube, I want to be able to switch shots and control backing tracks by pressing switches with my feet. Now, I’m not exactly sure what would happen if 102kg of slightly excitable developer stood on a Raspberry Pi Zero W – or a normal computer keyboard, for that matter – but I suspect if it happened regularly, the devices in question might start complaining a bit.

So having solved the logical elements of this puzzle, let’s figure out the physical bits. How do you connect a Pi Zero to a bank of footswitches that can cope with a big hairy guy pressing them with a pair of size 10 boots?

Well, as with many problems in life, the answer is… metal. In this case, 0.6mm bright mild steel sheet, because that’s what I could get hold of. I don’t have access to a proper machine shop or any welding gear (#lifegoals), so I had to come up with a design that I could make using the tools and materials I had available, but which would protect the Pi and other bits of delicate circuitry within.

mintice-momentary-button-electric-switch

The switches I’m using for this project are a brand called Mintice, available from Amazon for £11.79 for a pack of 5. They’re pretty easy to work with, other than requiring you to drill a 12mm diameter hole… making holes in sheet steel is easy, especially if you have a drill press… I don’t have a drill press. I’m working with a cordless hand drill here, so making sure the holes end up exactly where they’re supposed to be is a bit tricky.

The Cardboard Prototype

Just like software, you should always plan to build one version to throw away. Unlike in software, when it comes to metalwork it’s normally really obvious which one’s the prototype… it’s the one made out of JavaScript cardboard. The prototype I’m building here is to answer a couple of key questions:

  • Will all the components actually fit?
  • How much sheet stock will I need, and what shapes will I need to cut?
  • Is there enough space between the switches that I won’t accidentally press two switches at once?

IMG_4736

Sketching layouts and checking clearance for the components

IMG_4738

Cardboard prototype for the top part of the housing

IMG_4741

Testing the footswitches in the cardboard housing mockup

IMG_4751

The Pi Zero board and the footswitches installed in the prototype housing to check clearance

Time to Get Metal

The cardboard prototype worked. The components all fit, nothing’s fouling anything else, and it’s small enough to make from a single sheet of the 250mm x 400mm steel sheet stock I had available, but big enough to install five switches on the unit with enough distance between them that I’m not going to hit two switches at once.

Now I just need to make the same thing again, except in steel instead of cardboard. That’s not actually as daunting as it sounds. I really enjoy working with steel. Cardboard’s easy to cut and fold, sure, but it also frays and has a tendency to unfold. Steel takes time (and the proper tools) to cut and shape, but once you fold it, it stays folded.

First step was to cut a piece of steel for the top of the housing, and then drill the five mounting holes for the switches:

IMG_4759

Mounting holes for the foot switches

Next step was to bend the top part of the housing. There’s dozens of videos on YouTube about how to bend sheet metal – some show you how to use a machine called a metal brake; some show you how to make a metal brake if you don’t have one available, and some show you how to bend metal without a brake. This video from Cosador is great if you want an overview of a few different techniques. I ended up using hand bends and hammered bends for most of my project, using a couple of lengths of cold-rolled steel angle and lots of clamps to hold everything straight. It came out OK – not perfect, but good enough for what I need.

IMG_4760

Improvised metal brake made by clamping angle and square section steel onto my kitchen table.

IMG_4763

The main bends for the top part of the casing done.

IMG_4787

Test fitting the foot switches into the bent metal casing.

For the bottom half of the casing, I needed to bend up the edges of the case, but also to cut notches for the HDMI and USB ports on the Pi Zero.

IMG_4821

Rough-cutting the bottom casing panel using a jigsaw

IMG_4877

Work in progress filing out the notches for the Pi IO connectors

IMG_4880

Testing fit of the Pi Zero IO ports

The Pi board itself was mounted on a small piece of 6mm MDF – you can see the original sheet in this photo, that I’m using to hold the Pi in place to check the fit of the IO ports.

One more thing I did was to use a needle file to enlarge the mounting holes on the Pi so I could use 3mm screws. Out of the box, the Pi uses 2.5mm mounting screws. I don’t have any of those lying around – but I have lots of 3mm screws and bolts, so slightly enlarging the holes gave me way more options when it came to mounting the board.

Wiring it up

To wire the switches to the Pi’s GPIO ports, I cut one end off a 40-pin ribbon cable, giving me a wiring harness with about 15cm of wire on each pin. The fun part here was figuring out which wire connects to which pin. I used a Raspberry Pi breakout board for this part, and it took about an hour of testing connections with a multimeter and labelling each wire as I identified which pin it connected to. Fiddly, but not actually difficult.

IMG_4896

Tracing the individual cables in the 40-pin ribbon cable back to the source pins

For this project, I wired GPIO pins 04-08 to switches 1-5. At this stage I also wired in two extra breakout ports – one’s a mono 6.5mm jack socket, the other is a stereo 6.5mm jack socket. I wired these into GPIO pins 9 and 10+11, so I could hook up three extra external footswitches to give me another three inputs on the board.

IMG_4904

Here’s both parts of the casing, with all five switches and the two 6.5mm breakout ports all wired in and the ribbon cable seated on the Pi’s GPIO connector. You can see the 6 holes I drilled in the case here – the original plan was to tap M3 threads into the top half of the casing and assemble the case using M3 bolts. Turns out 0.6mm mild steel isn’t actually hard enough to hold a thread… two of them came out OK, one of them I stripped completely and ended up bodging by supergluing a nut in place above the hole, the other three I’m just going to ignore for now. You can also see the Pi board here mounted on a piece of 6mm MDF, which is attached to the steel using 3M Command Strips – again, that’s what I had easily to hand. They’re normally used to hold pictures on the wall, but they adhere to steel and to MDF pretty well and they’re easily removable if necessary.

IMG_4927

The Piedroit wired up and ready for final assembly

And – that’s it! Put the whole thing together, boot it up, and… it works. Windows detects each footswitch as a key on a USB keyboard, and now I can control WinAmp, OBS, and any other application that supports global hotkeys by pressing footswitches.

Ideas for vNext

This was a great project. Frustrating in places, especially the Bluetooth dead end, but I had a lot of fun putting it together. At a time when so much of what we’re all doing – work, social life, entertainment – is all taking place on screen, it’s also a nice change to build something physical; something you can actually pick up and touch and handle.

But, of course, I have loads of ideas for building a better version.

  • The circuitry. The Pi is a great little computer, but… do I really need 512Mb of RAM in a footswitch? I’m also still keen to see what I can do with Bluetooth, so I suspect the next incarnation of the project will use either something like an Arduino or a Teensy, or I’ll cannibalise a Bluetooth keyboard and hack the circuitry from that into a footpedal controller.

  • Status LEDs. There’s currently no way of telling whether the board has actually booted up properly. It wouldn’t be that hard to wire up a couple of LEDs to the GPIO pins – something as simple as a red LED for power and a green LED that lights up once the USB keyboard event loop is running would make the device a lot friendlier.

And, of course, there’s all the “it would be cool if…” – reprogramming key mappings, macros, modifier keys… once you get into these kinds of projects, the hardest part is knowing when to stop.

But this one is done. I’ll be using it for a bunch of events I’m doing this week, including HalfStack Online on Friday, and I’m sure you’ll be able to catch it in action on a YouTube or Twitch stream near you before too long!

"Piedroit: A Raspberry Pi-powered USB Footpedal (Part 2)" was posted by Dylan Beattie on 18 May 2020 • permalink

Piedroit: A Raspberry Pi-powered USB Footpedal (Part 1)

I often find myself doing daft things with computers and playing the guitar at the same time. I use laptops on stage to run videos and backing tracks, I record my own music, and, most recently, I’ve been livestreaming music over YouTube and Twitch for some of the online conferences I’ve spoken at.

Since playing the guitar tends to require both hands, many guitar amps and effects include some kind of footswitch controller, so you can switch between different sounds and effects without taking your hands off the guitar. For a while, I’ve been after something similar that’ll let me control a computer remotely using foot switches. I’ve used various kinds of foot controllers in the past, but none of them has ever done quite what I wanted. The two that have stuck around the longest are the AirTurn PEDPro and the iRig Blueboard.

airturn-ped-pro

The PEDPro runs on Bluetooth and works great as a hands-free Powerpoint clicker. It connects to Windows or macOS as a Bluetooth keyboard, but it only has two keys, which are (normally) hardwired to be Left and Right. This works great for controlling Powerpoint, but it’s a bit limited.

10158884_800

The iRig Blueboard has four footswitches, and works very nicely with iOS and macOS, but it connects to the host system as some kind of proprietary Bluetooth MIDI device, and it doesn’t work on Windows.

So I figured building my own pedalboard might be a fun lockdown project. At a bare minimum, I wanted to be able to switch between scenes in OBS and control some sort of media player at the same time, so I can stop/start videos and backing tracks and switch between different camera angles when doing live streams.

There’s two approaches I could have taken:

  • Network-based: the footswitch device connects to wifi and sends signals to a host PC over the network. I write some bespoke software that runs on the host PC, which either translates those signals into emulated keystrokes, or controls the target applications directly.
  • Device emulation: the footswitch connects directly to the host PC, via USB or Bluetooth, and shows up as a keyboard, joystick or some other kind of human interface device (HID).

I went for device emulation, mainly because the host PC is already going to be pretty busy handling multiple cameras, OBS, media playback, greenscreen effects, and live network streaming, and having my footswitch just show up as a keyboard seemed a lot more straightforward. Plus, I’ve done a whole bunch of network programming and client/server stuff, but I’ve never built something that emulated a physical keyboard before and it sounded like fun.

The Raspberry Pi Zero W

For this version of the project, I used the Raspberry Pi Zero W. Lots of people asked why I didn’t use an Arduino or some other device: well, I used a Pi because I like them. They’re wonderful little devices, they’re lots of fun to work with, and I’ve done some interesting projects with them before so I’m not starting from scratch here.

One very interesting idea which I’ll probably return to in a future project would be to cannibalise the controller from a Bluetooth keyboard and use that instead of building my own device. More on that in a moment.

image-20200518124113452

Banana! (Raspberry Pi Zero W for scale)

The Pi Zero is a tiny Linux computer, not much bigger than a stick of gum. It’s got a 1GHz single-core CPU, 512Mb RAM, a mini HDMI port, two USB ports – one for power, one for peripherals. Most important of all for this project, it has a bank of general-purpose input/output (GPIO) pins that you can wire up to external switches, LEDs, sensors, all kinds of things, and then write some fairly simple code to interface with them. Which is brilliant if you want to connect a bunch of mechanical footswitches to a tiny Linux computer and don’t really know what you’re doing.

The other nice thing about the Pi Zero W is that it’s got exactly the same hardware and programming interface as its big brother, the Raspberry Pi 4 Model B – so if you get into serious code-wrangling, you can use the more powerful Pi 4B as your dev platform, get your code working, then pop the MicroSD card out, put it into the Pi Zero and boot the exact same code on the smaller device.

Plan A: Bluetooth

Image

My first approach with this project was to get the Pi Zero to connect to the host PC over Bluetooth, and emulate a Bluetooth keyboard. I spent a rather fun, if occasionally frustrating, weekend playing around with this. You can read the tweet-by-tweet accounts from day 1 and day 2 – but to cut a long story short, I couldn’t get it to work well enough for what I wanted.

I got to the point where I could boot the Pi, start the various Python scripts, then go onto my Windows machine and add a new Bluetooth device – and it worked. The device would show up as paired, then connected, and it would actually send keystrokes to the host PC:

There was a problem, though. When I stopped the Python script that was running the Bluetooth service on the Pi, the device would go from connected to paired – and I could not find any way to get it to reconnect without removing and re-adding it. Which made the whole thing a bit impractical, particularly if I was going to try using it in any kind of live performance situation.

In this video, you can see that with my Logitech K380 Bluetooth keyboard, this works perfectly – and part of me wishes I’d just cannibalised a K380, taken out the controller chips and switches, and wired my own footswitches into it. That would have made the hardware side of this a lot more straightforward… but hey, we live and learn, right?

Plan B: Wired USB

In tech projects, it’s way too easy to get fixated on your current approach and lose sight of what you’re actually trying to accomplish. It was this tweet from Jonty – and particularly the phrase “you’re wayyyy down this rabbit hole” – that got me to take a metaphorical step back and remember that Bluetooth is not actually a requirement here. The goal is to be able to control OBS and WinAmp, on a desktop PC, using my feet. I’m trying to control a stationary computer from a stationary footswitch, so having a wire connecting the two is not a problem. It turns out the Pi Zero will also quite happily emulate any number of USB gadgets, from virtual keyboards to joysticks and network interfaces.

So, I recast the project a bit. The milestone for this part was to get to a point where:

  • The Pi Zero is connected to a Windows 10 PC via USB
  • The Windows PC thinks the Pi Zero is a keyboard
  • I can run some Python code on the Pi Zero to send arbitrary keystrokes (including modifier keys) to the PC

This was actually pretty straightforward, thanks to a really great article “Composite USB Gadgets on the Raspberry Pi Zero” over at iSticktoit.net. I did have one slight stumbling block: when I first started working on this, I originally found this tutorial instead. That’s almost exactly the same (the code samples are identical) except the Random Nerd Tutorials article says quite clearly that you can run the whole thing off a single micro USB port:

image-20200517163434097

Now, a little later in the article, our Random Nerd author does actually say:

image-20200517163507995

To say this does not match my own experience would be putting it mildly. The first few times I tried booting the Pi drawing power through this USB port, it caused all sorts of chaos, including completely shutting down the entire USB bus on my Windows PC more than once, leaving me with no mouse and no keyboard. That was fun. It is possible – I got a working setup a few times using only a single USB cable – but I wouldn’t recommend it. After a few rounds of this, I tried booting the Pi using standalone USB power, waiting until it was up and running, and then connecting the second USB port to the host PC – and it worked flawlessly. You have no idea how excited I got when I saw this little pop-up in the corner of my Windows 10 display:

image-20200517165722956

TL;DR: Boot the Pi using dedicated USB power. Once it is up and running, connect the peripheral USB port to the host PC, and everything works fine.

The Code

The software side of this is really in two parts. First, there’s the configuration you’ll need to run to persuade the Pi to start pretending it’s a USB keyboard. Then there’s a bit of Python code that will detect when a circuit is closed across a pair of GPIO pins, and send a particular keystroke over the USB interface when this happens. This is wonderfully, beautifully simple on the Pi Zero, thanks to the RPi.GPIO library that makes it really easy to write Python code that talks to the GPIO pins. All the code for my implementation is available on Github, along with instructions about how to get it set up and running:

https://github.com/dylanbeattie/piedroit

The important part is here – piedroit.py. This is the code that detects events on the GPIO pins, translates them into the specific data structure required by the USB keyboard interface, and sends those events to the /dev/hidg0 device that’ll pass them to the host PC:

#!/usr/bin/env python
# piedroit: translate GPIO pin inputs into USB keystrokes
# https://github.com/dylanbeattie/piedroit

import RPi.GPIO as GPIO
import modifier_keys

NULL_CHAR = chr(0)

def send_data_to_usb(data):
  with open('/dev/hidg0', 'rb+') as fd:
    fd.write(data.encode())

def get_key_code(gpio_pin):
  # https://www.usb.org/sites/default/files/documents/hut1_12v2.pdf
  # Physical switches are wired to GPIO pins 4-11
  # I want footswitch #1 (GPIO pin 04) to send F1, #2 > GPIO02 > F2, etc.
  # F1 has USB key code 58 (0x3A), F2 is 59, etc. 
  # So we can get the key code we need by adding 54 to the GPIO pin number.
  return(gpio_pin + 54)

def send_key_down(key_code):
  # USB key events are an 8-byte struct containing:
  # – a one-byte bitfield of modifier keys 
  # – a null byte
  # – Up to six key codes. (USB allows you to press up to six keys simultaneously)
  #
  # This code will always send Ctrl+{key}
  modifiers = modifier_keys.LEFT_CTRL
  key_data = chr(modifiers) + NULL_CHAR + chr(key_code) + NULL_CHAR*5
  send_data_to_usb(key_data)

def release_all_keys():
  send_data_to_usb(NULL_CHAR*8)

def send_key_for_gpio_pin(gpio_pin):
  key_code = get_key_code(gpio_pin)
  send_key_down(key_code)

# This code will support GPIO pins 4-21, although 
# only pins 4-11 are actually connected in my device
FIRST_GPIO_PIN = 4
FINAL_GPIO_PIN = 21
ALL_PINS = range(FIRST_GPIO_PIN,FINAL_GPIO_PIN)

# Tell the Pi which numbering mode we're using to talk to the GPIO pins
# https://raspberrypi.stackexchange.com/questions/12966/what-is-the-difference-between-board-and-bcm-for-gpio-pin-numbering
GPIO.setmode(GPIO.BCM)

for pin in ALL_PINS:
  GPIO.setup(pin, GPIO.IN, pull_up_down=GPIO.PUD_UP)

# Remember closing a switch connects the GPIO pin to ground (GND)
# so GPIO.input(pin) will return 0 ("grounded") or 1 ("not grounded")
SWITCH_CLOSED = 0

# Now we just sit in an infinite loop, reading all the GPIO pin states 
# every time we loop, and watching to see if any pin state has changed.
previous_states = [1] * FINAL_GPIO_PIN

while True:
  for pin in ALL_PINS:
    state = GPIO.input(pin)
    previous_state = previous_states[pin]
    if (state != previous_state):
      if (state == SWITCH_CLOSED):
        print("GPIO PIN {} now CLOSED".format(pin))
        send_key_for_gpio_pin(pin)
      else:
        print("GPIO PIN {} now OPEN".format(pin))
        release_all_keys()

      previous_states[pin] = state
 
# This is good practice, but since we're going to sit in our loop
# until we kill the process or disconnect the power, we'll never
# actually get here. But in this scenario, that's OK.
for pin in ALL_PINS:
  GPIO.cleanup(pin)

The Case

Finally, I needed a box to put it all in – a box that wouldn’t get upset if 102kg of Dylan stood on it wearing cowboy boots. Check out part 2 of this post which involves a lot less code – and a lot more sheet steel.

🤘🏻

IMG_4923

"Piedroit: A Raspberry Pi-powered USB Footpedal (Part 1)" was posted by Dylan Beattie on 17 May 2020 • permalink

Microphone Tips for Remote Presentations

In my last post, I shared some tips for giving online presentations. In this talk, we’re going to completely nerd out about microphones, and how to get the best possible results out of the equipment you already have.

9434755558_129d6bce9e_o

drestwn via Flicker / CC BY 2.0

Audio quality is essential to connecting with your audience when you’re presenting remotely. A conference is about speakers giving talks. Not looks, not stands, not dances – talks. We are speakers, we are there to talk, and our audiences are there to listen. If your audience can’t hear you, you’ve lost them, no matter how beautiful your slides or or how many hours you’ve spent practising… and when you’re presenting online, your microphone is the Jesus nut – the single point of failure that can bring the whole thing crashing down.

You can easily spend a fortune on specialist microphones, but if you don’t know what you’re doing, it won’t make any difference – and if you do know what you’re doing, you can get great results from relatively inexpensive kit.

Humans are good at dealing with visual clutter. We can focus our eyes, look at the things we care about and ignore unnecessary background detail - check out this video for a remarkable demonstration of this.

Audio isn’t like that. Your ears never blink. We hear every detail, every keystroke and passing car and buzzing fluorescent lamp - and so when we’re doing presentations, it’s absolutely vital to understand how much background noise and interference your mic is picking up.

Before we go any further, take a look at this video. I recorded myself using seven different microphones at the same time, so you can hear for yourself how the different microphones sound, and how they cope with different kinds of interference and background noise.

Microphone placement

You want your mic as close to your mouth as possible; 5 cm (2”) to 25 cm (10”) is ideal. You also want to avoid moving around too much relative to the microphone.

Headset mics are great, because they keep the microphone in the same position relative to your mouth – you can turn your head, walk around, and they still sound good. Lavalier mics – the ones that clip into your clothes – and phone headsets also work pretty well, and you can stand up and walk around, as long as you remember not to turn your head. If you’re using a fixed mic on a stand, you’ll need to sit very, very still to get the best results from it.

Background noise and isolation

You’ll notice in the video that the built-in mic in the Surface Pro sounds really good, right up until I start typing. It’s actually a really good mic, but because it’s built in to the device, it’s in the worst possible position – it’s on the desk, quite a long way from my mouth, right next to my keyboard, and it’ll pick up every bit of vibration and background noise.

This isn’t just a problem with built-in mics – I’ve seen folks spend quite a lot of money on specialist USB microphones like the Blue Yeti, and then sit them on the desk right next to their mechanical keyboard and wonder why they’re not getting a good sound.

If your mic is attached to your clothing, or you’re using a phone headset, watch out for clothing rustle – check out this article from Rode about lavalier mic placement, which has some excellent tips.

Connection

If you’re going shopping, you’ll need to consider how your mic connects to your computer. USB headsets will just plug straight in, and the headphone jack in most modern laptops is compatible with the TRRS plugs used on phone headsets.

If you’re going for a standalone mic or a wireless system, you’ll need an audio interface to connect it to your computer. I highly recommend the Yamaha AG03 and AG06, for this – they’re great quality, incredibly versatile and easy to use.

Photograph of Yamaha AG03 and AG06 USB mixing consoles

Yamaha AG06 and AG03 portable USB mixing consoles

Listen to yourself

The golden rule with any microphone, though is: listen to yourself. Install some audio recording software – Audacity is free, open-source and cross-platform – make some recordings, listen back to yourself (and make sure to listen through headphones.) Record 30 seconds of silence and listen back to it. What do you hear? Traffic noise? Dishwasher? Mouse clicks? If you can hear it, your audience will hear it. You might not able to eliminate background noise entirely, but figure out what you can to reduce it – close windows, close doors, take off your shoes, switch off the aircon. Make yourself a pre-flight checklist.

Now record 30 seconds of you speaking. at the same volume you’d use when giving a talk, and listen back to that. Try reading these ten sentences out loud, then listen back and see what you sound like:

  1. The dark pot hung in the front closet.
  2. Carry the pail to the wall and spill it there.
  3. The train brought our hero to the big town.
  4. We are sure that one war is enough.
  5. Grey paint stretched for miles around.
  6. The rude laugh filled the empty room.
  7. High seats are best for football fans.
  8. Tea served from the brown jug is tasty.
  9. A dash of pepper spoils beef stew.
  10. A zestful food is the hot-cross bun.

This is one of 72 lists of stock phrases known as the “Harvard Sentences”:

“a collection of phonetically balanced sentences that measure a large range of different qualities in the human voice. These were originally published in 1969 as the Institute of Electrical and Electronics Engineers recommended practice for speech quality measurements.”

– you can find the whole list online here.

If you hear loud pop or thud on words like ‘pepper’ and ‘bubble’, that’s called a plosive – it’s the mic picking up the sharp release of breath that happens when we pronounce letters like ‘b’ and ‘p’. See if you can move the mic downwards or to the side slightly so that it isn’t directly in front of your mouth. If you hear hissing or whistling on words like ‘stew’ and ‘seats’, that’s called sibilance – try moving the mic a little further away from your mouth.

Play with the distance until you’ve got a good clear voice with minimal background noise, but you’re not getting any hissing or popping. If your mic has a volume control, turn it up until you’re about as loud as you can go without hearing any distortion or seeing any warning lights, then back it off about 5%. Do this every time you change anything – move the furniture, get a new mic, install new drivers. And remember the golden rule: listen to yourself. That’s what your audience is going to be listening to for an hour – if it doesn’t sound good in your own room, on your own headphones, there’s no way that sending it halfway around the world on a video call is going to make it any better.

Conclusions

A USB headset gives the best balance of quality and price – you can get excellent audio quality from a £20 headset, and it won’t pick up things like typing and background noise. The only drawbacks here are that you’ve gotta have a big chunky thing on your head, and if it’s wired, you can’t get up and walk around. If you’re going to be sat a desk for your recordings, and don’t mind how it looks (or you’re not going to be on video), go for one of these.

If all you have is a phone headset, use it – but be very careful not to move around too much. You’ll get good results if you sit still and speak clearly, but watch out for the mic rubbing on your clothes and be careful you don’t snag the cable.

If you’re using a fixed mic like the RØDE Podcaster or the Blue Yeti, make sure it’s mounted high and insulated from vibration – ideally on a proper microphone stand with a shock mount.

If you have no choice but to use the mic built in to your laptop, work out how to isolate it as much as possible from background noise. If your presentation doesn’t involve any typing, clicking or anything, you’ll probably be OK. If you need to type, try resting the laptop on a pillow or a cushion - maybe even use an external keyboard as well to reduce the typing noise.

And remember: you don’t need to spend a lot of money on specialist equipment. Start with what you’ve already got, make some recordings, listen to yourself, figure out what’s not working, fix it, repeat.

"Microphone Tips for Remote Presentations" was posted by Dylan Beattie on 12 May 2020 • permalink