Instantly share code, notes, and snippets.
Last active
August 28, 2020 13:27
-
Star
0
(0)
You must be signed in to star a gist -
Fork
0
(0)
You must be signed in to fork a gist
-
Save skutov/ed6c3866554eb11098aa3277916a602a to your computer and use it in GitHub Desktop.
Qlab Button triggers using arduino
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//#include "Keyboard.h" | |
#include "MIDIUSB.h" | |
// At the moment, button 9 is being used as an output to control a relay via MIDI | |
const int buttonPins[10] = {3, 4, 5, 6, 7, 9, 8, 10, 11, 12}; // input pins for pushbuttons | |
const char buttonKeys[10] = {'1', '2', '3', '4', '5', '6', '7', '8', '9', '0'}; | |
int buttonCurrentStates[10] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; | |
int buttonPrevStates[10] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; | |
unsigned long lastDebounceTime[10] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; | |
const unsigned long debounceDelay = 50; // the debounce time; increase if the output flickers | |
// MIDI commands | |
// First parameter is the event type (0x09 = note on, 0x08 = note off). | |
// Second parameter is note-on/note-off, combined with the channel. | |
// Channel can be anything between 0-15. Typically reported to the user as 1-16. | |
// Third parameter is the note number (48 = middle C). | |
// Fourth parameter is the velocity (64 = normal, 127 = fastest). | |
void noteOn(byte channel, byte pitch, byte velocity) { | |
midiEventPacket_t noteOn = {0x09, 0x90 | channel, pitch, velocity}; | |
MidiUSB.sendMIDI(noteOn); | |
MidiUSB.flush(); | |
} | |
void noteOff(byte channel, byte pitch, byte velocity) { | |
midiEventPacket_t noteOff = {0x08, 0x80 | channel, pitch, velocity}; | |
MidiUSB.sendMIDI(noteOff); | |
MidiUSB.flush(); | |
} | |
// First parameter is the event type (0x0B = control change). | |
// Second parameter is the event type, combined with the channel. | |
// Third parameter is the control number number (0-119). | |
// Fourth parameter is the control value (0-127). | |
void controlChange(byte channel, byte control, byte value) { | |
midiEventPacket_t event = {0x0B, 0xB0 | channel, control, value}; | |
MidiUSB.sendMIDI(event); | |
MidiUSB.flush(); | |
} | |
void setup() { | |
// initialise serial | |
Serial.begin(9600); | |
// initialise GPIO pins | |
for (int i = 0; i < 9; i++) | |
{ | |
pinMode(buttonPins[i], INPUT_PULLUP); | |
} | |
pinMode(buttonPins[9], OUTPUT); | |
digitalWrite(buttonPins[9], HIGH); | |
Serial.println("Started, listening for MIDI"); | |
} | |
void loop() { | |
handleMidi(); | |
// Check NO inputs | |
for (int i = 0; i < 9; i++) | |
{ | |
int reading = digitalRead(buttonPins[i]); | |
if (reading != buttonPrevStates[i]) | |
{ | |
// reset the debouncing timer | |
lastDebounceTime[i] = millis(); | |
} | |
if ((millis() - lastDebounceTime[i]) > debounceDelay) { | |
// whatever the reading is at, it's been there for longer than the debounce | |
// delay, so take it as the actual current state: | |
// if the button state has changed: | |
if (reading != buttonCurrentStates[i]) | |
{ | |
if (buttonCurrentStates[i]) | |
{ | |
// MIDI Command | |
noteOn(0,i,64); | |
Serial.print("Note "); | |
Serial.print(i); | |
Serial.println(" On"); | |
// Keyboard command | |
// Keyboard.write(buttonKeys[i]); | |
} | |
else | |
{ | |
// Button released | |
noteOff(0,i,64); | |
Serial.print("Note "); | |
Serial.print(i); | |
Serial.println(" Off"); | |
} | |
buttonCurrentStates[i] = reading; | |
} | |
} | |
buttonPrevStates[i] = reading; | |
} | |
} | |
void handleMidi() { | |
midiEventPacket_t rx ; | |
do { | |
rx = MidiUSB.read(); | |
switch (rx.header) { | |
case 0: | |
break; //No pending events | |
case 0x9: // Note on message | |
if(((rx.byte1 & 0xF) == 0x01) && //channel | |
(rx.byte2 == 48) && //pitch | |
(rx.byte3 > 0)) //velocity | |
{ | |
} | |
break; | |
case 0x8: // Note off message | |
break; | |
case 0xB: // CC message | |
switch (rx.byte1 & 0x0F) // channel | |
{ | |
case 0x0: // Channel 1 | |
if (rx.byte2 == 1) // Control 1 | |
{ | |
if(rx.byte3) | |
{ | |
digitalWrite(buttonPins[9], HIGH); | |
Serial.println("CC 1 On"); | |
} | |
else | |
{ | |
digitalWrite(buttonPins[9], LOW); | |
Serial.println("CC 1 Off"); | |
} | |
} | |
break; | |
} | |
break; | |
default: | |
Serial.print("Unhandled MIDI message: "); | |
Serial.print(rx.header, HEX); | |
Serial.print("-"); | |
Serial.print(rx.byte1, HEX); | |
Serial.print("-"); | |
Serial.print(rx.byte2, HEX); | |
Serial.print("-"); | |
Serial.println(rx.byte3, HEX); | |
} | |
} while (rx.header != 0); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment