1. Introduction
  2. Features
  3. Build
  4. Software Setup
  5. Ideas
  6. Thanks


2 ottopot variants, one with LEDs and one without

This is the ottopot. It's a MIDI controller I made with nothing but 8 dials. However, the dials I made in the highest quality that I possibly could. There are 2 things in particular that I haven't seen in any other similar devices:
High resolution with 14bit MIDI CCs (12bit effective resolution) and a quasi-1:1 mapping from physical movement to CC value; like you know from analog potentiometers but of course without the stops on either end.

If you would like to build your own, I have published the 3D print files, a build documentation and the source code here.

Here is an introduction and demonstration video

I'm considering this the 0.9 version; I'm currently trying to learn KiCad to make a simple PCB for it so the building process is easier.

Let's dive into some of the details!


14bit CCs

I've come across this a couple of years ago and I've been obsessed with it ever since. Usually you send MIDI control messages with a single CC that can hold a value between 0 to 127, so 7bit. That's a bit coarse for a lot of applications. 14bit CCs are a clever way of sending 2 CC messages in quick succession where the first one is the coarse value and the second one is the fine value. Since every bit doubles the resolution, this is huge improvement! Now it feels like it is rather obscure, but I have found software support to be pretty good. Logic and Bitwig both support it; those are the DAWs I use, but from a quick search it seems like Ableton also supports it and probably others as well. With Bitwig I use Moss' generic flexi.
Hardware support for 14bit CCs on the other hand is basically non-existent. That's one of the reasons why I built my own controller.
For the ottopot, I've settled with using 12bit for the read resolution.

1:1 mapping

With analog pots it feels like you are very much in control of the parameter; every movement on the dial directly translates into a change of the parameter. With typical MIDI controllers using encoders, it feels like there is a disconnect; like there's a layer of goop between the dial and the parameter. I think that is mostly because the relationship is not 1:1, so one full turn of the dial doesn't correspond to a full sweep through the parameter's range. They also often use acceleration so the value change is depending on the speed of your motion, not just the distance.
With the ottopot, it feels very close to analog potentiometers to me. There's no acceleration and I've made it so one full turn is one full sweep across the whole range. It makes for a much more musical feeling, at least it does to me.


I think you should be familiar with soldering and have a bit of experience with other electronics projects before trying to build an ottopot right now. It might get quite a bit easier with the next version after I learn KiCad and make a PCB.
For now, there's just a lot of wiring.
Overall cost for materials and shipping has been around 220€ for me. I have made a version of the faceplate that doesn't have the holes for the LEDs so you can just skip them — the code works the same without the LED boards connected. This way you can save ~100€ for the LED boards.
Another thing you could skip is the re-greasing of the pots, but I highly suggest that you do it. It feels so much better with lower resistance.


Replacing the grease on the pots for lower turning resistance

Opening a potentiometer

Pry open the small legs that hold the metal part to the plastic base. I found it easiest to start with a utility knife and once they're opened a little bit, continue with pliers.

Removing the circlet

Remove the circlet using a pair of pliers. It's not easy! I found it helps to use a potentiometer knob to make it easier to hold on to the body.

Remove the factory grease

Use degreaser to remove the factory grease from both the shaft as well as the base. That stuff is super sticky, it feels almost like glue. The shaft will turn very easily once the grease is gone. Make sure it is fully gone so the different pots will feel the same. Best to do that in a sink and use some paper towels to dry and clean the parts. You can roll the edges of a piece of paper towel and use something like a tooth pick to get inside of the axle hole in the body.

Put new grease on the shaft

Put some new grease on the shaft and the axle hole in the body. I'm using Shimano premium bearing grease and I really like the feel of it, just the right amount of resistance. Though I'm sure any other bearing grease will do the same. I'm putting a little grease on both parts and then insert the shaft and turn it around a couple of times before wiping the excess with a bit of paper towel.

Reinstall the circlet

Reinstall the circlet with a pair of pliers. Again, I found it helps to use a poti knob as kind of a stand for the shaft.

Reinstall the wiper

Put the wiper back on the body. There's a matching cutout on the wiper that fits into the shaft. The photo shows the orientation which I found to be easiest to make them fit.

Reinstall the plastic body part

