mirror of https://github.com/midilab/uClock
Added example of teensy usage for midi clock slave monitor using timer interrupt to read incomming midi messages. That is to avoid jitter created when reading midi on loop() along with other code lines
parent
06ebbcbe23
commit
2f70ed8b82
@ -0,0 +1,139 @@ |
|||||||
|
/* USB MIDI Sync Slave Box Monitor
|
||||||
|
*
|
||||||
|
* This example demonstrates how to create a |
||||||
|
* MIDI hid compilant slave clock box with
|
||||||
|
* monitor support using oled displays |
||||||
|
* |
||||||
|
* Making use of a 250 usceconds timer to |
||||||
|
* handle MIDI input to avoid jitter on clock |
||||||
|
*
|
||||||
|
* You need the following libraries to make it work |
||||||
|
* - u8g2 |
||||||
|
* - uClock |
||||||
|
* This example code is in the public domain. |
||||||
|
*/ |
||||||
|
|
||||||
|
#include <U8x8lib.h> |
||||||
|
|
||||||
|
//
|
||||||
|
// BPM Clock support
|
||||||
|
//
|
||||||
|
#include <uClock.h> |
||||||
|
|
||||||
|
U8X8 * u8x8; |
||||||
|
IntervalTimer teensyTimer; |
||||||
|
|
||||||
|
// MIDI clock, start, stop, note on and note off byte definitions - based on MIDI 1.0 Standards.
|
||||||
|
#define MIDI_CLOCK 0xF8 |
||||||
|
#define MIDI_START 0xFA |
||||||
|
#define MIDI_STOP 0xFC |
||||||
|
|
||||||
|
char bpm_str[3]; |
||||||
|
uint16_t bpm = 126; |
||||||
|
uint8_t bpm_blink_timer = 1; |
||||||
|
uint8_t clock_state = 1; |
||||||
|
|
||||||
|
void handle_bpm_led(uint32_t * tick) |
||||||
|
{ |
||||||
|
// BPM led indicator
|
||||||
|
if ( !(*tick % (96)) || (*tick == 1) ) { // first compass step will flash longer
|
||||||
|
bpm_blink_timer = 8; |
||||||
|
digitalWrite(LED_BUILTIN, HIGH); |
||||||
|
} else if ( !(*tick % (24)) ) { // each quarter led on
|
||||||
|
digitalWrite(LED_BUILTIN, HIGH); |
||||||
|
} else if ( !(*tick % bpm_blink_timer) ) { // get led off
|
||||||
|
digitalWrite(LED_BUILTIN, LOW); |
||||||
|
bpm_blink_timer = 1; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
// Internal clock handlers
|
||||||
|
void ClockOut96PPQN(uint32_t * tick) { |
||||||
|
// Send MIDI_CLOCK to external gears
|
||||||
|
usbMIDI.sendRealTime(MIDI_CLOCK); |
||||||
|
handle_bpm_led(tick); |
||||||
|
} |
||||||
|
|
||||||
|
void onClockStart() { |
||||||
|
usbMIDI.sendRealTime(MIDI_START); |
||||||
|
} |
||||||
|
|
||||||
|
void onClockStop() { |
||||||
|
usbMIDI.sendRealTime(MIDI_STOP); |
||||||
|
} |
||||||
|
|
||||||
|
// External clock handlers
|
||||||
|
void onExternalClock() |
||||||
|
{ |
||||||
|
uClock.clockMe(); |
||||||
|
} |
||||||
|
|
||||||
|
void onExternalStart() |
||||||
|
{ |
||||||
|
uClock.start(); |
||||||
|
} |
||||||
|
|
||||||
|
void onExternalStop() |
||||||
|
{ |
||||||
|
uClock.stop(); |
||||||
|
} |
||||||
|
|
||||||
|
void setup() { |
||||||
|
// A led to count bpms
|
||||||
|
pinMode(LED_BUILTIN, OUTPUT); |
||||||
|
|
||||||
|
//
|
||||||
|
// MIDI setup
|
||||||
|
//
|
||||||
|
usbMIDI.begin(); |
||||||
|
usbMIDI.setHandleClock(onExternalClock); |
||||||
|
usbMIDI.setHandleStart(onExternalStart); |
||||||
|
usbMIDI.setHandleStop(onExternalStop); |
||||||
|
|
||||||
|
//
|
||||||
|
// OLED setup
|
||||||
|
// Please check you oled model to correctly init him
|
||||||
|
//
|
||||||
|
u8x8 = new U8X8_SH1106_128X64_NONAME_HW_I2C(U8X8_PIN_NONE); |
||||||
|
u8x8->begin(); |
||||||
|
u8x8->setFont(u8x8_font_pressstart2p_r);
|
||||||
|
u8x8->clear(); |
||||||
|
u8x8->drawUTF8(0, 0, "uClock");
|
||||||
|
|
||||||
|
//
|
||||||
|
// uClock Setup
|
||||||
|
//
|
||||||
|
// Setup our clock system
|
||||||
|
// drift for USB Teensy
|
||||||
|
uClock.setDrift(1); |
||||||
|
uClock.init(); |
||||||
|
uClock.setClock96PPQNOutput(ClockOut96PPQN); |
||||||
|
// For MIDI Sync Start and Stop
|
||||||
|
uClock.setOnClockStartOutput(onClockStart); |
||||||
|
uClock.setOnClockStopOutput(onClockStop); |
||||||
|
uClock.setMode(uClock.EXTERNAL_CLOCK); |
||||||
|
// make use of 250us timer to handle midi input sync
|
||||||
|
teensyTimer.begin(handleMidiInput, 250);
|
||||||
|
} |
||||||
|
|
||||||
|
void handleMidiInput() { |
||||||
|
while (usbMIDI.read()) { |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
void loop() { |
||||||
|
if (bpm != uClock.getTempo()) { |
||||||
|
bpm = uClock.getTempo(); |
||||||
|
itoa(bpm, bpm_str, 10); |
||||||
|
u8x8->drawUTF8(10, 7, bpm_str); |
||||||
|
u8x8->drawUTF8(13, 7, "bpm");
|
||||||
|
} |
||||||
|
if (clock_state != uClock.state) {
|
||||||
|
clock_state = uClock.state; |
||||||
|
if (clock_state >= 1) { |
||||||
|
u8x8->drawUTF8(0, 7, "playing");
|
||||||
|
} else {
|
||||||
|
u8x8->drawUTF8(0, 7, "stoped ");
|
||||||
|
} |
||||||
|
} |
||||||
|
} |
Loading…
Reference in new issue