Midi notes to Digital outputs

Grumpy_Mike:
How about this
MIDI Glockenspiel

Hello Mr. Mike, it's one of your own projects!?! Can you re-link this code please?

http://www.thebox.myzen.co.uk/Hardware/MIDI_Shield_files/MIDI_Shield.pde

My respect.

Sorry don't know where it has gone. Copy it from here.

/* Midi Shield - Mike Cook May 2009
 * ----------------- 
 * listen for MIDI serial data, 
 * sends MIDI note on with push button on Pin 2
 
#####################################################################################################################################################

HARDWARE NOTE:
The MIDI Socket is connected to arduino RX through an opto-isolator to invert the MIDI signal 
and separate the circuits of individual instruments.

####################################################################################################################################################
*/

//variables setup

  byte incomingByte;
  byte note;
  byte button;
  int noteDown = LOW;
  int state=0;        // state machine variable 0 = command waiting : 1 = note waitin : 2 = velocity waiting
  byte channel = 1;  // MIDI channel to respond to (in this case channel 2) change this to change the channel number
                    // MIDI channel = the value in 'channel' + 1

//setup: declaring inputs and outputs and begin serial 
void setup() { 

  pinMode(13,OUTPUT);       // LED to light up
  pinMode(2,INPUT);         // push button to read
  digitalWrite(2,HIGH);     // enable internal pull up resistors
  button = digitalRead(2);  // initialise push button state
  state = 0;  // initialise state machine variable
  //start serial with MIDI baud rate 31250 or another standard speed for debugging
  Serial.begin(31250);        
  digitalWrite(13,LOW);     // Turn LED off
}

//loop: wait for serial data, and interpret the message 
void loop () {
  checkIn(); // see if anything has arrived at the input
  checkButton();
  }
  
void checkButton(){
  if(button != digitalRead(2)) {  // only do stuff on a change
    button = digitalRead(2);     // get new state of button
    if(button == HIGH) noteSend(0x80, 65, 0); else noteSend(0x90, 65, 127);
  }
}  

//  plays a MIDI note
void noteSend(byte cmd, byte data1, byte data2) {
  cmd = cmd | channel;        // merge channel number
  Serial.print((byte)cmd);    // command
  Serial.print((byte)data1);  // note number
  Serial.print((byte)data2);  // velocity
}
  
void checkIn(){
  if (Serial.available() > 0) {
    // read the incoming byte:
    incomingByte = Serial.read();

   switch (state){
      case 0:
    // look for as status-byte, our channel, note on
    // if (incomingByte== (144 | channel)){  // un comment and comment the line below - to read only one channel
      if ((incomingByte & 0xf0) == 0x90){    // this reads all channels
         noteDown = HIGH;
         state=1;
        }
    // look for as status-byte, our channel, note off
   // if (incomingByte== (128 | channel)){   // un comment and comment the line below - to read only one channel 
        if ((incomingByte & 0xf0) == 0x80){  // this reads all channels
         noteDown = LOW;
         state=1;
        }
        
       case 1:
       // get the note to play or stop
       if(incomingByte < 128) {
          note=incomingByte;
          state=2;
       }
       else{
       state = 0;  // reset state machine as this should be a note number
       }
       break;
       
       case 2:
       // get the velocity
       if(incomingByte < 128) {
         doNote(note, incomingByte, noteDown); // do something withh the note on message
       }
         state = 0;  // reset state machine to start            
     }
  }
}

void doNote(byte note, byte velocity, int down){
  // if velocity = 0 on a 'Note ON' command, treat it as a note off
  if ((down == HIGH) && (velocity == 0)){
      down = LOW; 
  }
  // do something with the note message 
  // this just toggles Pin 13 and ignores the note value and velocity
 if(down == LOW) digitalWrite(13, LOW); else  digitalWrite(13, HIGH);

}

Grazie mille Mike.

That was code for an older version of the IDE, sorry just spotted this, you need to use write not print to output MIDI

