implement serial MIDI interface
This commit is contained in:
parent
105388310b
commit
a7bc05506d
|
@ -0,0 +1,3 @@
|
||||||
|
[submodule "ArduinoMIDI"]
|
||||||
|
path = ArduinoMIDI
|
||||||
|
url = https://github.com/FortySevenEffects/arduino_midi_library
|
|
@ -0,0 +1 @@
|
||||||
|
Subproject commit d501f4bb3dfff548a7cef4d85371bec0b438bdd7
|
1
Makefile
1
Makefile
|
@ -23,6 +23,7 @@ VPATH := $(foreach path, ${VPATH}, ${path} $(shell find ${path} -type d))
|
||||||
# This is to prevent the command above from including directories like .git into
|
# This is to prevent the command above from including directories like .git into
|
||||||
# the VPATH list
|
# the VPATH list
|
||||||
VPATH += ${PWD} \
|
VPATH += ${PWD} \
|
||||||
|
${PWD}/ArduinoMIDI/src \
|
||||||
|
|
||||||
# Build parameters
|
# Build parameters
|
||||||
BUILD_DIR := out
|
BUILD_DIR := out
|
||||||
|
|
65
main.cpp
65
main.cpp
|
@ -1,8 +1,11 @@
|
||||||
#include <Arduino.h>
|
#include <Arduino.h>
|
||||||
|
#include <MIDI.h>
|
||||||
#include "motor_control.h"
|
#include "motor_control.h"
|
||||||
|
|
||||||
#define NUM_MOTORS 4
|
#define NUM_MOTORS 4
|
||||||
|
|
||||||
|
using namespace midi;
|
||||||
|
|
||||||
MotorControl motors[NUM_MOTORS] = {
|
MotorControl motors[NUM_MOTORS] = {
|
||||||
MotorControl(5, 2),
|
MotorControl(5, 2),
|
||||||
MotorControl(6, 3),
|
MotorControl(6, 3),
|
||||||
|
@ -10,6 +13,18 @@ MotorControl motors[NUM_MOTORS] = {
|
||||||
MotorControl(13, 12)
|
MotorControl(13, 12)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// MIDI setup
|
||||||
|
struct MySerialMIDISettings {
|
||||||
|
// ttymidi wants a baud rate of 115200
|
||||||
|
static const long BaudRate = 115200;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef SerialMIDI<HardwareSerial, MySerialMIDISettings> MySerialMIDI;
|
||||||
|
|
||||||
|
MySerialMIDI serialMIDI(Serial);
|
||||||
|
|
||||||
|
MidiInterface<MySerialMIDI> MIDI(serialMIDI);
|
||||||
|
|
||||||
void handle_tick(unsigned long cur_micros) {
|
void handle_tick(unsigned long cur_micros) {
|
||||||
// Randomize the order we process motor ticks every time
|
// Randomize the order we process motor ticks every time
|
||||||
// This helps reduce the minor frequency discrepancies between each motor
|
// This helps reduce the minor frequency discrepancies between each motor
|
||||||
|
@ -19,6 +34,20 @@ void handle_tick(unsigned long cur_micros) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define ASSERT_CHANNEL() \
|
||||||
|
if (channel <= 0) return; \
|
||||||
|
if (channel - 1 > NUM_MOTORS) return;
|
||||||
|
|
||||||
|
void midi_note_on(uint8_t channel, uint8_t note, uint8_t velocity) {
|
||||||
|
ASSERT_CHANNEL();
|
||||||
|
motors[channel - 1].TickAtPitch(note);
|
||||||
|
}
|
||||||
|
|
||||||
|
void midi_note_off(uint8_t channel, uint8_t note, uint8_t velocity) {
|
||||||
|
ASSERT_CHANNEL();
|
||||||
|
motors[channel - 1].TickOff();
|
||||||
|
}
|
||||||
|
|
||||||
int main() {
|
int main() {
|
||||||
// Arduino library initialization
|
// Arduino library initialization
|
||||||
// Needed for some functions to work (like micros)
|
// Needed for some functions to work (like micros)
|
||||||
|
@ -33,39 +62,17 @@ int main() {
|
||||||
motors[i].Init();
|
motors[i].Init();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Test: play Twinkle Twinkle Little Star
|
// Start serial MIDI interface
|
||||||
unsigned long note_time = 500ul * 1000ul; // 500 ms
|
MIDI.begin(MIDI_CHANNEL_OMNI);
|
||||||
unsigned int seq_motor[4][15] = {
|
|
||||||
{ 60, 60, 67, 67, 69, 69, 67, 0, 65, 65, 64, 64, 62, 62, 60 },
|
// Set up MIDI callbacks
|
||||||
{ 57, 57, 64, 64, 65, 65, 64, 0, 62, 62, 60, 60, 59, 59, 57},
|
MIDI.setHandleNoteOn(midi_note_on);
|
||||||
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
|
MIDI.setHandleNoteOff(midi_note_off);
|
||||||
{ 48, 48, 53, 53, 48, 48, 0, 0, 53, 53, 48, 48, 55, 55, 48},
|
|
||||||
};
|
|
||||||
unsigned long last_note_ts = 0;
|
|
||||||
int cur_note = -1;
|
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
unsigned long cur_micros = micros();
|
unsigned long cur_micros = micros();
|
||||||
handle_tick(cur_micros);
|
handle_tick(cur_micros);
|
||||||
|
MIDI.read();
|
||||||
if (cur_micros - last_note_ts >= note_time) {
|
|
||||||
last_note_ts = cur_micros;
|
|
||||||
cur_note += 1;
|
|
||||||
|
|
||||||
for (int i = 0; i < 4; i++) {
|
|
||||||
if (seq_motor[i][cur_note] != 0) {
|
|
||||||
motors[i].TickAtPitch(seq_motor[i][cur_note]);
|
|
||||||
} else {
|
|
||||||
motors[i].TickOff();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Prevent out of bounds access
|
|
||||||
if (cur_note >= 15) {
|
|
||||||
motors[i].TickOff();
|
|
||||||
while (true) {}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
Loading…
Reference in New Issue