Skip navigation


3 Posts authored by: gadget.iom Top Member

This is part III of a three part post.

Please read Part I QLab Midi Controller for an introduction to the project

and Part II QLab MIDI Controller - The Build for the build.


After a short delay, the current version of the MIDI Controller code is now ready.

TeensyDuino is required in order to use the Arduino IDE, the software is available from the pjrc website here:


  QLab MIDI Controller v2.0

  Created: 10 Dec 2015 by Paul Ellison
  Updated: 25 Feb 2015 - Cleaned up code

  You must select MIDI from the "Tools > USB Type" menu
  To view the raw MIDI data on Linux: aseqdump -p "Teensy MIDI"

#include <Bounce.h>

// the MIDI channel number to send messages
const int channel = 1;

int blinkGo = 0;
int blinkStop = 0;

int goLEDstate = HIGH;
int stopLEDstate = HIGH;

long previousGoMillis = 0;
long previousStopMillis = 0;

long goBlinkInt = 200;
long stopBlinkInt = 500;

int goLED = 2;
int stopLED = 3;
int nextLED = 4;

// Create Bounce objects for each button.  The Bounce object
// automatically deals with contact chatter or "bounce", and
// it makes detecting changes very simple.
Bounce goButton = Bounce(10, 5);
Bounce stopButton = Bounce(11, 5);
Bounce nextButton = Bounce(12, 5);

