Testing, Testing, 1 2 3
In this installment of the MIDI for the Arduino series, we will get our hands dirty with the software side of this project and take a look at working with the Arduino MIDI Library.
If you are new to this series, check out the last installment where we build up the Midi Input Circuit and connect it to the Arduino.
For this tutorial I am using version 4.2 of the MIDI Library and version 1.6.0 of the Arduino IDE. If you are using other versions - your mileage may vary ;)
The Arduino Midi Library can be downloaded HERE.
The MIDI Input Test program file can be found HERE.
Watch the video below for the tutorial.
First off - great series on MIDI. This was the most straight-forward how-to I have found.
ReplyDeleteI have an application in which I need to identify a single control change and set a pin to high (I am using a solid state relay shield)
I tried to find documentation to that explained the correct way...but have resorted to throwing code spaghetti at the wall to see what sticks...so, nothing has.
I have tried so many different attempts - I do not know what to try next. Here I thought I could just try and match anything with a second data-byte of 10 - but no luck.
void MyHandleNoteOn(byte channel, byte pitch, byte velocity) {
if (velocity = 10) digitalWrite (LED1, HIGH); //not working
Any ideas to get my headed in the right direction?
Thank you,
CG
Hi Chris. Glad you enjoyed the tutorial. If I understand you correctly, you are trying to have one note on the keyboard trigger your LED.
DeleteTo do this you will want to read the "pitch" variable instead of velocity. Lets say you want middle C on the keyboard to be the trigger note (Middle C is MIDI note 48). Your code would look like:
if (pitch == 48) digitalWrite (LED1, HIGH);
Remember to use '==' instead of '=' when testing if a variable is equal to something. Hope this helps. Dave.
Thanks for the fast response Dave,
DeleteThe midi command is coming from a video switcher and the "velocity" or data-byte2 seems to be important. Here is the MIDI info that I have "sniffed" when selecting different inputs on the unit.
Type DATA1 DATA2 CHAN NOTE EVENT
Input 1
B0 0D 10 1 --- Control Change
Input 2
B0 0D 11 1 --- Control Change
Input 3
B0 0D 12 1 --- Control Change
Input 4
B0 0D 13 1 --- Control Change
Still
B0 0D 14 1 --- Control Change
Thank you for the reminder on the "==", I wonder if that has caused some of my issues.
CG
OK, that makes more sense. The switcher is putting out MIDI CC messages so you will want to handle them with a control change function. The first byte B0 means (CC Message - Chanel 1).
DeleteThe second byte 0D means (Controller ID# 13).
The third byte 10 means (Controller Value = 16)
As you are pushing the buttons, the switcher is changing the value of Controller #13 to 16,17,18,19,20 (I'm converting the HEX to decimal)
You could capture the values from this control with the following:
MIDI.setHandleControlChange(MyCCFunction);
void MyCCFunction(byte channel, byte number, byte value){
if (number == 13){
if(value == 16) digitalWrite(LED1, HIGH);
if(value == 17) digitalWrite(LED2, HIGH);
}
}
Thank you! That worked. Now I need to do a bit of if/else statement work.
DeleteThanks again,
CG
Coding hint:
DeleteFor comparisons to constants, you can put the comstant in front:
if (48 == x) ...
This will lead to a syntax error if you write = instead of ==.
This comment has been removed by the author.
ReplyDeleteHi, works so good, thanks.. I would like to put a note number and not a simple "pitch", becouse I need to light up a LED when I press note C3, another LED with note D3, and so on...
ReplyDeleteHow can I do?
thanks so much
Hi EnomYs. I'm glad things are working for you! The value that is passed to the pitch variable is the note number. You can use it to turn on your less. example if (pitch == 60) digitalWrite(LED1, HIGH); **LED1 is the arduino pin number of your led**
Deletethanks for answer... where I should put the modification? inside void loop?
DeleteHi, I made some change and it works great. I send a midi sequence from Logic Pro9 and trigger the input of a drum machine Oberheim DMX.
Delete#include // Add Midi Library
//Create an instance of the library with default name, serial port and settings
MIDI_CREATE_DEFAULT_INSTANCE();
void setup() {
pinMode (2, OUTPUT); // Kick
pinMode (3, OUTPUT); // Snare
pinMode (4, OUTPUT); // Hit Hat
MIDI.begin(10); // Midi channel
MIDI.setHandleNoteOn(MyHandleNoteOn); // This is important!! This command
// tells the Midi Library which function you want to call when a NOTE ON command
// is received. In this case it's "MyHandleNoteOn".
MIDI.setHandleNoteOff(MyHandleNoteOff); // This command tells the Midi Library
// to call "MyHandleNoteOff" when a NOTE OFF command is received.
}
void loop() { // Main loop
MIDI.read(); // Continuously check if Midi data has been received.
}
void MyHandleNoteOn(byte channel, byte pitch, byte velocity) {
if (channel == 10) //Works only with MIDI channel 10
{
if (pitch == 36)
digitalWrite(2,HIGH); //Turn Kick on
if (pitch == 38)
digitalWrite(3,HIGH); //Turn Snare on
if (pitch == 42)
digitalWrite(4,HIGH); //Turn Hit Hat on
}
}
void MyHandleNoteOff(byte channel, byte pitch, byte velocity) {
if (channel == 10)
{
if (pitch == 36)
digitalWrite(2,LOW); //Turn Kick off
if (pitch == 38)
digitalWrite(3,LOW); //Turn Snare off
if (pitch == 42)
digitalWrite(4,LOW); //Turn Hit Hat off
}
}
Thanks for the great tutorial. I finally got it to work after hearing the 'disconnect the RX pin before uploading the program' part. My question is, does this mean using the Arduino IDE Serial Monitor is not an option? Or does Serial out still work? I'd really like a better way than LEDs to debug what I want to do next.
ReplyDeletePut a 1n914 Diode between RX and Pin 6 on Optocoupler, so can you upload code without disconnect the RX pin
DeleteAwesome, one of the few real straightforward how-to's amidst a lot of vague information! On top of that everything is produced with professional quality, thanks!
ReplyDeleteHi. I want to make a midi unit that adds swing to the original midi signal. I assume that I would make the input and the midi output. I wonder whether a code for this function exists somewhere and if not, whether or not it would be a relatively straightforward? Any thoughts greatly relieved. Love the clear videos that you produce. Cheers. Simon
ReplyDeleteI hope you don't mind, but I need some help downloading your
ReplyDeletetest file. I am on Linux mint and was wondering if there is a way to download it. Right now it takes me to a page with a button that is not clickable. Thanks
Hey, I am trying to use the Control Change function with an Tlc5940. But how ever this dont work:
ReplyDeletevoid MyCCFunction(byte channel, byte number, byte value) {
switch (number) {
case 21:
mapval = map(value, 0, 127, 0, 16); //Map the Output
Tlc.set(mapval, brightness); //Write to Mux
Tlc.update(); //Update Mux
}
Any Ideas?
would like to know did it work?
DeleteCan I use this code to control the zoom ms70cdr?
ReplyDeleteFantastic work and tutorials. This is coming rather late so I hope you see it, I built the circuit add it works great, now I was wondering how to modify the sketch so I can use multiplexers for my LED outputs.
ReplyDeleteHow you see it.
Thanks and God bless
Awesome tutorials. Congrats. I have a question, probably trivial but not for me. How do we deal with chords, i.e. multiple notes? It seems that MyHandleNoteOn just handle one note (pitch) at once. Is that correct? How do we enable chords by using MyHandleNoteOn? Are there other alternatives possible?
ReplyDeleteThanks,
Cheers
Did you solve it ? im also intressed in this.
ReplyDeleteHola Dave, estoy tratando de encender y apagar un motor a pasos NEMA 17, a través de mensaje MIDI.
ReplyDeleteTome tu código del encendido del led y pegue el código del motor.
Para el envío del mensaje, estoy utilizando CUBASE.
El si se enciende, pero el motor no se mueve.
A continuación te envío el código, y te agradecería cualquier comentario.
#include // Add Midi Library
#include
#define LED 13 // Arduino Board LED is on Pin 13
#define STEP 4 // pin STEP de A4988 a pin 4
#define DIR 5 // pin DIR de A4988 a pin 5
#define ENABLE 2 // PIN ENABLE de A4988 a pin 2
#define M1 10 // pin M1 de 4988 a pin 10
#define M2 11 // pin M2 de 4988 a pin 11
#define M3 12 // pin M3 de 4988 a pin 12
int potenciometro; // lectura del potenciometro
int pot_mapeado;
int vel_motor;
//Create an instance of the library with default name, serial port and settings
MIDI_CREATE_DEFAULT_INSTANCE();
void setup() {
MIDI.begin(MIDI_CHANNEL_OMNI); // Initialize the Midi Library.
// OMNI sets it to listen to all channels.. MIDI.begin(2) would set it
// to respond to notes on channel 2 only.
pinMode (LED, OUTPUT); // Set Arduino board pin 13 to output
//Serial.begin(9600);
pinMode(STEP, OUTPUT); // pin 4 como salida
pinMode(DIR, OUTPUT); // pin 5 como salida
pinMode(M1, OUTPUT); // PIN 10 como salida
pinMode(M2, OUTPUT); // PIN 11 como salida
pinMode(M3, OUTPUT); // PIN 12 como salida
MIDI.setHandleNoteOn(MyHandleNoteOn); // This is important!! This command
// tells the Midi Library which function you want to call when a NOTE ON command
// is received. In this case it's "MyHandleNoteOn".
MIDI.setHandleNoteOff(MyHandleNoteOff); // This command tells the Midi Library
// to call "MyHandleNoteOff" when a NOTE OFF command is received.
}
void loop() { // Main loop
MIDI.read(); // Continuously check if Midi data has been received.
}
// MyHandleNoteON is the function that will be called by the Midi Library
// when a MIDI NOTE ON message is received.
// It will be passed bytes for Channel, Pitch, and Velocity
void MyHandleNoteOn(byte channel, byte pitch, byte velocity) {
digitalWrite(LED,HIGH); //Turn LED on
pot_mapeado = velocidad();
digitalWrite(ENABLE, LOW);
digitalWrite(M1, HIGH); // control con micropasos
digitalWrite(M2, HIGH); // a un 1/16
digitalWrite(M3, HIGH); //
digitalWrite(DIR, HIGH); // giro en sentido horario
digitalWrite(STEP, HIGH); // nivel alto
//delayMicroseconds(pot_mapeado);
delayMicroseconds(250);
digitalWrite(STEP, LOW); // nivel bajo
//delayMicroseconds(pot_mapeado);
delayMicroseconds(250);
}
// MyHandleNoteOFF is the function that will be called by the Midi Library
// when a MIDI NOTE OFF message is received.
// * A NOTE ON message with Velocity = 0 will be treated as a NOTE OFF message *
// It will be passed bytes for Channel, Pitch, and Velocity
void MyHandleNoteOff(byte channel, byte pitch, byte velocity) {
digitalWrite(LED,LOW); //Turn LED off
digitalWrite(ENABLE, HIGH);
}
//FUNCION PARA LEER EL POTENCIOMETRO
int velocidad(){
potenciometro = analogRead(A0); // leemos el potenciometro
int nuevo_potenciometro = map(potenciometro,0,1024,30,2500); // adaptamos el valor leido a un retardo
return nuevo_potenciometro;
}
You should take part in a contest for one of the best blogs on the web. I will recommend this site!
ReplyDeleteLinkfly.to
Information
Click Here
Visit Web