Building a distributed MIDI Controller with Android Things and Nearby API #2

This is the second part of my blog Building a distributed MIDI Controller with Android Things and Nearby API, which if you dear reader have not read but were curious enough to venture into this entry, I encourage you to do so as it outlines the background, the challenges and the concepts upon which we merely build upon here, which result in a more complete solution — a two channel, 3 EQ each DJ mixer with 2 FX and start/stop buttons and a vertical volume slider potentiometer each. The finished product will allow us to fully mix two channels in DJ Traktor software effectively becoming a most basic, but functional performance mixer that you can rock your part..err, bedroom with. OK, without further ado, let’s dive in!


What’s new — Hardware

In the last entry we put a MCP3008 8-channel ADC into a breadboard and connected one rotary potentiometer to it. This time we are going to utilise all 8 channels, enabling us 3 EQ pots + 1 volume pot per channel. We are also going to add two additional buttons, to the existing two, that we will use for start/pause function per channel, leaving the other two to function as toggles for two FX modules of our choice. This, again, is merely an expansion on our previous module so let’s just paint a picture instead of explaining any more:

In detail:

  • A Raspberry Pi 3
  • A breadboard — one large one or a couple of small ones
  • 10KΩ resistor x 4
  • Push button x 4
  • MCP3008–8-Channel 10-Bit ADC
  • 10KΩ Linear rotary potentiometer x 6 — I used these
  • 10KΩ Linear slider potentiometer x 2 — I used these
  • Potentiometer Knob (optional) x 6 — I used these
  • Enough male-to-male and female-to-male wires to wire it all together

…and wired up like this:

  • All Pots to pins 1–8 of the ADC, GND, 3v3 (blue, black, red wires)
  • All Buttons to pins 26/23/6/5 and GND, 5v (brown, black, orange)
  • ADC pins, as mapped below, 16&15 -> 3v3, 14-> (analog) GND, 13-> SPI0 CLK (BCM11), 12-> SPI0 MISO (BCM9), 11-> SPI0 MOSI (BCM10), 10-> CS0 (BCM8), 9-> (digital) GND

Although for prototyping in the first blog a small breadboard was enough, in order to operate a mixer fully intuitively, one would expect the sliders and the knobs to be laid out in a typical mixer manner, with two vertical banks of controls per channel. This means that we will need some sort of an enclosure into which we can place our control surface, without having to worry about plugging out a wire from our breadboard or two.

As a person not terribly experienced with DIY I chose to improvise with a solution I would not hurt myself with and one not requiring too much investment. It just so happened that something quite useful for the job I had around the house, which with a little imagination and careful planning I managed to turn into a semi stable enclosure. Behold, a mixer encased with a big box of mini Tic Tacs :-)

Testing the soldering
Enclosure done

In case you want to build an enclosure from same materials you will also need a good soldering iron and bolts that will fit the holes in the slide pots (3mm).


Software

OK, with the hardware out of the way, let’s focus on what’s changed in the software element since the first iteration.

1 Pot -> 8 Pots

Pots are controllers which only publish changes in the analog value of a controller they are mapped to with a static key notation per a controller. What this means is that although a key on a keyboard is mapped to a given controller, that key is static, and in effect identifies your controller. Therefore, our MidiPot instances can share one MIDI Channel, and in that channel they will be identified by different keys (notes). Here we’ve chosen all pots to share channel 10 and their IDs to be resolved by notes in the first octave. The only variable value per pot is the change (or velocity).

This in effect will allow us to map them in Traktor to Ch11.CC.<019–024>, which mean Channel 11, Control Change, corresponding key ID.

2 Buttons -> 4 Buttons

Not much has changed in the domain of the buttons except that, like the pots, we have removed the knowledge of their corresponding pins and on instantiation their address is assigned by the MidiControls class. Unlike the pots, buttons send NOTE_ON events, meaning they specify that a note (key) has been pressed and thus they need to specify which key it is. Therefore they can’t be restricted to covering one key on the keyboard each and in effect a MIDI Channel identifies each button and not a key.

And that’s pretty much it! All that’s left is to map our control surface…

…and start having fun!

*Bottom-left knob began misbehaving so I replaced Mid EQ for Low and used bottom-right for Filter Adjust

What’s next

This rudimentary solution was a lot of fun to put together and although my slightly more advanced MIDI mixer I had purchased about 10 years ago had set me back £80, the overall cost of this project was about half that. However, I believe that you can’t put a value on the knowledge and fun gathered building it and that’s what I find most exhilarating about Android Things — ability to prototype real life solutions that combine software and hardware.

Secondly, I don’t think that I am done with the project. First of all, it’s clear to see I haven’t chosen the best enclosure, which has limited my ability to add buttons to it, instead having to opt to using an additional breadboard. I would like to fix this with a custom made enclosure with better access to the cables. Lastly, the RPi has twin SPI Chip Select pins — BCM8, which we’ve used here, and BCM7 which should allow us to add another MCP3008 ADC for extra 8 analog channels. A better enclosure should allow me add another row of pots and a crossfader, which could be mapped to any additional controls in the software. These additions will probably not call for another blog as it should be clear how to go from what I have already written. Either way, I hope you enjoyed reading about this project and if you have build it as well, do let me know.

The source code for this project is available on Github.