USB Host Shield Library 2.0 USBH_MIDI bidirectional_converter

Hey all I found myself in need of a product that would convert 5pin MIDI into midi over USB to control my Hotone Ampero Mini from a midi controller that sends program change messages over a 5pin MIDI DIN cable connected to the arduino uno.

I found these instructions and library http://cyfrowogitarowo.pl/wp-content/uploads/2014/04/MIDI-USB-HOST-DIY-tutorial.pdf as to not reinvent the wheel. I've got it working but it has 1 quirk.

It only works if the Arduino is powered (at least when it starts) by a usb port on my computer. if the arduino is off, and I power it on from say, a 9v battery or other power source on the barrel jack, it won't function (at least not that I can tell from watching my ampero not change patches when I send it program change messages from a midi controller).

If I power on the arduino from a usb port on my PC, then plug in a barrel jack power supply, then unplug the USB to my computer, the unit functions just as it should, so it only seems to matter what power supply is used when the arduino first starts, leading me to think it's something with a serial connection that's made on startup.

I've done arduino projects before but it's always been my code instead of someone elses, and I'm not really familiar with this library, nor did I find my answer trying to dig through documentation on it. I'm sure that's a failure on my part. Hoping one of you can help me spot the problem. Exact code I'm using is straight from the library example "bidirectional_converter" from USB Host Shield Library 2.0

If anyone has the time to help me out I'd really appreciate it! Thanks in advance!

/*
 *******************************************************************************
 * Legacy Serial MIDI and USB Host bidirectional converter
 * Copyright (C) 2013-2021 Yuuichi Akagawa
 *
 * for use with Arduino MIDI library
 * https://github.com/FortySevenEffects/arduino_midi_library/
 *
 * Note:
 * - If you want use with Leonardo, you must choose Arduino MIDI library v4.0 or higher.
 * - This is sample program. Do not expect perfect behavior.
 *******************************************************************************
 */

#include <MIDI.h>
#include <usbh_midi.h>
#include <usbhub.h>

//Arduino MIDI library v4.2 compatibility
#ifdef MIDI_CREATE_DEFAULT_INSTANCE
MIDI_CREATE_DEFAULT_INSTANCE();
#endif
#ifdef USBCON
#define _MIDI_SERIAL_PORT Serial1
#else
#define _MIDI_SERIAL_PORT Serial
#endif

// Set to 1 if you want to wait for the Serial MIDI transmission to complete.
// For more information, see https://github.com/felis/USB_Host_Shield_2.0/issues/570
#define ENABLE_MIDI_SERIAL_FLUSH 0

//////////////////////////
// MIDI Pin assign
// 2 : GND
// 4 : +5V(Vcc) with 220ohm
// 5 : TX
//////////////////////////

USB Usb;
USBH_MIDI Midi(&Usb);

void MIDI_poll();

//If you want handle System Exclusive message, enable this #define otherwise comment out it.
#define USBH_MIDI_SYSEX_ENABLE

#ifdef USBH_MIDI_SYSEX_ENABLE
//SysEx:
void handle_sysex( byte* sysexmsg, unsigned sizeofsysex) {
  Midi.SendSysEx(sysexmsg, sizeofsysex);
}
#endif

void setup()
{
  MIDI.begin(MIDI_CHANNEL_OMNI);
  MIDI.turnThruOff();
#ifdef USBH_MIDI_SYSEX_ENABLE
  MIDI.setHandleSystemExclusive(handle_sysex);
#endif
  if (Usb.Init() == -1) {
    while (1); //halt
  }//if (Usb.Init() == -1...
  delay( 200 );
}

void loop()
{
  uint8_t msg[4];

  Usb.Task();
  if ( Midi ) {
    MIDI_poll();
    if (MIDI.read()) {
      msg[0] = MIDI.getType();
      switch (msg[0]) {
        case midi::ActiveSensing :
          break;
        case midi::SystemExclusive :
          //SysEx is handled by event.
          break;
        default :
          // If this is a channel messages, set the channel number.
          if( msg[0] < 0xf0 ){
            // The getchannel() returns 1-16, but the MIDI status byte starts at 0.
            msg[0] |= MIDI.getChannel() - 1; 
          }
          msg[1] = MIDI.getData1();
          msg[2] = MIDI.getData2();
          Midi.SendData(msg, 0);
          break;
      }
    }
  }
}

