Forum Rule: Always post complete source code & details to reproduce any issue!
Results 1 to 5 of 5

Thread: How do you send a MIDI control change message using the USB Host Shield library?

  1. #1
    Junior Member
    Join Date
    Jan 2019
    Posts
    10

    How do you send a MIDI control change message using the USB Host Shield library?

    I'm trying to use the USB Host Shield 2.0 library to send a control change message to a MIDI device. The MIDI device is connected to the Teensy 3.2 via a USB Host Shield. The device set to MIDI channel 2.

    I'm not sure how the message should be formatted, I think I need an example to understand the how a CC message should look.

    I have verified the USB host shield is working and have use it and the library successfully for other projects

    From the library's usbh_midi.cpp file:


    /////////////////////////
    // MIDI MESAGES
    // midi.org/techspecs/
    //////////////////////////
    // STATUS BYTES
    // 0x8n == noteOff
    // 0x9n == noteOn
    // 0xAn == afterTouch
    // 0xBn == controlChange
    // n == Channel(0x0-0xf)
    //////////////////////////
    //DATA BYTE 1
    // note# == (0-127)
    // or
    // control# == (0-119)
    //////////////////////////
    // DATA BYTE 2
    // velocity == (0-127)
    // or
    // controlVal == (0-127)
    ///////////////////////////////////////////////////////////////////////////////
    // USB-MIDI Event Packets
    // usb.org - Universal Serial Bus Device Class Definition for MIDI Devices 1.0
    ///////////////////////////////////////////////////////////////////////////////
    //+-------------+-------------+-------------+-------------+
    //| Byte 0 | Byte 1 | Byte 2 | Byte 3 |
    //+------+------+-------------+-------------+-------------+
    //|Cable | Code | | | |
    //|Number|Index | MIDI_0 | MIDI_1 | MIDI_2 |
    //| |Number| | | |
    //|(4bit)|(4bit)| (8bit) | (8bit) | (8bit) |
    //+------+------+-------------+-------------+-------------+
    // CN == 0x0-0xf
    //+-----+-----------+-------------------------------------------------------------------
    //| CIN |MIDI_x size|Description
    //+-----+-----------+-------------------------------------------------------------------
    //| 0x0 | 1, 2 or 3 |Miscellaneous function codes. Reserved for future extensions.
    //| 0x1 | 1, 2 or 3 |Cable events. Reserved for future expansion.
    //| 0x2 | 2 |Two-byte System Common messages like MTC, SongSelect, etc.
    //| 0x3 | 3 |Three-byte System Common messages like SPP, etc.
    //| 0x4 | 3 |SysEx starts or continues
    //| 0x5 | 1 |Single-byte System Common Message or SysEx ends with following single byte.
    //| 0x6 | 2 |SysEx ends with following two bytes.
    //| 0x7 | 3 |SysEx ends with following three bytes.
    //| 0x8 | 3 |Note-off
    //| 0x9 | 3 |Note-on
    //| 0xA | 3 |Poly-KeyPress
    //| 0xB | 3 |Control Change
    //| 0xC | 2 |Program Change
    //| 0xD | 2 |Channel Pressure
    //| 0xE | 3 |PitchBend Change
    //| 0xF | 1 |Single Byte
    //+-----+-----------+------------------------


    My sample code, which does not work, i.e. the device does not respond. I think I have the hex values/message wrong.
    Code:
    #include <usbh_midi.h>
    #include <usbhub.h>
    
    USB Usb;
    //USBHub Hub(&Usb);
    USBH_MIDI  Midi(&Usb);
    
    void setup()
    {
      Serial.begin(115200);
      if (Usb.Init() == -1) {
        while (1); //halt
      }//if (Usb.Init() == -1...
      delay( 200 );
    }
    
    void loop()
    {
      Usb.Task();
      ccOn();
      delay(400);
      ccOff();
      delay(100);
    }
    
    //note On
    void controlChangeOn(void)
    {
      uint8_t buf[3];
      buf[0] = 0x1B; // Control change type message on channel 2 ??
      buf[1] = 0x51; // control change #81
      buf[2] = 127; // turn effect off
      Midi.SendData(buf);
    }
    
    //note Off
    void controlChangecOff(void)
    {
      uint8_t buf[3];
      buf[0] = 0x1B; // Control change type message on channel 2 ??
      buf[1] = 0x51; // control change #81
      buf[2] = 0;   // turn effect off
      Midi.SendData(buf);
    }
    Last edited by SteveO; 03-02-2019 at 12:36 AM. Reason: Fixed typo in code

  2. #2
    Senior Member
    Join Date
    Nov 2012
    Posts
    1,069
    In both cases, buf[0] should be 0xB1 for a CC message on channel 2.

    Pete

  3. #3
    Junior Member
    Join Date
    Jan 2019
    Posts
    10
    Thanks Pete,

    I changed my code to buf[0] = 0xB1; I also noticed I had another mistake in the code above, corrected code with your suggestion below. I'm still not getting a response from my MIDI device. If the CC message is now correct it must be a something else. The device does accept sysex messages via a library called MS3. The device also responds to PC and CC messages from a Raspberry PI. This might not be an easily fixable problem using the USB Host Shield library.

    Code:
    #include <usbh_midi.h>
    #include <usbhub.h>
    
    USB Usb;
    //USBHub Hub(&Usb);
    USBH_MIDI  Midi(&Usb);
    
    void setup()
    {
      Serial.begin(115200);
      if (Usb.Init() == -1) {
        while (1); //halt
      }//if (Usb.Init() == -1...
      delay( 200 );
    }
    
    void loop()
    {
      Usb.Task();
      controlChangeOn();
      delay(400);
      controlChangecOff();
      delay(400);
    }
    
    //note On
    void controlChangeOn(void)
    {
      uint8_t buf[3];
      buf[0] = 0xB1; // Control change type message on channel 2 ??
      buf[1] = 0x51; // control change #81
      buf[2] = 127; // turn effect off
      Midi.SendData(buf);
    }
    
    //note Off
    void controlChangecOff(void)
    {
      uint8_t buf[3];
      buf[0] = 0xB1; // Control change type message on channel 2 ??
      buf[1] = 0x51; // control change #81
      buf[2] = 0;   // turn effect off
      Midi.SendData(buf);
    }

  4. #4
    Senior Member
    Join Date
    Nov 2012
    Posts
    1,069
    It might be difficult to distinguish between no response from the MIDI device (what is it anyway?) and failing to initialize the USB host device.
    Print a message when the init fails.
    Code:
      if (Usb.Init() == -1) {
        Serial.println("Usb.Init() failed");
        while (1); //halt
      }//if (Usb.Init() == -1...
    Pete

  5. #5
    Junior Member
    Join Date
    Jan 2019
    Posts
    10
    Ok, I added the Print and it looks like the the USB Host is initializing the host device.

    The device is a Boss Katana amplifier. I'm not sure this is going to be easy and really don't expect anyone to help me fix this problem but I'll elaborate anyway. This is the project I'm working on: https://github.com/SteveObert/KatanaUSB_Midi_controller. The code is still very much a work in progress and does not yet include the test code I posted in this thread.

    I'm working on adding the expression pedal and have it working with sysex in a limited fashion. However, if I can get it to work with CC messages it will be much more flexible because each effect requires a different sysex message for foot pedal control, but a change control 81 should work for any effect.

    In the code below, which is part of the full code, I'm trying to replace MS3.write(FV_PDL, pedalVal1, 1); with Midi.SendData(buf); where buff is CC 81 channel 2 pedalVal1.

    Code:
      MIDI.read();
    
      //handle expression pedal 1 input
      if (millis() - lastRead1 > 40 && exp1Connected_sel == 1) {   // This delay is necessary to prevent overwhelming the MS3 queue
    
        pedalVal1 = analogRead(8);
        pedalVal1 = map(pedalVal1, exp1Min, exp1Max, 0, 63);     // apply the calibration to the sensor reading
        pedalVal1 = constrain(pedalVal1, 0, 63);     // in case the pedal value is outside the range seen during calibration
    
        if (abs(pedalVal1 - lastPedalVal1) > 1) { // If the value does not = the last value the pedal has moved.
          MS3.write(FV_PDL, pedalVal1, 1);
          lastRead1 = millis();
          lastPedalVal1 = pedalVal1;  // remeber the last value of the pedal position so we can see if it changed later
          Serial.print("expression pedal 1 position: ");
          Serial.println(pedalVal1);
        }
      }

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •