Go Down

Topic: Arduino UNO and a MIDI Shield (Read 287 times) previous topic - next topic

sohal89

Hi all! I'm new to the world of Arduino and while I'm enjoying it, I find certain parts difficult.

Right so I have a small project I want to complete and I have no idea what to do.

If you guys would be able to help me out or even provide some sort of code to get me going, that would be greatly appreciated.

I need to create two separate codes for the following tasks

Task 1 - When SW1 is pressed, playing a note generates a major chord (the   notes +4 and +7 higher than the played note sound at the same time)

Task 2 - Normally the   MIDI   Shield should pass through   musical notes, however when SW1 is held pressed, drum sounds are played instead

The MIDI shield I am using... please see attached schematic image.

Many thanks

coxrk

#1
Mar 26, 2015, 08:35 pm Last Edit: Mar 26, 2015, 08:58 pm by CrossRoads
You first task is easy.  Start with the MIDI example called "MIDI_Callbacks".  Add the sending of the original note plus the other two notes in the "handleNoteOn" method and the corresponding note off stuff in handleNoteOff.  A little setup and testing adds the ability to look at SW1 - assuming your using the Sparkfun MIDI Shield which connects SW1 to Digital Pin 2.  See sample code below.  Note that I have not tested this code, but expect it to work okay. 

Your second task is not possible as you stated it.  MIDI by itself does not make the sound.  It only sends a note on or off.  However, you can send a change program message via midi to tell your MIDI sound source to select a musical sound or a drum sound.  You will have to decide which sounds you want and send the Program Change message to change the sound based on SW1.  See http://www.midi.org/techspecs/midimessages.php for the complete list of possible MIDI messages.

CODE for First Task:
 (code tags please!)
Code: [Select]

#include <MIDI.h>

MIDI_CREATE_DEFAULT_INSTANCE();

// -----------------------------------------------------------------------------

// This function will be automatically called when a NoteOn is received.
// It must be a void-returning function with the correct parameters,
// see documentation here:
// http://arduinomidilib.fortyseveneffects.com/a00022.html

void handleNoteOn(byte channel, byte pitch, byte velocity)
{
    // Do whatever you want when a note is pressed.
    MIDI.sendNoteOn( pitch, velocity, channel );
   
    // Note that a LOW value means the button was pushed.
    if ( digitalRead( 2 ) == LOW )
    {
      MIDI.sendNoteOn( pitch + 4, velocity, channel );
      MIDI.sendNoteOn( pitch + 7, velocity, channel );
    }

    // Try to keep your callbacks short (no delays ect)
    // otherwise it would slow down the loop() and have a bad impact
    // on real-time performance.
}

void handleNoteOff(byte channel, byte pitch, byte velocity)
{
    // Do something when the note is released.
    // Note that NoteOn messages with 0 velocity are interpreted as NoteOffs.
    // Sending all three note offs should not hurt anything
    // but you could add the test for SW1 as was done above
    MIDI.sendNoteOff( pitch, 0, channel );
    MIDI.sendNoteOff( pitch + 4, 0, channel );
    MIDI.sendNoteOff( pitch + 7, 0, channel );
   
    // if you have trouble with notes being stuff on, you can use the following
    // which turns off all notes
    MIDI.sendControlChange( 123, 0, channel );  // all notes off
}

// -----------------------------------------------------------------------------

void setup()
{
    // Connect the handleNoteOn function to the library,
    // so it is called upon reception of a NoteOn.
    MIDI.setHandleNoteOn(handleNoteOn);  // Put only the name of the function

    // Do the same for NoteOffs
    MIDI.setHandleNoteOff(handleNoteOff);

    // Initiate MIDI communications, listen to all channels
    MIDI.begin(MIDI_CHANNEL_OMNI);
   
    // Sets to input mode the digital pin that correspond to SW1
    // These are also pulled up to 5 v ( HIGH ) when the button is not pressed.
    // Pushing the button drops the value to LOW
    pinMode( 2, INPUT_PULLUP );  // left button
}

void loop()
{
    // Call MIDI.read the fastest you can for real-time performance.
    MIDI.read();

    // There is no need to check if there are messages incoming
    // if they are bound to a Callback function.
    // The attached method will be called automatically
    // when the corresponding message has been received.
}

Megasis

Regarding changing from playing an Instrument Patch to a Drum Patch, you could program SW1 to change the MIDI Channel from 1 to 7 (add 6 to channel), this way you don't need to send any program Change. 

The default MIDI channel for Drums is 7, so you could have pre-configure your sounds source (Module or Keyboard) in Channel 1 with an Organ and Channel 7  with Drums,  and SW1 will change the NOTE ON/OFF channel from 1 to 7, like this:

Channel 1 Note On:  hex 90 or dec 144
Channel 7 Note On:  hex 96 or dec 150

So just add 6 to the variable channel when SW1 is Pushed

void handleNoteOn(byte channel, byte pitch, byte velocity)
{
  // Note that a LOW value means the button was pushed.
  if ( digitalRead( 2 ) == LOW )
    {
    // Send Note to channel 7 (Drums)
    MIDI.sendNoteOn( pitch, velocity, channel + 6 );
    }
  else
    {
    // Send Note normally to channel 1.
    MIDI.sendNoteOn( pitch, velocity, channel );

    }

SAME FOR NOTE OFF

Go Up
 


Please enter a valid email to subscribe

Confirm your email address

We need to confirm your email address.
To complete the subscription, please click the link in the email we just sent you.

Thank you for subscribing!

Arduino
via Egeo 16
Torino, 10131
Italy