void noteSend(byte cmd, byte data1, byte data2) {
  cmd = cmd | channel;        // merge channel number
  Serial.write((byte)cmd);    // command
  Serial.write((byte)data1);  // note number
  Serial.write((byte)data2);  // velocity

ok

Hello Mike, when I connect the serial pin 0 RX to pin n°6 of 6N139 the Arduino's program generate an error while transfer the code.

avrdude: stk500_getsync(): not in sync: resp=0xfc

Do you know what's wrong?

You can't use the hardware MIDI interface at the same time as you upload stuff. You have to switch it out. See the switches in my MIDI shield on my site.

Yes it works! But all notes goes out from port 13.Can you write an example string for sending only one note (c3) to out port 2 please?

Thanks a lot

But all notes goes out from port 13.

Sorry I don't understand what you mean by that, could you explain.

ok I'll try ...at moment,loading your code, every midi note-on I'm gonna play goes out to digital port 13, but I'd need that 6 different Midi note goes out separately in 6 digital output.I'm sorry Mike, I hope to be enought clear... :~

No I don't get it. What code is this?

If it is the last code I posted then pin 13 is used only to light up an LED not push a note out on.

If it is the MIDI glock then pin 13 is the strobe that enables the solenoid drivers, not the output to the solenoid drivers they are on pins 2 to 9.

Hello Mike,did you ever checked the polyphony? that's, the ability to play two or more notes simultaneously. My prototype didn't does, I must shift a little bit the timing of notes ... do you know why?

The glock can only trigger notes at the rate of the monostable. However if while the monostable is firing another note comes along then it will play that as well.

Hi Mike,
I have opened new thread and only later found this one. I'm usign your code and schematics for midi glockenspiel. It all works awesome straigt! Now question is coud I implement velocity with current setup or driver circuit would change? Thanks a bunch! Cheers

Hi! I thought I would add to this thread since it is exactly what I want to know. I want to assign specific midi note (Middle C) to a specific Digital out (Pin 7).

I have gotten to a point where I can read incoming midi messages from channel 16 but I don't know how to listen for an exact note (s).

This is what I have so far:

#include <MIDI.h> // Add Midi Library

#define REW 7 // Arduino Board LED is on Pin 7

//Create an instance of the library with default name, serial port and settings
MIDI_CREATE_DEFAULT_INSTANCE();

void setup() {
pinMode (REW, OUTPUT); // Set Arduino board pin 13 to output
MIDI.begin(16); // Initialize the Midi Library.
MIDI.setHandleNoteOn(MyHandleNoteOn);
MIDI.setHandleNoteOff(MyHandleNoteOff);
}

void loop() { // Main loop
MIDI.read(); // Continuously check if Midi data has been received.
}

void MyHandleNoteOn(byte channel, byte pitch, byte velocity) {
digitalWrite(REW,HIGH); //Turn LED on
}

void MyHandleNoteOff(byte channel, byte pitch, byte velocity) {
digitalWrite(REW,LOW); //Turn LED off
}

1 Like

It sounds like you just need a couple of if statements in the NoteOn and NoteOff handlers. Have you tried anything at all? The note is given by the pitch value and middle C is 60.

Steve

Great! I think I just need a few breadcrumbs to follow. Let me see where this leads. Thanks!

Well that worked! Thanks slipstick! This code will be used to control my Revox A77 reel to reel tape recorder(s) with my DAW (Digital Performer) for performance and I just crossed the first big hurdle! Next step is to connect the Arduino to the relays of the machine. I will post the finished project when it is complete in a new post.

Wow I never thought I would see the day I would write my own program! It's an amazing feeling.

If there is a way to make this code more efficient please do let me know.

Thanks!

#include <MIDI.h>  // Add Midi Library


// Define labels for the 6 pins
#define REW 7   
#define FF 6
#define PLAY1 5
#define PLAY2 4
#define STOP 3
#define REC 2

//Create an instance of the library with default name, serial port and settings
MIDI_CREATE_DEFAULT_INSTANCE();



//output pin 7-2 when receiving noteON message with note = 60-65

void setup() {
  pinMode (REW, OUTPUT); 
  pinMode (FF, OUTPUT); 
  pinMode (PLAY1, OUTPUT); 
  pinMode (PLAY2, OUTPUT); 
  pinMode (STOP, OUTPUT); 
  pinMode (REC, OUTPUT); 
 
  MIDI.begin(16); // Initialize the Midi Library. Respond to notes on channel 16 only.
  MIDI.setHandleNoteOn(Press); 
  MIDI.setHandleNoteOff(Release); 
}

void loop() { // Main loop
  MIDI.read(); // Continuously check if Midi data has been received.
}

// Press 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 Press (byte channel, byte note, byte velocity){   
  if (note== 60 ){ 
  digitalWrite(REW,HIGH);  // Send on pin 7 
  }
  if (note == 61){
    digitalWrite(FF,HIGH);  // Send on pin 6
  }
   if (note == 62){
    digitalWrite(PLAY1,HIGH); 
    digitalWrite(PLAY2,HIGH);// Send on pin 4 and 5
  }
   if (note == 63){
    digitalWrite(STOP,HIGH);  // Send on pin 4
  }
   if (note == 64){
    digitalWrite(REC,HIGH); 
    digitalWrite(PLAY2,HIGH);// Send on pin 4 and 6
  }
}

// Release 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 Release(byte channel, byte note, byte velocity) {  
  if (note== 60){
  digitalWrite(REW,LOW);  // Stop send on pin 7
  }
   
    if (note== 61){
  digitalWrite(FF,LOW);  // Stop send on pin 6
    }
    
    if (note == 62){
  digitalWrite(PLAY1,LOW);
  digitalWrite(PLAY2,LOW);// Stop send on pin 4 AND 5
  }
   
    if (note == 63){
  digitalWrite(STOP,LOW);  // Stop send on pin 4
  }
 
    if (note == 64){
  digitalWrite(REC,LOW);
  digitalWrite(PLAY2,LOW);// Stop send on pin 2 AND 4
  }
  }

If there is a way to make this code more efficient please do let me know.

Make the notes and the pin numbers into an array each and all those if statements disappear into a for loop and single if.

For the cases with two digital writes like play1 and play2 have a separate array for these extra writes, this will be a sparse, that is lots of numbers that signify do nothing or the number of a pin. You then need another if statement inside the loop to see if you need to write the supplemental.

As a rule when you are doing the same thing over and over you can nearly always change this into an array and a loop.