Skip to content

Instantly share code, notes, and snippets.

@kylev
Last active October 29, 2020 15:38
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kylev/4a618529a5ebff113d82 to your computer and use it in GitHub Desktop.
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).
/**
* 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;
}
}
@DTekieli
Copy link

Hey this is awesome thank you! I wanted to to a similar project, this is very inspiring for me as a bloody beginner

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment