Category Archives: design

OpenDeck platform v1.0

You’d be forgiven for thinking that OpenDeck project is dead, as well as this blog – after all, it’s been more than a year since the last update. While it’s true that in the past year I haven’t had much time to work on the platform, last couple of months have been full of development again, and this post is an announcement of OpenDeck v1.0 – stable version of firmware, hardware and Web configuration utility. This time, I’ll concentrate on user-facing changes only – low-level changes are going to be discussed in future posts.

In case this is your first visit here, I’ll copy OpenDeck info straight from GitHub:

OpenDeck is a platform suited both for prototyping and developing custom MIDI controllers compatible with any MIDI software on any OS. Main part of the platform is board on which various components used to build a MIDI controller can be connected. The board supports the following components:

  • Buttons
  • Encoders
  • LEDs (single color or RGB)
  • Potentiometers
  • FSRs (force-sensitive resistors)


Since my last post, OpenDeck board went through two revisions. I’ve fixed some stuff, and added some as well, however, the basic layout is exactly the same, as well as dimensions. Final version of the board is black – it sure does look nicer compared to ugly green one.


Now there are three indicator LEDs, compared to two on last revisions. One is for power, and other two are active when there’s MIDI traffic on board (one for input and one for output). Those two LEDs serve double-purpose, as they’re both on while in bootloader mode.

On MIDI side of things, I’ve replaced 6N138 optocoupler with way-faster 6N137.

Configuration utility

This is the big news. Really big. Ever since Google announced the support for Web MIDI in Google Chrome, I wanted OpenDeck configuration utility to run inside it. Building one app which runs on any platform is definitely better than coding three different apps for Mac, Linux and Windows. Since my knowledge of web is pretty miserable, I’ve hired two guys (programmer and designer) to design and build configuration utility based on my specs. I don’t know much about low-level details of utility, but I do know it involves some magic words such as “Angular” and “Javascript”. Concept of utility is actually pretty simple – it has sidebar containing configuration blocks available on OpenDeck – MIDI, buttons, LEDs, encoders and analog stuff. It also has activity log, displaying all incoming and outgoing messages, info window and backup and restore functionality. All configuration is done using custom SysEx protocol explained here. Below are the screenshots.

MIDI configuration block

On MIDI screen, user can configure couple of settings related to MIDI protocol itself, as well as channels for MIDI messages used on OpenDeck. Toggling DIN MIDI in to USD MIDI out will result in all MIDI traffic received via DIN MIDI in connector being forwarded to USB MIDI out, so any older MIDI gear can be used as USB MIDI controllers using OpenDeck  board. You can read more about running status and note off messages here.

Button configuration block

Button window lists all buttons which are possible to configure on board. Even though board has 64 inputs for buttons, 32 analog inputs can be converted to digital inputs (that is, buttons), resulting in total of 96 possible buttons. One of the cool features of utility is that pressing the button connected to board will automatically blink the correct button ID in utility, so that you don’t have to waste time finding it. You can read about how is that accomplished here. Another cool thing is that number of buttons (or anything else) isn’t hardcoded, but generated by the utility. Before the configuration section is rendered, a request is sent to board asking it how many buttons are possible to configure, so utility is future-proof if I’m ever going to increase or decrease number of buttons, encoders etc.

Single button configuration

Clicking on certain button brings up modal window which lists all possible parameters for single button. Here, user can configure button as momentary or latching. MIDI message sent by button can be chosen as well (note or program change) and also, any MIDI ID (0-127) can be assigned to specified button. MIDI ID is used as note or program, depending on which message type is selected.

LED configuration block

LED configuration lists some global parameters applied to all LEDs, as well as list of all LEDs which are possible to configure. OpenDeck supports 48 single-color LEDs, or 16 RGB LEDs, since RGB LED is actually three LEDs in single case.

Single LED configuration

Any LED can have assigned any activation note (0-127). When local control is disabled, LED is controlled with received MIDI note and velocity. You can read more about LED control here. When enabled, any button which sends note same as activation note will control the LED instead. LED can also be configured as RGB LED. Last two options are used for testing LED states (when RGB LED is enabled, different colors can be picked from state test field).