// Poll USB MIDI Controler and send to serial MIDI
void MIDI_poll()
{
  uint8_t size;
#ifdef USBH_MIDI_SYSEX_ENABLE
  uint8_t recvBuf[MIDI_EVENT_PACKET_SIZE];
  uint8_t rcode = 0;     //return code
  uint16_t  rcvd;
  uint8_t   readPtr = 0;

  rcode = Midi.RecvData( &rcvd, recvBuf);

  //data check
  if (rcode != 0) return;
  if ( recvBuf[0] == 0 && recvBuf[1] == 0 && recvBuf[2] == 0 && recvBuf[3] == 0 ) {
    return ;
  }

  uint8_t *p = recvBuf;
  while (readPtr < MIDI_EVENT_PACKET_SIZE)  {
    if (*p == 0 && *(p + 1) == 0) break; //data end

    uint8_t outbuf[3];
    uint8_t rc = Midi.extractSysExData(p, outbuf);
    if ( rc == 0 ) {
      p++;
      size = Midi.lookupMsgSize(*p);
      _MIDI_SERIAL_PORT.write(p, size);
      p += 3;
    } else {
      _MIDI_SERIAL_PORT.write(outbuf, rc);
      p += 4;
    }
#if ENABLE_MIDI_SERIAL_FLUSH
      _MIDI_SERIAL_PORT.flush();
#endif
    readPtr += 4;
  }
#else
  uint8_t outBuf[3];
  do {
    if ( (size = Midi.RecvData(outBuf)) > 0 ) {
      //MIDI Output
      _MIDI_SERIAL_PORT.write(outBuf, size);
#if ENABLE_MIDI_SERIAL_FLUSH
      _MIDI_SERIAL_PORT.flush();
#endif
    }
  } while (size > 0);
#endif
}

update: stripped down code, same problem.
only works when arduino is initialized connected to my computer.
I've tried connecting to/powering from other computers and other power sources, it only likes the computer I programmed it from.... arduino IDE doesnt have to be running. I'm stumped.

#include <MIDI.h>
#include <usbh_midi.h>
MIDI_CREATE_DEFAULT_INSTANCE();
USB Usb;
USBH_MIDI Midi(&Usb);
void setup() {
  MIDI.begin(MIDI_CHANNEL_OMNI);
  Usb.Init();
}
void loop() {
  uint8_t msg[4];
  Usb.Task();
  if (Midi) {
    if (MIDI.read()) {
      msg[0] = MIDI.getType();
      if (msg[0] < 0xf0) {
        msg[0] |= MIDI.getChannel() - 1;
      }
      msg[1] = MIDI.getData1();
      msg[2] = MIDI.getData2();
      Midi.SendData(msg, 0);
    }
  }
}

Alternative project using Teensy 3.6/4.1 for a Yamaha guitar effects amp.

I would not use 9V batteries for anything except transistor radios and smoke detectors. The problem may be voltage or current too low when powered via barrel jack. I would try 9V, 1A. Also try powering the amp via its 9V power port so it does not draw power (I hope) from the Arduino USB host port.

Or try using a USB power bank connected to the Arduino USB device port.

hey thanks for the link. I'll check that out. As for power, that's not it. It works fine with usb 2.0 from my computer (max current is 500mA at 5v on usb2) and I've also tried 1A and 2A usb power adapters (like phone chargers etc). tried barrel jack from my 1spot 9v 1700mA power supply I use for my pedalboard too. no dice. what really confuses me is that it will work when connected to MY computer. just mine. I've tried anther desktop, and 3 laptops, a few of which have the CH340 driver for the UNO chip, just like my computer does. and with my computer, nothing has to be running. no IDE, no utility anything for it at all. nothing. pulling my hair out (if I had any)

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.