void setup() {
  // Setup input pins for "active low"
  pinMode(10, INPUT_PULLUP);
  pinMode(11, INPUT_PULLUP);
  pinMode(12, INPUT_PULLUP);

  // Setup output pins
  pinMode(goLED, OUTPUT);
  pinMode(stopLED, OUTPUT);
  pinMode(nextLED, OUTPUT);

  // Set initial LED values.
  digitalWrite(goLED, HIGH);
  digitalWrite(stopLED, HIGH);

void loop() {
  // Update all the buttons.

  // Check each button for "falling" edge.
  // Send a 'MIDI Note On' message when each button is pressed
  if (goButton.fallingEdge()) {
    usbMIDI.sendNoteOn(62, 99, channel);  // 62 = D4
    blinkGo = 4;

  if (stopButton.fallingEdge()) {
    usbMIDI.sendNoteOn(63, 99, channel);  // 63 = D#4
    if (blinkStop == 0) {
      blinkStop = 6;
    } else {
      blinkStop = 0;
      digitalWrite(stopLED, HIGH);

  if (nextButton.fallingEdge()) {
    usbMIDI.sendNoteOn(64, 99, channel);  // 64 = E4
    digitalWrite(nextLED, LOW);

  // Check each button for "rising" edge
  // Send a 'MIDI Note Off' message when each button is released
  if (goButton.risingEdge()) {
    usbMIDI.sendNoteOff(62, 0, channel);  // 62 = D4
  if (stopButton.risingEdge()) {
    usbMIDI.sendNoteOff(63, 0, channel);  // 63 = D#4
  if (nextButton.risingEdge()) {
    usbMIDI.sendNoteOff(64, 0, channel);  // 64 = E4
    digitalWrite(nextLED, HIGH);

  // MIDI Controllers should discard incoming MIDI messages.
  // Read more at the following url:
  while ( {
    // Ignore incoming messages

  unsigned long currentGoMillis = millis();
  unsigned long currentStopMillis = millis();

  if ((blinkGo > 0) || (goLEDstate == LOW)) {
    if(currentGoMillis - previousGoMillis > goBlinkInt) {
      // save the last time you blinked the LED
      previousGoMillis = currentGoMillis;  

      // if the LED is off turn it on and vice-versa:
      if (goLEDstate == LOW) {
        goLEDstate = HIGH;
      } else {
        goLEDstate = LOW;
      // set the LED with the ledState of the variable:
      digitalWrite(goLED, goLEDstate);

  if ((blinkStop > 0) || (stopLEDstate == LOW)) {
    if(currentStopMillis - previousStopMillis > stopBlinkInt) {
      // save the last time you blinked the LED
      previousStopMillis = currentStopMillis;  

      // if the LED is off turn it on and vice-versa:
      if (stopLEDstate == LOW) {
        stopLEDstate = HIGH;
      } else {
        stopLEDstate = LOW;
      // set the LED with the ledState of the variable:
      digitalWrite(stopLED, stopLEDstate);


An improved version of the controller is in progress, build and code to follow in an additional post.


Would be interested to hear if anybody has any comments/suggestions/improvement ideas for the code (or project as a whole). Any additions will be credited.

This is part II of a three part post.

Please read Part I QLab Midi Controller for an introduction to the project.


Parts Required

1x Teensy 3.1 -

1x 60mm Illuminated Arcade Button -

1x Rectangular Arcade Button -

1x Triangular Arcade Button -

5x 5V Wedge Base LEDs -

1x Hammond Instrument Enclosure -



1x Sacrificial Micro-USB cable



The wiring for the controller is very simple. Internal pull-ups negate the need to resistors on the switches. I’ve put together a very rough schematic in Fritzing. Please let me know if you have any questions, comments or suggestions.





When powered up all three of the buttons will illuminate.


The Go button is intended to fire the currently selected cue. To do this it sends a MIDI note to the computer when the button is pressed, and turns the note off when the button is released. During this time the go button will blink 3 times.


The next button will send a different note to the computer when pressed. The LED on this button will extinguish while the button is pressed.


The Stop button has two functions. QLab will fade all active cues when the ‘Panic’ button is pressed. The time of this fade can be modified in the preferences. If the button is pressed a second time the track will stop immediately. To reflect this, the first press of the stop button will cause the button to flash for three seconds. the second press will cancel the flash and re-illuminate the button.





The enclosure front was cut to accommodate the three buttons, the rear face was cut to accept the panel mounted USB receptacle (apologies for the lack of photos). Each of the Buttons was installed and four cables were run to each of them. The Teensy and wire ends were then mounted onto a piece of strip-board



The inclusion of the specific Bulgin connectors are purely optional, I chose them because the USB cable can be ‘locked’ in place, and a standard Mini USB can also be accepted.



The QLab MIDI Controller Arduino code will follow in part III.

This project is still work in progress. Comments, questions, and suggestions are welcome.


QLab Midi Controller

Posted by gadget.iom Top Member Dec 10, 2014

This is my first blog post on Element 14. I have recently completed a small electronics project and wanted to share it with anybody who may wish to make on of their own. But first some background....



What is QLab?

Any Mac user with a reasonable footing in theatre sound production has probably heard of QLab already. For those who haven't it is an application that allows you to control music and/or video for live productions. There is also a great deal of integration possibilities for advanced show control. More information about QLab can be found here: Figure 53 | QLab | Live Show Control for Mac OS X


Why this project?

I was approached by a colleague a few months ago who who had seen an online tutorial for creating a QLab remote from a dismantled keyboard. The membrane was connected to buttons that were used to simulate keypresses that activated hotkeys within the software. We immediately thought that we could do something more elaborate. After a brief initial consideration of using an Adafruit Trinket to emulate keyboard presses we changed the design entirely and decided to use MIDI instead.



MIDI Control

The free edition of QLab allows remote control via MIDI. The primary advantage of MIDI is that the activation of cues would no longer be dependent on the application having "focus". We looked into reprogramming the Trinket to output MIDI and then employed a MIDI to USB convertor with mixed results. This was mostly due to the quality of the usb device.


What we really needed was native MIDI over USB support which the trinket (while capable of performing keyboard emulation) did not appear to support, and so we looked into alternative micro-controllers.



The Teensy 3.1

PJRC had recently released version 3.1 of their Teensy Development Board and a quick investigation indicated that it was capable of outputting MIDI over USB. Full details of the USB MIDI capabilities can be found here:



The Build

Our intention was to keep the unit as simple to operate as possible. After a fair bit of consideration a design featuring only three buttons was created. These give the operator the ability to 'Go', 'Panic' (Stop), and advance down to the next cue. This was added so that unnecessary cues (such as fades) could be skipped if required.


We elected to use some heavy duty LED backlit buttons from Arcade World, in addition to being virtually bullet proof, we were also able to insert legends indicating the function of each button.



Full build details are available in Part II QLab MIDI Controller - The Build.

Filter Blog

By date: By tag: