build log

Building Tannin 2

In this post, I’ll be talking about build process of my latest and greatest MIDI controller; Tannin 2. It took me almost 5 months to actually finish it since there were so many architectural changes in it that I basically started from scratch.

The design

Tannin 2 design is, naturally, very similar to the original Tannin controller (incidentally, I never actually wrote a post about that one since it was finished some months ago before I started this blog). Since Tannin 1 is first Shantea Controls controller ever built, it has a special meaning for me – not so much as a physical product since it’s disassembled (I used some of its parts for Tannin 2) – but more as an idea. I had to make sure that Tannin 2 would be a worthy successor. For the reference, here’s the rendering of original Tannin controller:


Assembled controller:


And one from the back:


I can assure you it looks much better on the pictures than it really looked.

It had 16 potentiometers and 16 buttons in 4×4 grid, 3 additional metal buttons and 4 LEDs at the bottom. Very simple and very efficient layout. Over the time, I got used to it so much that I mapped virtually every function I need in my DJ software (Traktor Pro) using nothing but this controller. Still, it was my first controller, and naturally it had some flaws. First and most obvious one, there were too many screws. Second, that box was huge, too heavy and after few months it started to crack all over the place. It was also such a pain in the ass to carry around. On the hardware side of things, it featured Arduino Nano and circuitry that later became the basis for OpenDeck board. If you’re wondering what’s that chemical – it’s Flavan-3-ol.

So, now that we have Tannin 1 as a reference, let’s move on to Tannin 2.

Tannin 2 was imagined to be an improvement in every area – not just the flawed ones. When I thought about the design, I was trying to figure out what was missing in original controller. First of all, I wanted better buttons than those tactile ones and more LEDs. I also wanted either faders or encoders. Eventually I discarded the faders idea since it was impossible to fit them in same dimensions (I wanted to keep plate dimensions exactly the same – 200x300mm). So, after some consideration, this is what I came up with:


As you can see, design is really similar to original Tannin, but with few tweaks. Below 16 potentiometers, I wanted to have 4 encoders, and under them 16 silicone buttons with white LED inside each of them. 4 LEDs at the bottom got removed since a) I didn’t have much room left, and b) who needs 4 LEDs at the bottom when you have one in each button above? Potentiometers and metal buttons remained the same. I also added number 2 to Tannin name, even though it actually looks like letter ‘R’. Tannin Remixed? Acceptable as well. Notice that there are only few screws in this one. All in all, I was happy enough with that layout to proceed to actual build process.


As with the Ceylon controller, I wanted to experiment a bit with plate color. This time, I picked green one, and it really looks great – same as any gravoply plate.


The case

Until I built this controller, cases were always source of biggest frustration, since – let’s face it – they looked like crap, and thus ruining the overall feel of entire controller. Well, I didn’t want to go through same story again, so for a couple of weeks I was searching for someone who would do the job right. Whether or not I was successful, judge for yourself:


And back.


Finally, I have gorgeous case! That green plate really blended well with the tone of the wood. Also, its weight is just about right, not too light (it’s wood after all), and actually not heavy at all. Perfect!

One more thing – I redesigned USB cable plate:



For second revision of Tannin controller, I decided to use PCBs crafted specifically for Tannin 2, instead of using OpenDeck reference board. This proved to be a very challenging task, as I literally had to do everything from scratch. The main premise behind designing electronics for this one was that I was going to use ATmega32u4 as microcontroller. In the past, I used either Arduino Nano or Arduino Pro Mini. Both of those boards are fine on their own, however, the biggest drawback to using them is that they have no native USB capabilities. In practice, this meant that I had to use serial-to-usb adapter to program them and couple more layers of software to make them talk MIDI. In my commercial designs I also used those boards, but in addition to main board I used USB MIDI board which translated serial signals from Arduino to USB MIDI. Works just fine, but that USB MIDI board doesn’t support MIDI System Exclusive (primary method of configuring the controller) and it represents additional hardware. So, using ATmega32u4 solves both of those problems since it has USB built right into the chip. In case you didn’t know, Arduino Leonardo, Arduino Pro Micro and Teensy 2.0 use that exact microcontroller, however, this time I needed my own custom board. I needed it to be as small as possible – so Leonardo was discarded right away, I needed pretty much every available pin – discarded Pro Micro at this point as well and I also needed ability to use a custom bootloader for uploading new firmware to board. Now, you absolutely can put a new bootloader on a Teensy board – but you can’t upload the new code on it using Teensy loader then since that bootloader is proprietary, an aspect of Teensy I’m not particularly fond with. So, when you put new bootloader on Teensy, what’s the point of buying Teensy in the first place? Also, it was cheaper to buy pure ATmega32u4 chip with few external components than buying Teensy. I’ve been delaying this design with each controller since I figured that soldering SMD is going to be much harder than soldering standard DIP packages. I was right, but just because it’s harder doesn’t mean it’s impossible. You just need steady hand and some patience. The final result was this:


Only 5x5cm! Obviously, main component is ATmega32u4, the mighty brain which does all of the processing. Next, it features my standard hardware for LED/button matrix, 74HC238 decoder and ULN2803 current sink. For reading button rows, this time I added 74HC165 shift register. I had few 4021 registers lying around, but 165 register can work a bit faster, so that’s why I’ve chosen it. I also added reset button, ICSP header so that I could program it with external programmer (USBasp) and also MIDI header, which is nothing more than +5V, GND and RX/TX serial pins from microcontroller. Having them on header allowed me to test hardware MIDI on this board as well, and it works! This means I can expand this board with real DIN MIDI in/out connectors. Not that I have any use for it at the moment, but since this board will serve as a basis for OpenDeck v2 reference board, I wanted to see how it’s going to behave. Board also features pin headers on the edges to connect potentiometers, buttons, LEDs and encoders. One resistor is missing in this picture – at that point I was unsure what to do with HWBE (hardware boot enable) pin on ATmega, but more on that later.

Now, having the main board finished didn’t mean I was done with electronics. At all. First of all, those silicone buttons needed a PCB. Encoders also needed a PCB, and potentiometers as well. That’s lots of PCBs. I ended up designing a single 10x10cm board with panelized designs for each part. In total, I needed 4 separate PCBs for buttons, 2 boards for encoders and 2 boards for potentiometers. I also needed a small board for USB connector which would be housed in the box. Luckily, I managed to fit all of that in a single board, and the guy who cuts gravoply plates for me also did the cutting of PCBs.


To make one controller, I actually needed two of those boards, however, you can’t order less than 10 pieces, so that wasn’t a problem.


Free candy! I mean PCBs!

This is how Tannin 2 looked inside after first round of soldering:


Analog boards feature one 4051 multiplexer each. One of them is “slave”, other is “master”. This only means that slave (right one) connects to master (left one) using 6-pin IDC cable. That allowed me to use only 7 wires from master analog board to main board. Encoder boards feature 5 pins each. Both boards also connect to main board. Four boards with LEDs and silicone buttons have shared columns, so each board connects to the next using four wires. Finally, those four wires are connected to main board. Boards also have one LED/button row wire each, so that’s two additional wires from each of the four boards to main board. Three metal buttons below also connect to main board on assigned pins.


I used some hot glue to ensure the wires don’t move and break. Each board has one resistor for LEDs and 4 diodes for button matrix (there are actually 2 diodes per package so there are 2 packages per board). Diodes for three metal buttons are placed on main board.

Since encoders are nothing more than a two buttons, they are connected in separate button matrix. Reason for separation is that button/LED matrix switches columns every 1ms, and that’s too slow to read encoders properly. Setting the matrix to faster switching rate would result in LED flickering since I also needed PWM for LEDs.

Final look inside:


That wooden part makes sure the button PCBs don’t bend. Also, main board is designed so that it fits perfectly on four screws holding two PCBs together. Finally, I added some hot glue to secure all contacts:


Entire schematic will be available on my GitHub at some later date.


As I mentioned before, Teensy 2.0 board uses ATmega32u4, same microcontroller that I picked. Even though Teensy boards are compatible with Arduino, software is of much higher quality and they can also be programmed as USB MIDI devices, something Arduino boards aren’t officially capable of doing (at least in Arduino environment). Selecting Teensy 2.0 board in Arduino IDE and then trying to upload it to Arduino Pro Micro or Leonardo won’t work because Teensy uses Teensy Loader to load software on board, which in turn communicates with their HalfKay bootloader, which you can’t download. However, I needed that USB MIDI stack that Teensy boards provide. So, I simply connected my main board to USBasp programmer, selected Teensy 2.0 as a board, USB MIDI as device type and uploaded it to board. Note: if you want to upload code to Teensy/Arduino using external programmer, simply hold shift and then press upload. That worked flawlessly! Board immediately showed up as Teensy MIDI on my computer. Awesome! Now, the hard part was moving all of my existing OpenDeck code to Arduino-style format. In the process, I integrated most of Ownduino functions directly into OpenDeck library. I could talk about the software part for hours, but you can easily check the code yourself on my GitHub. This was all very nice, but every time I needed to change something in the code, I needed to connect external programmer to main board. In practice, this meant constant opening and closing of controller – quite tedious. I needed a bootloader and I found one. It’s called USB Mass Storage Bootloader and it’s really fantastic. After you reboot your board into bootloader mode, your PC shows a new device connected to your PC: removable drive! It shows two files: EEPROM.bin – which contains all parameteres stored into EEPROM (obviously) and FLASH.bin – the compiled code. To upload new code, simply delete FLASH.bin, copy new one, eject the drive (very important – ejecting it actually triggers the upload process), and then simply reconnect controller to USB.