Finally fit the body; there is a longer side which should face in the direction of the pins. Use pliers to bend the legs back over to hold the plastic part in place.

Finished pot

Done! You should have a pot that feels a lot easier and very nice to turn. Now just do it seven more times 🫠

3D printing the case and knobs

I've published the models on printables.
There's a top case for the version with LEDs and one for the one without.
For the knobs, I'm using this model: Encoder Knob by Void, the 16mm_3mm_D.stl file printed at 103% scale on my Prusa Mini. I suggest printing 1 and checking the fit before committing to print all 8 in one go.
In my models I'm using 0.2mm tolerances for all the holes but I think my printer isn't tuned perfectly so I also need to clean up the holes after printing with a drill a tiny bit; for the pot holes I use a 7mm drill, for the small LED holes I use a 2.5mm drill.
I use 4 heat set insert from CNC kitchen in the bottom case and 4 generic m3x8 screws with allen heads to fasten the top case to the bottom.
Finally I use a couple of 3m rubber feet to glue onto the base to prevent slipping.

Wiring up the boards (Teensy + multiplexers)

I'll try to go over this quickly because I'm planning to do a PCB soon so this will become obsolete.
You'll need to wire up the Teensy to two 74HC4051 multiplexers and then the multiplexers to a leg each of the the 8 pots along with ground and 3v3.
5v from the Teensy goes to the LED boards as well as 3v3, ground and clock+data for i2c.
I designed the case so that the wire mess will fit snugly, so you'll have to leave the wires relatively short.

Wired up boards

These are the boards wired together with the bit of perfboard in the middle to splice some wires. Black is ground, red is 3v3, yellow are the multiplexer select pins. Let's go over the individual connections next; I hope this picture can help with orientation and give you an idea of the dimensions you should aim for to make it fit in the case.

Now for the second mux board, basically the same but we're using the pins on the right side of the first mux board if possible to save some space:

These are all the connections in the image above.
Next, let's prepare the LED boards (optionally) and then let's take care of the potentiometers.

Preparing the LED boards (optional)

Each of the 8 LED boards needs some specific solder bridges. I'll number them the way they are wired to the multiplexers, so left to right, top to bottom.

Potentiometers from the top with numbers

This is the order of the potentiometers (and LED boards) seen from the top; this will be the order in which to connect the Y-pins on the mux boards as well. Keep in mind we're working from the bottom so it will be flipped.

View of a single LED board with areas for the solder bridges

These are the areas in which we will need to add some solder bridges to set the i2c addresses and the pull-up resistors.

First board with the required bridges

As an example, here's the first board with all solder bridges we need. This is the only board that will have the bridges for the resistors.

Here's a list of all solder bridges needed on the 8 LED boards:

Wiring up the potentiometers

For this, we will add a long wires to each of the mux boards' Y0 - Y7 pins. I will use grey wires for the pins on the first mux board and purple wires for the second one. This is important for the order in which they'll get soldered to the pins on the potentiometers.
We will also add one long wire from the VCC and one from the GND pins on the second mux board. These will connect to the first potentiometer and from there, we'll do a “wavey wire chain” between all the pots; check the next pictures to understand what I mean.
Start by putting all the pots in the 3d printed top case so there's a guide for the lengths of the wires. If you use the LED boards, put them in first and use the pot's washer between the pot and the LED board; see below for the LED board orientation. The holes are a slightly unfortunate size and the washers help so the pots don't get jammed up in the LED board holes.
For the next couple of pictures, I'm not using the LED boards so it's easier to see where things go.

Wavey wire for connecting the pots together

This is how I prepare the wavey wire to connect the `3v3` and `gnd` pins. The loops are about 5-4cm lengths of wire where I each twist the ends together with the next piece. All in all we need 7 pieces because the eighth one will connect to the wire on the mux board.

Pots connected together with 3v3 wavey loops

Solder the red wavey wire loop to the leftmost pin on each of the pots except the upper right one. Here's all the 3v3 pins connected; note that the top right is still open since this is the one that'll connect to the mux board. Do the same thing with the ground wavey wire and connect it to the third pin from the left on each pot leaving the upper right one loose again.

Connections on one pot