Encoder configuration block

Encoder section displays total of 32 encoders. 64 digital inputs available on OpenDeck can be used to connect those 32 encoders (one encoder takes 2 digital inputs). Note that analog inputs cannot be used to connect encoders.

Single encoder configuration

Encoders need to be specifically enabled in order to function. Encoders send CC messages, and any CC number can be assigned to specific encoder (0-127). Two encoding modes are available: 7Fh01h and 3Fh41h, which can also be inverted.

Analog configuration block

Analog configuration section displays total of 32 components.

Single analog component configuration

Analog components need to be enabled in order to function. This is to avoid junk coming out of floating analog input when nothing is connected to it. All analog inputs can be configured as potentiometers, FSRs and buttons. Default is potentiometer. Any MIDI ID can be assigned (0-127). Potentiometer type will send CC messages with CC number specified as MIDI ID, FSR type will send MIDI note event with note being MIDI ID, and button type will send note event specified in button configuration section. Invert option applies only when potentiometer is active type. Lower and upper CC limits can be used to scale CC values coming from potentiometer and FSR.

Info window

Info window contains some basic info about the board (firmware and hardware version). Checking for updates is done by comparing last tag on OpenDeck GitHub to firmware version currently present on board, which is a very cool feature. Other options include rebooting the board, factory reset and bootloader mode, which is used for firmware update process.

I can say I’m very proud of configuration utility, as it’s one of the first WebMIDI apps used for configuration using SysEx messages! Building a MIDI controller sure does seem easy now. I haven’t had the chance of testing it on Linux distros yet, but it works (mostly) flawlessly on Windows and Mac OS X – mostly because of WebMIDI still being finicky. For instance, MIDI connection sometimes won’t be detected, and leaving the utility idle for some time can sometimes lead to issues. On top of that, Google also requires SSL connection when using SysEx messages via WebMIDI which is a real PITA. Really Google? I hope those issues will be resolved one day, but for now, I can live with it. I also hope other Web browsers will include support for WebMIDI soon – not everyone likes Chrome. There is some activity with WebMIDI implementation in Firefox, though.


Undocumented code is worthless. I’ve written extensive wiki on OpenDeck GitHub, so you can check entire documentation here – everything from schematics, connection diagrams, SysEx protocol, firmware update process etc.

Open Source

Most of OpenDeck really is open. I’ve done my best to write clean and efficient code and document entire project. Exceptions to this are board design (gerber files) and Web utility. Those two things are truly custom solutions, and OpenDeck is a platform open enough to be used without them, since my GitHub contains complete schematics and full documentation on SysEx protocol. Maybe someone will build a better board and better configuration app – who knows? In the meantime, my board and utility really are the only incentives for someone to actually spend any money on OpenDeck. At the end of the day, whenever someone buys it, it will make me invest more time into platform, which translates to less bugs, more features and possibly new products. So far, development of platform has been pretty slow. Supporting it will definitely change that.


Now that board, firmware and configuration utility are ready, you can contact me for pre-order. Pre-order here means that I’ll send the boards to manufacturing once I receive at least 10 pre-orders. I’m selling the board for 111€. Package contains:

  1. Board
  2. USB cable
  3. MIDI cable
  4. Access to online web utility
  5. One year guarantee

Bugs and feature requests can always be reported here.

Thanks for reading!

Building Ceylon

This is a long overdue post about Ceylon, another Shantea Controls controller, only this time, one that I’ve built for myself. Of course, it’s based on OpenDeck platform.

Ceylon was actually built about three months ago. Reason why I haven’t written about it is a combination of things really. First, it was in a beta period for more than a month, and after that I just didn’t have much time to write posts, as I was really busy (and still am) with other projects that I’ll hopefully write about soon.

Name and design

Let’s start with a name. After Anandamidi and Sensimidia, it was time to bring back tea in Shantea Controls again. So, Ceylon is actually well-known high-quality tea originating from Sri Lanka, former British colony known as Ceylon (hence the name). There are couple of variations of it, black one being my favorite (with some spices of course, that is, loads of ginger).


Picture above is a rendered drawing of Ceylon design. Numbers around the circle are coordinates of Kandy District, heartland of tea production in Sri Lanka. So there you have it, a Ceylon story!