The trouble I had with bootloader was that the controller was constantly turning on in bootloader mode – it never showed as MIDI device. Later I found out I need to change certain fuses on microcontroller. USB AVR microcontrollers generally have two fuses responsible for deciding whether to run user program or bootloader: BOOTRST and HWBE. If you enable BOOTRST, microcontroller is going to run bootloader everytime it’s reset. HWBE, on the other hand, acts a bit differently. If you enable HWBE and disable BOOTRST, your device will reboot into bootloader only if HWBE is shorted to ground before you turn on microcontroller. This is why you need to hold reset key on certain devices before you can update firmware on them. I figured I don’t really need any of these fuses, so I disabled both of them. I want microcontroller to always run application program, and bootloader only on demand. To trigger the bootloader reset, I need to send specified MIDI System Exclusive message to controller. After that, controller reboots into bootloader mode, showing as a disk drive. Just what I want. Great! Another puzzle was how to generate that FLASH.BIN file? I only use Arduino IDE for testing out stuff and use Atmel Studio for any bigger project. After you compile project in Atmel Studio, it generates .hex, .elf and few other files inside your project directory. You can also define “external tools” in Atmel Studio. I defined one such tool to convert .elf to .bin. Basically, you need avr-objcopy tool with these parameters:

-O binary -R .eeprom -R .fuse -R .lock -R .signature <compiled_project>.elf FLASH.bin

I only need to figure out how to do that automatically after compilation so that I don’t have to manually invoke the command.


This is how controller looks right now – fully assembled:


So, here’s a quick video showing Tannin 2 in action. Notice how LEDs fade now – I finally added PWM support with selectable fading speed using System Exclusive.

19 thoughts on “Building Tannin 2

  1. Very nice project, will have to dig in a little more.

    Have you looked into Copperlan (Midi over ethernet) their C++ SDK is now free to use. A native sysex system in Copperlan would be awesomeness:

    You could build a Copperlan (ethernet) port into your controllers and have it be just another node on the network. Once all the routing is done in CopperLan Manager, you dont even need a computer to run all the midi gear, because all the nodes hold the routing info.

    Their also working on integrating audio and making the whole experience even easier.


    1. Hey! No, it’s a board built exclusively for Tannin 2. At the moment I’m designing v2 of the board, and it should be ready within month or two (two more likely) – then you can buy it!

      1. Looks pretty straightforward at all, v2 will be use the same modular idea?
        My controller burned so i want to bild my own. Arduino+usbserial converter is not the right way, as i think. Livid Brain Jr seems doesn’t meet all my needs – many potentiometers and only 4 encoders fit in digital pins, with no buttons, but so many analog ports will be unused

        BTW for encoders – it will be possible to handle not just a rotation, there is another pushbutton built to many controllers inside of any encoder

      2. Yes, v2 will run exactly the same software as Tannin 2 does. In fact, all of my controllers run the same OpenDeck platform code, with minor differences due to pin layout. In that sense, v2 board will be based on Tannin 2 board. About the components – v2 board will support 64 buttons (32 encoders), 32 analog inputs, 48 single-color LEDs (16 RGB LEDs), as well as DIN MIDI in/out ports. 10x10cm size. Price wil be the same as Brain Jr.

  2. 4 – Button pad looks very wide on the one side, if it will be placed horizontally. Maybe, it will be possible to drill holes for pin headers. And what is the difference between B1/B2 and B3/B4?

    1. I’m not sure what do you mean. As for the last question, there is no difference, I just labeled it that way because both boards are part of bigger PCB which featured panelized design. However, there is difference between two boards with potentiometers.

      1. But why would I (or you) turn it that way? Again, each PCB inside Tannin 2 is made *specifically* for Tannin 2 with specific way of connecting and placing them.

      2. I just love sugarcube buttons 🙂 But i didn’t found any kits, which can be divided to 4×1. But i think, i can make pcb for buttons by myself if you will provide wiring scheme in the future

      3. I don’t see the point in releasing those PCB files since they won’t be compatible with new OpenDeck board due to the different button/LED setup. However, if you’re interested in kit with those boards, we can discuss the details via email. You can find it in “About” section.

  3. Is there a way to build a “midi converter box” which can be used for old dual cd/mp player (like denon dn models) to use the remote interface as midi controller ?

    1. I’m not quite sure what do you mean. What kind of remote interface? You can connect MIDI out from any device to MIDI in on OpenDeck and configure it as MIDI-USB converter.

    2. It’s impossible. Use timecode. Or you can just disassemble remote panel to get buttons and encoders, you can even use parts of its circuit and box. Or…. you can do reverse research of protocol which was used in wired connection between front panel and player module to receive buttons/encoders state… Some microcontroller and programming will be needed

  4. Hey, great thing you’ve done pretty design everything is cool.
    Would you like to share the pcb for avr (ATmega32u4..) bcz I really want to make one for me.

    1. Hi, glad you like it. Tannin PCB design is now obsolete (it also had some hardware bugs). My new reference board is now OpenDeck – you can download schematic and code on my GitHub, however, PCB design is not public.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.