Hello,
I'm trying to figure out whether, and if yes, how it would be possible to implement the following with the Arduino midi library (I have UNO + midi shield with in-out-thru).
-
Arduino sends out midi clock, and additionally midi commands at precise points (to change patches on a hardware synthesizer, guitar effects device etc).
-
Arduino receives midi clock from an external source and passes it on, in addition to passing on its own midi commands at precise points (ditto).
I haven't been able to find examples for how to use the midi library, such that I would understand well enough. So below is what I think needs to be taken into account, and what might be done. Please correct me if/as I'm wrong, and please point out to more elegant solutions if you have one in mind. (The midi library page and a link to the reference is at Arduino Playground - MIDILibrary)
Midi clock sends 24 pulses per quarter note, and because patch change on external equipment doesn't (for me) need to be accurate to the 1/24 of a quarter note, maybe the midi clock pulses could be mapped onto quarter notes; it would also make determining the command timing a bit more intuitive.
I've read the midi library reference, and it seems the following stuff is what I would need (but maybe there's more):
sendControlChange(byte ControlNumber, byte ControlValue, byte Channel)
sendProgramChange(byte ProgramNumber, byte Channel)
sendRealTime(kMidiType Start/Stop/Continue/Clock) (But how to receive?)
Overall the reference is too technical for me, I would require more concrete examples in context to really get it.
Anyway here's is a rough sketch of what I think the code might look like in outline. It probably is a mess and certainly it's not in any functioning condition. For example at this stage I haven't figured where to put all the {'s, and what the correct syntax exactly is; this is just a rough sketch of what it could look like. Corrections and suggestions are most welcome.
#include <MIDI.h>
int switch1 = 1; // These switches select which
int switch2 = 2; // loop/program is going to be run and which
int switch3 = 3; // Arduino pin they're connected to. A normal-open button enables the switches to be checked.
int ledPin1 = 4;
int buttonPin = 5;
void setup() {
// The reference said MIDI.begin has to be here.. I don't know what to do with it though. This sets input to channel 1, but I'm not sure if
// there's going to be any MIDI input. I don't know if midi clock reception will care about (input) channels.
MIDI.begin();
// These determine where the switches send their information.
// An led is there to be lit up in case of faulty switch condition. It will start unlit.
// Button enables switch check.
pinMode(switch1, INPUT);
pinMode(switch2, INPUT);
pinMode(switch3, INPUT);
pinMode(ledPin1, OUTPUT);
pinMode(buttonPin, INPUT);
digitalWrite(ledPin1, LOW);
}
void loop() {
// When the button is pressed, the code checks the switches, and if only one
// of them is on, runs the appropriate loop; if none
// of them is on, or if several are on, an led lights up and
// nothing else happens. Maybe there's a more elegant way
// to do the if-else thing. Or it's not going to look pretty when there's
// a dozen inputs to be checked. Probably a more elegant way calls for
// one single turnable, detented knob instead a dozen switches.
// In this sketch the curly brackets are wrong, I'm not sure how to make them right.
digitalRead(buttonPin);
if (buttonPin == HIGH) {
if (switch1 == HIGH && switch2 == LOW && switch3 == LOW); {
switch1program; }
else if (switch1 == LOW && switch2 == HIGH && switch3 == LOW); {
switch2program; }
else if (switch1 == LOW && switch2 == LOW && switch3 == HIGH); {
switch3program;
else { digitalWrite(ledPin1, HIGH); }
}
void switch1program() {
// If the switch conditions were such that none of the switch loops were run, and the error led lit up,
// here the led turned off if the situation was corrected and a program started running.
// The commands are to change a patch on my guitar mfx (boss GT-10). First CC#0 value 0, then CC#32 value 0, then program
// change value 81 - all on midi channel 10. It will change to patch U21:1.
digitalWrite(ledPin1, LOW);
sendControlChange(byte 0, byte 0, byte 10); // is this the correct syntax, do I need to write the word "byte" there?
sendControlChange(byte 32, byte 0, byte 10);
sendProgramChange(byte 81, byte 10);
}
void switch2program() {
}
void switch3program() {
}
Trying to compile gives the following errors:
sketch_aug30a.cpp: In function ‘void loop()’:
sketch_aug30a.cpp:49:2: error: expected ‘}’ before ‘else’
sketch_aug30a.cpp:51:2: error: ‘else’ without a previous ‘if’
sketch_aug30a.cpp:53:2: error: ‘else’ without a previous ‘if’
sketch_aug30a.cpp:56:23: error: a function-definition is not allowed here before ‘{’ token
sketch_aug30a.cpp:68:23: error: a function-definition is not allowed here before ‘{’ token
sketch_aug30a.cpp:71:23: error: a function-definition is not allowed here before ‘{’ token
sketch_aug30a.cpp:72:1: error: expected ‘}’ at end of input
I've tried doing various stuff and managed to change the code to get rid of the error messages, but this is what's left, I can't seem to get rid of them. If someone can help me with this I'd be grateful.
Anyway a bigger problem is I have no idea how to put midi clock into all this, and how to tie the control changes etc. to a certain point of the midi clock. There is some code at little-scale: How to Deal with MIDI Clock Signals in Arduino for midi clock, and maybe I could use that (haven't tried yet), but as the midi library page says, "Simple and fast way to send and receive every kind of MIDI message (including all System messages, SysEx, Clock, etc..)", maybe there's a simpler way with the help of the library than the one offered by the little-scale blog. I don't know whether switch1program etc. can be called like that from within the loop(), I got the idea from the mentioned little-scale blog, where the Sync() seems to be called in a similar fashion from within the loop().
These are the problems I have at the moment (I'm sure there's others too