Since Tannin was my only controller so far, I’ve mapped nearly every function I need, so when I started designing my second controller, I wanted something really simple that would complement Tannin well. There was no need for a complicated layout or redundant functions, that’s why its design is really minimal. There are 3 faders, 12 orange LEDs for some eye-candy, err, I mean VU-meter, shift button, two potentiometers above faders for gain control, six anti-vandal switches with blue LEDs, and disk. Most significant change here from Tannin is the use of encoder. Well, not your usual encoder though. It’s a salvaged HDD motor acting to be encoder actually.


Ceylon is first controller I’ve built which doesn’t use standard black/white Gravoply plate, as I grew tired of it. Instead, I’ve picked blue plate this time, and it looks really gorgeous.


I also redesigned USB plate.


Case is white again, just like Tannin.

The disk

As I’ve already stated, only thing new in Ceylon is the disk. So, how does it work? The motor in mechanical hard disk generates phase-shifted sinusoidal waveforms when spinned. The faster you spin it, larger the amplitude and frequency of waveforms. By examing waveforms, you can determine disk direction, which is what I needed. There are couple of issues with this:

1) Signal amplitude is way too low to be sampled directly by a microcontroller, unless you spin the disk real fast, which is kind of missing the point of whole setup as you want fine grained control. My measurements showed that disk generates +-500mV when spinned at maximum speed (maximum being somewhat subjective term, I spinned it by hand).

2) For encoders, you don’t actually need analog signals, but digital ones. By examining output data from two encoder pins, you can easily determine its direction. Those two outputs are called quadrature outputs, as they are 90 degrees out of phase.



Making the signals digital

Basically, what this setup needed was ADC (analog-to-digital converter). For this use, I’ve chosen LM339, a very cheap, available and popular comparator. LM339 contains four comparators in a package, making it suitable for this setup, as I needed only two. Comparator takes two inputs, and simply determines which one is bigger. If voltage on non-inverting input (+) is larger than voltage on inverting input (-), output is digital 1, or Vcc, and if non-inverting input is smaller than inverting input, output is digital 0, or -Vcc (in this case GND). Very simple. But as usual, there are couple of caveats.


Connecting motor inputs directly to LM339 isn’t such a good idea, for two reasons:

1) What happens if two signals are very close to each other? Comparator would output bunch of ones and zeros very fast, which is actually junk, so you get unreliable results.

2) According to LM339 datasheet, you cannot apply more than -0.3V at either of its inputs. This is a problem, as disk actually outputs about -0.5V when spinned real fast.


It took me really long to figure out what hysteresis actually is, but it’s actually really simple. Using hysteresis on comparator, you are creating two thresholds for generating two output states, that is, you are setting one threshold for output to be Vcc, and second one to be -Vcc, that is GND. This is achived by applying positive feedback from output back to input, using two resistors. Since signal from motor is really low, I’ve designed hysteresis for low values, just to keep signal from circling around switch point. Hysteresis is calculated using this formula:

Vth+ = -VN ∙ (R1 / R2)
Vth-  = -VP ∙ (R1 / R2)

Vth is threshold voltage, Vn is negative output (in this case 0V), and Vp is positive output (+5V in this case).  I wanted to set positive threshold above 0V, and negative below -5mV, so resistor values are 1k for R1, and 1M for R2:

Vth+ = -0 * (1000/1000000)
Vth+ = 0V
Vth- = -5 * (1000/1000000)
Vth- = -5mV

So, when positive input voltage is above 0V, output is 1, and only when negative input drops below -5mV, output is 0. This way I created “dead zone”, or area where my signal can be of any value (between 0 and -5mV), without affecting the output of comparator.


Graph is showing the input signal (U), usage of comparator on that signal without hysteresis (A), and output signal from comparator with applied hysteresis (B).


Picture above shows hysteresis setup. This is how you debounce your inputs using hysteresis, so that your output never becomes gibberish.

Voltage clipping

