Last active
October 29, 2020 15:38
-
-
Save kylev/4a618529a5ebff113d82 to your computer and use it in GitHub Desktop.
This is the code for an Arduino MIDI "visual metronome". I wrote it using a Sunfounder Uno R3 and a Sparkfun MIDI shield (with only the MIDI In connector installed).
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
/** | |
* MIDI Visual Metronome | |
* | |
* Developed on Sparkfun Uno R3 and Sparkfun MIDI Shield. | |
* | |
* Reqires the popular FortySevenEffects MIDI library: | |
* https://github.com/FortySevenEffects/arduino_midi_library | |
* | |
* The intended application is with MIDI and electronic music in | |
* a situation where proper stage or in-ear monitors are not | |
* available. | |
* | |
* Currently hard-coded for 4/4. Oontz-oontz. | |
* | |
* The beat is kept via the MIDI Clock, the lamest clock in the land. | |
* There are no sync frames of any sort, so you just have to make sure | |
* not to miss anything. For this reason, I used manual register | |
* manipulation rather than digitalWrite() just to make sure I had | |
* plenty of clock cycles to spare; it might not be necessary. | |
*/ | |
#include <MIDI.h> | |
#define BUTTON_PIN 2 | |
#define GREEN_PIN 6 | |
#define RED_PIN 7 | |
// Register flips for Sparkfun MIDI shield LEDs. | |
// Note: they're inverted from Arduino behavior. | |
#define GREEN_ON PORTD = PORTD & B10111111 | |
#define GREEN_OFF PORTD = PORTD | B01000000 | |
#define RED_ON PORTD = PORTD & B01111111 | |
#define RED_OFF PORTD = PORTD | B10000000 | |
MIDI_CREATE_DEFAULT_INSTANCE(); | |
void setup() { | |
pinMode(BUTTON_PIN, INPUT_PULLUP); | |
pinMode(GREEN_PIN, OUTPUT); | |
pinMode(RED_PIN, OUTPUT); | |
// Again, inverted. | |
digitalWrite(GREEN_PIN, HIGH); | |
digitalWrite(RED_PIN, HIGH); | |
MIDI.begin(); | |
} | |
void loop() { | |
static int8_t ticks = -1; | |
static int8_t prevTicks = -1; | |
static int buttonState = LOW; | |
static bool buttonHeld = false; | |
if (MIDI.read()) { | |
switch (MIDI.getType()) { | |
case midi::Start: | |
ticks = -1; | |
break; | |
case midi::Clock: | |
ticks++; | |
if (ticks == 0) { | |
GREEN_ON; | |
} else if (ticks == 1) { | |
GREEN_OFF; | |
} else if (ticks % 24 == 0) { | |
RED_ON; | |
} else if (ticks % 24 == 1) { | |
RED_OFF; | |
} else if (ticks >= 95) { | |
ticks = -1; | |
} | |
break; | |
case midi::Stop: | |
prevTicks = ticks; | |
ticks = -1; | |
break; | |
case midi::Continue: | |
ticks = prevTicks; | |
break; | |
} | |
} | |
buttonState = digitalRead(BUTTON_PIN); | |
if (!buttonHeld && buttonState == HIGH) { | |
buttonHeld = true; | |
ticks = -1; | |
} else if (buttonHeld && buttonState == LOW) { | |
buttonHeld = false; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Hey this is awesome thank you! I wanted to to a similar project, this is very inspiring for me as a bloody beginner