new stuff with FPGAs


For this project I am builiding a modular, FPGA powered MIDI/OSC Control Surface.

The setup consists of an arduino MCU as a master controller, that communicates to the PC over SLIP-encoded Serial OSC messages. The controller talks to daughterboards over SPI. Each daugherboard contains a rotary encoder, 8 RGB LEDs and does capacitive sensing on the knob.

This was the first time I worked with an FPGA, and the first time I designed my own PCBs as well. The FPGA I used is an ICE40UP5k, it was targeted using the icestorm open toolchain and Verilog. I started by prototyping using an UPduino v2 Prototyping board (orange), and my failed rev1 PCBs (green). On the FPGAs I implemented capacitive sensing, the SPI slave and control logic before moving on.

driving WS2812 RGB LEDs on the prototype board
developing and debugging the SPI protocol
getting the encoder and capacitive sensing working on the prototype

Once I got everything working there I designed my custom boards with the FPGA integrated directly, including power conditioning and configuration. There is also a busboard that manages SPI addressing / multiplexing as well as latching the power state for each daughterboard, so that they can be started and configured individually.

configuring the FPGA on the custom PCB via an arduino for the first time
encoder & capacitive sensing working on the custom PCB

I also contacted some suppliers of machined aluminum knobs online and ordered a some samples from one of them.

I selected only knobs that are made made from solid aluminum and that use a set-screw for fastening to make sure that the aluminum and the encoder would make electrical contact through the set-screw, which is required for the capacitive sensing to work (at leas the way I implemented it).

testing different knob spacings
sampling machined aluminum knobs from chinese supplier

The daughterboards and controller communicate over a custom SPI protocol I designed. The controller configures the daughterboards on boot or request from the PC. It sends and receives OSC messages over SLIP-encoded Serial. On the PC a small nodejs application relays the OSC messages over UDP or WebSocket, so that native and web applications can consume them and interact with the control surface.

a browser application talking to the encoders through a websocket/serial OSC bridge (nodejs)