Now, there is one more concern. As I stated already, inputs on LM339 cannot be smaller than -0.3V. To accommodate this, I used BAT46 Schottky diode on inputs, having anode connected to ground. When the input is positive, diode doesn’t do anything as current cannot pass through. When the input is negative, diode still won’t do anything, as long as input voltage doesn’t become smaller than -0.3V. Those diodes have a voltage drop of about 0.3V (how convenient), so, when input voltage exceeds -0.3V, current will pass through diode, and voltage on comparator input will actually be voltage drop on that diode, and it will not exceed those -0.3V. Two problems solved, yay!


Software side of things

Now that I’ve taken care of hardware, it was time to actually read and process signals from motor. For this, I’ve used modified encoder library for Teensy/Arduino. Library is great as it has two really clever parts:

1) Since it’s written with Teensy/Arduino in mind, it automatically detects whether the pins on your microcontroller on which you’ve connected encoder have interrupt capability. If they do, library reads encoder using interrupts. Since HDD motor can be spinned real fast, I’ve connected both motor pins to interrupts (pins 2/3 on Arduino) in order not to miss any pulse. Pins 2 and 3 are two out of four unused pins on my OpenDeck board, so this was very convenient.

2) It has “predicting” algorithm, giving your encoder 4x more resolution. This is achieved by remembering previous state of pins, and comparing it to current state of pins with a lookup table. Lookup table contains valid encoder transitions:


This works really, really well, but since HDD motor jumped a bit when changing direction, I’ve implemented additional debouncing:

