LED on while midi note is played

hey folks. i have an urgent question:

i'm quite new to arduino and i'm on a project that involves midi. i got all the midi hooked up and it works in terms of clock and receiving signals and stuff.

now can anybody help me out on how to get an LED to light up only as long as a midi note (let's say 0x39 for an A4) is held? the 'note on' byte seems to be 144, the 'note off' byte is 128 but i just can't work it out.

i'd be gracious for any help. thanks, benni the code:

#define LED 4
#define STATUSLED 5
byte midi_start = 0xfa;
byte midi_stop = 0xfc;
byte midi_clock = 0xf8;
byte midi_continue = 0xfb;
byte midi_A4 = 0x39;
byte data;

void setup() {
Serial.begin(31250); 
pinMode(LED,OUTPUT);
pinMode(STATUSLED,OUTPUT);
} 

void loop() {
if(Serial.available() > 0) {
data = Serial.read();

if(data == midi_start) {
digitalWrite(STATUSLED,HIGH);
}

else if(data == midi_continue) {
  digitalWrite(STATUSLED,HIGH);
}

else if (data == midi_A4){
play();
}

else if(data == midi_stop) {
  digitalWrite (STATUSLED,LOW);
}
}
}

void play() {
digitalWrite (LED, HIGH);
}

Look at my code here:-
http://www.thebox.myzen.co.uk/Hardware/Glockenspiel.html

Simply do a digital write low on the note on and digital write high on the note off.

i already checked your code :slight_smile: … i’m just to much of a newbie to understand it…

i got it to work, that the led turns on when ‘note on’ is received and turns off again when ‘note off’ is received, but now i’m stuck, because it does that on all notes and not only on the A4 or what ever… can you help me out? here’s basically what i did:

if (data == midi_noteon){
noteon();
}

else if (data == midi_noteoff){
noteoff();
}


void noteon() {
if (data == midi_A4) {              // << this doesnt work :(
digitalWrite (SEQ, HIGH);
digitalWrite (RESET, HIGH);
  }
else {
  digitalWrite (SEQ, LOW);
digitalWrite (RESET, LOW);
}
}

void noteoff() {
digitalWrite (SEQ, LOW);
digitalWrite (RESET, LOW);
}

( ps i defined the midi_A4 as the correct byte before…)

oh and while i'm at it - is there (as an alternative) a possibility to have the led light up only for a certain time when ever a particular note is played without using a delay() function?

It is difficult to see what you are doing wrong because you only posted a bit of your code. For example:-
if (data == midi_A4) { // << this doesnt work :frowning:
I can’t see where you define midi_A4

You use data in 3 places with 3 different meanings. A MIDI message consists of 3 bytes.

to have the led light up only for a certain time when ever a particular note is played without using a delay() function?

Yes it is possible to do most things in a computer program. Look at the blink without delay function. However it is a bit harder to do than what you are trying to do at the moment.

hey mike… first of all thank you.
i’m sorry, i’ll post the complete code again:

#define LED 4
byte midi_start = 0xfa;
byte midi_stop = 0xfc;
byte midi_clock = 0xf8;
byte midi_continue = 0xfb;
byte midi_A4 = 0x39;
byte midi_noteon = 144;
byte midi_noteoff = 128;
byte data;


void setup() {
Serial.begin(31250); 
pinMode(LED,OUTPUT);
} 

void loop() {

if(Serial.available() > 0) {
data = Serial.read();

if (data == midi_noteon) {
noteon();
}

else if (data == midi_noteoff) {
noteoff();
}
}
}


void noteon() {
  if (data == midi_A4) {           //<- doesn't work
digitalWrite (LED, HIGH);
  }
  else {
  digitalWrite (LED,LOW);
}
}

void noteoff() {
digitalWrite (LED, LOW);
}

You don't seem to understand the structure of a MIDI message. It consists of 3 bytes you must read each one into a different variable before you can do anything with the message. The note on message is followed by the byte that tells you what note it is and finally the on velocity. You need to first find the note on, then the next byte you compare to the note you want and light the LED if it is. Finally the last byte you are not interested in so you just let it go. You need to keep track of what byte is coming in. That's what all my code does, it is about as simple as it gets any simpler, as you have found, and it doesn't work because you are not doing the right thing.

ok i got your code to work... thanks so much.

now alternatively i'm trying to have the LEDs flash up for a fixed periode of time whenever a certain midi note is received, although independent of how long this note is played.. i've checked the "flashing leds without delay" but i cant get it to work, because the LEDs don't react to every midi note (if they are played in a short periode of time)

could you help me out, based on my code? thanks.

You need to have a list (held in an array of long int) of what LEDs you have. The contents of the list should be the time reported by millis() of when you want the LEDs to be turned off. So whenever you turn an LED on you also store in the appropriate array the current value returned by millis() plus the number of milliseconds you want the light to be on for, so for 1 second you would add 1000. Then when you are in the loop looking to see if anything has come in from the serial port you also go through the array looking to see if it is time to turn any LED off by seeing if the current value of millis() is greater that that stored in the array. You could store a value of zero to indicate the LED was off anyway so there was no need to switch it off continually.

mh.. i'm afraid i have no idea how to do that. i've been cross-refering to the tutorial, but it doesn't end up doing what i want it to do. any chance you could post some example code? i'm sorry :/

This will do it for one LED:-

long timeToOff ;
int pin = 4; // pin the LED is attached to

void setup(){
  // the other setup stuff
  timeToOff = 0;
}

void loop(){
  if( (timeToOff != 0) && (millis() > timeToOff) ) {
    // turn off the LED
    digitalWrite(pin, LOW);
    timeToOff = 0; // reset the off time
  }
  // now do the rest of the loop looking at the serial input
  
  // at some stage you will turn on an LED
  digitalWrite(pin,HIGH);
  timeToOff = millis() + 1000; // set the off time.
}

Now extend it to do as many LEDs as you want. You can do it the baby way by just repeating nearly the same thing for each LED or the grown up way by making the timeToOff into an array and looping through that.