Saturday, 28 February 2015

MIDI for the Arduino - Arduino MIDI Library Input Test

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.


13 comments:

  1. First off - great series on MIDI. This was the most straight-forward how-to I have found.

    I 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

    ReplyDelete
    Replies
    1. 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.

      To 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.

      Delete
    2. Thanks for the fast response Dave,

      The 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

      Delete
    3. 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).
      The 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);
      }
      }

      Delete
    4. Thank you! That worked. Now I need to do a bit of if/else statement work.

      Thanks again,

      CG

      Delete
    5. Coding hint:
      For 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 ==.

      Delete
  2. This comment has been removed by the author.

    ReplyDelete
  3. Hi, 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...
    How can I do?
    thanks so much

    ReplyDelete
    Replies
    1. 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**

      Delete
    2. thanks for answer... where I should put the modification? inside void loop?

      Delete
    3. Hi, 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.

      #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
      }

      }

      Delete
  4. 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.

    ReplyDelete
  5. Awesome, 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!

    ReplyDelete