void OpenDeck::readEncoders(int32_t encoderPosition) {
if (_board == SYS_EX_BOARD_TYPE_OPEN_DECK_1) {
if (encoderPosition != oldPosition) {
if (millis() - lastSpinTime > ENCODER_DEBOUNCE_TIME) initialDebounceCounter = 0;
if (encoderPosition > oldPosition) {
if (!direction) { initialDebounceCounter = 0; direction = true; }
if (initialDebounceCounter >= ENC_STABLE_AFTER) {
sendPotCCDataCallback(127, 127, 5);
} else initialDebounceCounter++;
else if (encoderPosition < oldPosition) {
if (direction) { initialDebounceCounter = 0; direction = false; }
if (initialDebounceCounter >= ENC_STABLE_AFTER) {
sendPotCCDataCallback(127, 1, 5);
} else initialDebounceCounter++;
oldPosition = encoderPosition;
 lastSpinTime = millis();

If there is a movement detected, code first checks for whether the disk hasn’t been moved for more than ENCODER_DEBOUNCE_TIME (70mS). If it hasn’t, it resets the debounce counter. This is to avoid extra pulses when disk is slowing down. After that, initialDebounceCounter variable is incremented until it reaches 1. This is to prevent disk jumping when changing direction.

So there you have it, a pretty good resolution from HDD motor for use in MIDI controller! In all honesty, its resolution is far from optical encoders, but as this is more of a proof-of-concept, I’m really satisfied with results.

LEDs on anti-vandal switches

This was another issue that I had while building Ceylon. Anti vandal switches (the ones around the disk) I had around have blue LED on them. Their pins are separated from button pins. Those button pins can be connected in NC and NO configuration, so there’s 5 pins in total. Since I’m using shared column button/LED matrix in my OpenDeck platform, I’ve connected – pin of LED and one of button pins together, going into same column, and then + pin of LED into LED row, and second button pin to button row. Nothing out of ordinary, right? Well, something weird was happening with this setup. Whenever I pressed the button, LED on it lighted up. This is not the behavior that I expected nor wanted, so for a while I had no idea what was happening. Only few days later, I’ve discovered that it doesn’t really matter where you connect + and – of the integrated LED on button, since there are 2 LEDs inside, one of which has anode on + pin, and second one on – pin.

anti vandal configuration

Okay, but why does the LED turn on when button is pressed? For this, answer is in matrix setup. LED/button matrix works by switching columns very rapidly. Only one column is active at the  time, and during that time, it is connected to GND, while others are connected to Vcc. When button is pressed, connection from microcontroller input on which button is connected goes to GND, and button press is registered, but only during the time the column is active. When column isn’t active anymore, it’s connected to Vcc. Since those switches have two LEDs inside, one of which has anode on – pin, when button is pressed, and column isn’t active, that anode is actually connected to Vcc, and LED row on microcontroller starts acting like current sink, so LED is lighted up.


In order to solve this, I’ve placed Schottky diode (to minimize voltage drop) between LED anodes and microcontroller LED row pin, so that the current is blocked for second LED inside switches.



So, to conclude this post, here’s a short video of Ceylon in action, together with Tannin.

And also some higher quality pictures of Ceylon.

IMG_8551 IMG_8553 IMG_8565

Thanks for reading!

Sensimidia MIDI controller

Sensimidia is third Shantea Controls controller, and also my second commercial project. I’ve been working on it for the last two months, but most of that time I did nothing, because of some delivery issues with faders and box. Now that it’s finally over, I’d like to present it here.

SensimidiaIn many ways, Sensimidia is similiar to Anandamidi controller. Same buttons, same pots, same faders, same mounting techniques – except for the faders, which I’ve done right this time. It features 24 buttons, 12 LEDs, 6 rotary potentiometers and 2 faders. I’ve also added two additional mounting screws to the plate to avoid its bending, although I should’ve added two more – one in the middle left, and one in the middle right. Design features logo from the guy who ordered the controller. It turned very cool, but then again, that board has magical capability of turning everything into something super-nice.

This controller is first controller I’ve built using my recently-announced OpenDeck platform, therefore, if you’re interested what hardware does this run, scroll few posts below. Worth of note is that even though it’s based on OpenDeck design, it doesn’t mean Sensimidia runs full version of OpenDeck software. Yes, buttons, pots, MIDI input – all of that works, but full controller configuration via MIDI System Exclusive messages doesn’t work yet. Luckily, that is nothing to worry about in this case, since the guy really wanted something simple that works out-of-the-box. I can always update the firmware on controller later – once the OpenDeck platform is finished, and also assuming the guy would actually want the extra features.

Anyways, here’s how Sensimidia looks all wired-up:

OLYMPUS DIGITAL CAMERAAs I said, it’s all very similiar to Anandamidi construction. This OpenDeck board connects to my MIDI USB PCB via pin header right above that electrolytic cap.

OLYMPUS DIGITAL CAMERAThis is how it looks in case. Very nice, but a bit too dark for my taste.

P1010005_crAnd standard USB plate for the cable.

All in all, very fun project again, even though it’s not been really that much different from Anandamidi. Here’s a quick video I’ve taken demonstrating some of controller functionality (really sorry for the lack of good camera and tripod):

Building Anandamidi controller, part 1

Anandamidi, MIDI controller with a strange name, is my latest project. Guy for whom I’m building it sent me basic layout and a name, while I’m working on everything else, from design (which always come first) to electronics and programming.


Let’s explain the name first. “Anandamide is a molecule that plays a role in many bodily activities, including appetite, memory, pain, depression, and fertility – hence its name, which is derived from the word ‘ananda’ which means ‘extreme delight’ or ‘bliss’ in the Sanskrit language” (Source). The molecule looks like this:


Anandamide molecule



Moving on to layout. Project is fairly simple, as far as component number is concerned. It consists of 8 switches, 2 rows and 4 columns on the left side of controller and another 8 on the right side. Middle part consists of two vertically placed faders, with 5 LEDs in column next to each of them. Next to each LED column are 3 potentiometers. Below that is another horizontally placed fader. That’s it actually.



After few days of playing in CorelDraw, this is what I’ve come up with:


I’m very fond of Ace Futurism font, so I’m using it almost exclusively in my designs. You can get font for free here. Anandamide molecule is used around the controller name, along with the logo from the guy who ordered it inside it.

Shantea Controls is a name for a imaginary company which builds custom MIDI controllers, and the sole employee is me.) The leaf represents Camelia Sinensis leafs, a plant used for production of green, black and white teas (hence the “tea” in Shantea).



The plate actually consists of two parts. First is black 3mm thick plexiglass on which black Gravoply plate is glued, resulting in a very professional looking product. The Gravoply board is then engraved with laser CNC, so the final look is pretty much identical to the picture posted above.

That would be it for part 1, next time I’ll talk about some quirks and hacks involved into placement of components, among other things.