Now it's time to solder the `Y0` - `Y7` pins from both mux boards to the pots. This is fiddly stuff. The connections in the orientation from the picture are: 3v3, Y-pin from mux board 2, gnd, Y-pin from mux board 1. It's pretty important to keep the wires somewhat short so they'll fit in the case. There will be a picture of everything connected, but first let's go over how the pots are numbered.

Potentiometers from the top with numbers

This is the order of the potentiometers from the top; this will be the order in which to connect the Y-pins on the mux boards as well.

Pots numbered from the bottom

Flipping the board will make it so they are numbered like this. Note that I oriented the pots so the pins point towards the bottom in this orientation. Looking at it like this, both `Y0` pins from the mux boards will go to the top right pot, `Y1` to the one left to it and so on.

All the pots connected

So this is the end result of all the potentiometers connections. The 3v3 and gnd wires on the first potentiometer have been connected to the mux board as well as the wavey wires, connecting all pots together. (For the eagle eyed: please don't get confused, the mux boards are out of order in this picture. The written documentation is correct, I just messed up the order in the build. Sorry. This is the only picture where you can see the difference.)

Put it all in the case

If you're not doing the LED boards, you're almost done. Otherwise skip to the next section. Put a micro USB cable through the back hole of the bottom case, connect the Teensy and wiggle everything in place so you can close the case. If you're worried about it, you could use hot glue to fix the boards in place and use 2 cable ties (inside and outside) for strain relief on the cable.

Wiring up the LED boards (optional)

LED boards in the top case

If you use the LED boards, things should look like in this picture now. You'll need to connect all the boards with the supplied short wires to each other and solder one of the connecting wires up to the Teensy pins. The order of the wiring doesn't matter, the solder bridges of the i2c pins are what's making them match to their potentiometers.

LED boards in the top case, wired up

This is how it looks after you attached all the connecting cables between the LED boards. One on the first board is still disconnected, we'll solder this up to the Teensy next.

LED boards in the top case, wired to the Teensy

Connect the red wire to the 5v pin on the Teensy. The blue wire goes to pin 19 (SCL0) on the Teensy. Green wire to pin 18 (SDA0). The black wire goes to the ground pins on the perfboard. Yellow wire goes to the 3v3 pins on the perfboard.

That wraps up the build!
Like I wrote above: Put a micro USB cable through the back hole of the bottom case, connect the Teensy and wiggle everything in place so you can close the case. If you're worried about it, you could use hot glue to fix the boards in place and use 2 cable ties (inside and outside) for strain relief on the cable.

Building & uploading the firmware

The code is a platformIO project so you'll have to have it installed. I'm using platformIO core from the command line but the VSCode extension should be fine as well.
Clone the project from the repo to your computer.
If you have platformIO set up, make sure you connect the Teensy to your computer via USB and be sure that it is the only Teensy that is connected. Then run pio run --target upload from the main directory of the repo and that should be it.
If you would like to change the LED color from the default blue, you can do so in main.h.

Software Setup

Setup in Bitwig Studio

Install Driven By Moss so you can use its Generic Flexi script. Make sure the ottopot is connected.
Download this settings file and put it somewhere on your computer where it can stay.
Then in Bitwig's Settings->Controllers, add a controller, and select the Flexi controller script. For input and output port, use the ottopot MIDI ports. Scroll down a bit until you see the Load/Save section and press “Load”. Select the file you downloaded. That's it it; your remotes should now be controlled by the ottopot and the LEDs should be updated depending on the selected remotes.

Setup in Logic Pro

Open Smart Controls and press Learn Assignment for the first knob, then wiggle the first knob on the ottopot. Logic will pick up that it is a 14bit CC. Sadly you will need to disable the Feedback feature in the assignment settings since Logic doesn't seem to send usable 14 bit CCs back to the device (only the LSB will be sent, not the MSB). This also means that it will only work with the annoying “pick up after scrolling past” mechanic.
If there is enough interest, I could probably write a controller script for Logic to fix that.

Future goals, ideas


Bjørn and Juan for their work on the Endless Potentiometer code.

Input Labs for making the Alpakka controller and giving me the confidence that a homemade 3D printed product can easily rival industrially made commercial solutions.

Michael from CapraDesignStands for the advise and in advance for the help with the PCB.

Divergent Waves for helping with KiCad and the PCB.