Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

USB Host Shield Mini, not reconnecting. #593

Open
jhsa opened this issue Jan 24, 2021 · 130 comments
Open

USB Host Shield Mini, not reconnecting. #593

jhsa opened this issue Jan 24, 2021 · 130 comments

Comments

@jhsa
Copy link

jhsa commented Jan 24, 2021

Hi, If I disconnect the USB device from the shield and reconnect, or connect another USB device, most of the times I don't get a connection unless I reboot the Arduino and Shield assembly. Here is a picture of how I connected an Arduino Pro-Mini 8Mhz at 3.3V to the shield. the green numbers are the Arduino Pins.
Any ideas why this would happen?
Thank you very much for your help...

UT89srLXWRXXXagOFbX8

@Lauszus
Copy link
Collaborator

Lauszus commented Jan 24, 2021

Did you remember to cut the VBUS jumper?

@jhsa
Copy link
Author

jhsa commented Jan 24, 2021

You can see the cut on the picture above. that is how I did it. My board is exactly the same as the one in the picture. I did cut it where indicated. No jumper, just cut the track. If I hadn't cut it, the MAX chip would be already destroyed :)

@Lauszus
Copy link
Collaborator

Lauszus commented Jan 24, 2021

Sorry I missed the picture! What devices are you trying to use?

Please also enable serial debugging: https://github.com/felis/USB_Host_Shield_2.0#enable-debugging, so it gives me more information on what is going on.

@jhsa
Copy link
Author

jhsa commented Jan 24, 2021

Before I do anything else, please watch this little video I have made showing the problem.
Also, the arduino was a 16Mhz, and i replaced the crystal with an 8Mhz and burnt the correct fuses and the correct bootloader, so i don't think the arduino is the problem..
Thanks for looking into this.

https://www.youtube.com/watch?v=wQCUh8RX5ZQ

@Lauszus
Copy link
Collaborator

Lauszus commented Jan 24, 2021

Adding a VBUS power switch migth solve the problem: https://chome.nerpa.tech/mcu/vbus-power-control-on-usb-host-shield/.

@jhsa
Copy link
Author

jhsa commented Jan 24, 2021

That link gives me this error

502 Bad Gateway

@jhsa
Copy link
Author

jhsa commented Jan 24, 2021

Funny, just checked again, and only that commercial device seems to trigger that problem. If I connect my other devices that I built myself, an midi to USB converter (device) and my DIY guitar effect switcher, it seems to work ok.. Could it be that Boss ME-80 have a pullup on another USB data pin? I read that older equipment and newer equipment might be detected in different ways. But if i reboot the shield, the Boss device is detected. Weird.

@Lauszus
Copy link
Collaborator

Lauszus commented Jan 24, 2021

That link gives me this error
502 Bad Gateway

Weird. Can you try again?

Could it be that Boss ME-80 have a pullup on another USB data pin? I read that older equipment and newer equipment might be detected in different ways. But if i reboot the shield, the Boss device is detected. Weird.

The shield should work with both low and full speed devices, so that should not be the issue. Regarding the pull up resistor on D+ and D-, then it is simply used to identify a low and full speed device. You can read more about it here: https://www.beyondlogic.org/usbnutshell/usb2.shtml.

@jhsa
Copy link
Author

jhsa commented Jan 24, 2021

Still get the same "502 Bad Gateway" error. But thank you anyway.

The shield does work, the problem is that with the Boss pedalboard if I disconnect it, it doesn't connect to it anymore unless I reboot it. This thing can send Audio over USB and MIDI. I am using MIDI at the moment.
Thanks

@xxxajk
Copy link
Contributor

xxxajk commented Jan 25, 2021

Some devices only support high-speed USB, see if adding a powered hub solves the problem. The hub will translate full-speed to high-speed. This trick also works for super-speed only devices.

@jhsa
Copy link
Author

jhsa commented Jan 25, 2021

I didn't even know we could connect a hub with more devices to this shield :)
Actually, I did try one (very) old hub I have here but it didn't work. So I assumed it doesn't work with USB Hubs.

@Lauszus
Copy link
Collaborator

Lauszus commented Jan 26, 2021

Yes it's super easy. Just add this to your sketch:

#include <usbhub.h>
USBHub Hub1(&Usb);

@jhsa
Copy link
Author

jhsa commented Jan 26, 2021

Ahh, ok thanks. So, that will allow a Hub, and I could connect several devices to it, right? Or that Hub1 is just for one extra device connected to the Hub.. Sorry if it is a stupid question but I am a beginner in coding and certainly this USB stuff is new to me :)
Thank you again.

@Lauszus
Copy link
Collaborator

Lauszus commented Jan 26, 2021

Most hubs support 4 devices. Note a 7 port hub usually have two hub ICs inside where one of the downstream ports of the first IC is connected to the upstream port of the second hub, but you can simply just create two instances and the library will take care of the rest:

USBHub Hub1(&Usb);
USBHub Hub2(&Usb);

You can simply repeat that for as many as you need.

@jhsa
Copy link
Author

jhsa commented Jan 27, 2021

Cool, thank you so much.. Will try it tomorrow. Will then report.

@jhsa
Copy link
Author

jhsa commented Jan 27, 2021

Yes it's super easy. Just add this to your sketch:

#include <usbhub.h>
USBHub Hub1(&Usb);

Hi, question, do i need to add some more code? because i added this to the sketch and it is still not passing data on the Hub. I have:

/*
 *******************************************************************************
 * Legacy Serial MIDI and USB Host bidirectional converter
 * Copyright (C) 2013-2020 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>

// Satisfy the IDE, which needs to see the include statment in the ino too.
#ifdef dobogusinclude
#include <spi4teensy3.h>
#endif
#include <SPI.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);
USBHub Hub1(&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 myClock(void)
{

}
*/
void setup()
{
 MIDI.begin(MIDI_CHANNEL_OMNI);

  MIDI.turnThruOff();
//  MIDI.setHandleClock(myClock);
#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( msg[0] < 0xf0 ){
              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
}

@xxxajk
Copy link
Contributor

xxxajk commented Jan 28, 2021

Powered hub may be required.

@jhsa
Copy link
Author

jhsa commented Jan 28, 2021

ok, let me see if I find a power supply that fits this old hub. I do have a another hub but it has a different connector and i don't have an adapter for it :(

@jhsa
Copy link
Author

jhsa commented Jan 28, 2021

No, it doesn't work even with it powered. Is the code I posted above ok? Should it just work like that?
Thanks.

@jhsa
Copy link
Author

jhsa commented Jan 28, 2021

Forgot to say, when I insert the device connector in the hub slot, the corresponding LED turns ON. So, it seems it might be detected, but there is no data flowing as far as I can see

@YuuichiAkagawa
Copy link
Contributor

USB Usb;
USBHub  Hub1(&Usb);
USBH_MIDI Midi(&Usb);

@jhsa
Copy link
Author

jhsa commented Jan 30, 2021

It doesn't work.. At least with the hub I have.. Does it have to be some special sort of hub?
Thanks

@Lauszus
Copy link
Collaborator

Lauszus commented Jan 31, 2021

No any hub should be supported.

@jhsa can you try the following example: https://github.com/felis/USB_Host_Shield_2.0/blob/master/examples/hub_demo/hub_demo.ino?

@jhsa
Copy link
Author

jhsa commented Jan 31, 2021

Sure. But it doesn't compile. It seems some file is missing. The error is:

pgmstrings.h: No such file or directory

EDIT: I have jut created the pgmstrings.h file from github, and saved it in the sketch directory. It compiled now.

@jhsa
Copy link
Author

jhsa commented Jan 31, 2021

I guess you want to see the output from the IDE Monitor.

Start


41
--
String Descriptors:
Product:		USB2.0 Hub

Device descriptor: 
Descriptor Length:	12
Descriptor type:	01
USB version:		0200
Device class:		09
Device Subclass:	00
Device Protocol:	00
Max.packet size:	40
Vendor  ID:		05E3
Product ID:		0608
Revision ID:		0702
Mfg.string index:	00
Prod.string index:	01
Serial number index:	00
Number of conf.:	01

Configuration descriptor:
Total length:		0019
Num.intf:		01
Conf.value:		01
Conf.string:		00
Attr.:			E0
Max.pwr:		32

Interface descriptor:
Intf.number:		00
Alt.:			00
Endpoints:		01
Intf. Class:		09
Intf. Subclass:		00
Intf. Protocol:		00
Intf.string:		00

Endpoint descriptor:
Endpoint address:	81
Attr.:			03
Max.pkt size:		0001
Polling interval:	FF

Addr:41(1.0.1)

@jhsa
Copy link
Author

jhsa commented Feb 3, 2021

And, what does the monitor output mean?
Thanks.

@YuuichiAkagawa
Copy link
Contributor

I tested bidirectional_converter via HUB. It's working fine.

  • Arduino Pro Mini 328 - 3.3V/8MHz
  • USB Host Shield for Arduino Pro Mini
  • USB Hub (4port)
  • Zoom G1on
  • Arduino IDE 1.8.13 (Windows)
  • Arduino MIDI Library v5.0.2
  • Latest USB_Host_Shield_2.0 library
  • examples/USBH_MIDI/bidirectional_converter/bidirectional_converter.ino
    Uncomment line 47

I don't know why it doesn't work in your environment.

promini_ZoomG1on
promini_ZoomG1onMonitor jpg

@jhsa
Copy link
Author

jhsa commented Feb 8, 2021

Hi, thanks for your help.. I updated the library to the latest, flashed the code you linked above, uncommented line 47, the HUB is recognized as before, but it doesn't pass data to the USB MIDI adapter or to my guitar effect board. Both work when connected directly to the Host bidirectional converter. Just not through the hub. Need to find another Hub to test. This one might be too old. It does work when connected to a PC though..

@xxxajk
Copy link
Contributor

xxxajk commented Feb 11, 2021

USB hubs are "dumb" devices, and simply pass along the data. The only problems I have run into with hubs on UHS2 are:
1: Not enough power, use a powered hub
2: UHS2 hub enumeration can sometimes goof up bad if you disconnect in a certain order. Child hubs are not properly unallocated. Use a single hub in this instance.

@jhsa
Copy link
Author

jhsa commented Feb 11, 2021

Hi, the HUB I have works fine directly connected to the computer.

@xxxajk
Copy link
Contributor

xxxajk commented Feb 23, 2021

So basically, from what I'm understanding here, you are attempting to send messages FROM serial TO midi1 and midi2, correct?

@xxxajk
Copy link
Contributor

xxxajk commented Feb 23, 2021

Basically, I need to know what is routing to where.
from what midi
to which midi slaves

@jhsa
Copy link
Author

jhsa commented Feb 23, 2021

Yes, I am doing a bidirectional converter with a Hub. Please have a look at the bidirectional converter example. so, from USB to serial, and from serial to USB. Both directions.
I am also trying to have 3 Hub devices..

@xxxajk
Copy link
Contributor

xxxajk commented Feb 23, 2021

Ok, well, with a bit of parsing, I think I can get this to do what you want.
see appendices F and G, and you may be able to work this out before I can.
http://download.xskernel.org/docs/protocols/M2-104-UM_v1-0_UMP_and_MIDI_2-0_Protocol_Specification.pdf

@xxxajk
Copy link
Contributor

xxxajk commented Feb 23, 2021

Appendix D is probably what you really need to look at too.
It seems that this really depends on what spec that you want to support.
if you support midi2.0, we can have the USB bits query the stuff you have connected, and translate (most) messages to get what you want in an easy way.

@jhsa
Copy link
Author

jhsa commented Feb 23, 2021

I believe I am trying to use Midi 1.0 The old type midi. This is also what the midi library uses, right?

@jhsa
Copy link
Author

jhsa commented Feb 23, 2021

I think the 1st byte has the status and the channel number, and then another 2 bytes are the data bytes.
some midi messages use only the first databyte. example, the program change message. Other messages like note and control change use 2 databytes.

@xxxajk
Copy link
Contributor

xxxajk commented Feb 23, 2021

yeah, so, should be easy to do.
I'll base it on the current midi example.

@jhsa
Copy link
Author

jhsa commented Feb 23, 2021

Yes, thank you.. the bidirectional one..
But i got the feeling that there is a problem somewhere else :(

@xxxajk
Copy link
Contributor

xxxajk commented Feb 23, 2021

Nope, this should be pretty easy. (for me anyway)

@jhsa
Copy link
Author

jhsa commented Feb 23, 2021

Yeah, for you.. definitely not for me.... yet. Still on the steep side of the learning curve.. And I really appreciate your help. thank you.

@xxxajk
Copy link
Contributor

xxxajk commented Feb 23, 2021

Right, hence not exactly doable with this particular library. EMAIL me, I have an idea.

@jhsa
Copy link
Author

jhsa commented Feb 23, 2021

Done, I hope i got the right email address.
Thank you.

@xxxajk
Copy link
Contributor

xxxajk commented Feb 23, 2021

Yup! we can discuss options there.

@xxxajk
Copy link
Contributor

xxxajk commented Feb 23, 2021

Make sure my email didn't end up in your spam, whitelist it. ;-)

@YuuichiAkagawa
Copy link
Contributor

I found a NAK issue when sending to a slow device. It may not be the same as your problem.
https://youtu.be/xvV_jV5j5ns

If you want to retry when NAK is returned, you need to set "bmNakPower".

//for reconnect
for(uint8_t i=epDataInIndex; i<=epDataOutIndex; i++) {
epInfo[i].epAddr = (i==epDataInIndex) ? 0x81 : 0x01;
epInfo[i].maxPktSize = 0;
epInfo[i].bmSndToggle = 0;
epInfo[i].bmRcvToggle = 0;
}

        //for reconnect
        for(uint8_t i=epDataInIndex; i<=epDataOutIndex; i++) {
                epInfo[i].epAddr      = (i==epDataInIndex) ? 0x81 : 0x01;
                epInfo[i].maxPktSize  = 0;
                epInfo[i].bmSndToggle = 0;
                epInfo[i].bmRcvToggle = 0;
                // fix for NAK issue
                epInfo[i].bmNakPower  = (i==epDataOutIndex) ? 10 : USB_NAK_NOWAIT;    //<- add this line
        }

However, one slow device gets in the way and impacts performance.

https://youtu.be/bgKOMSGbiBI

@xxxajk
Copy link
Contributor

xxxajk commented Mar 1, 2021

... Or you could retry on your own, which wouldn't, because you could service the other devices.

@jhsa
Copy link
Author

jhsa commented Mar 5, 2021

I found a NAK issue when sending to a slow device. It may not be the same as your problem.
https://youtu.be/xvV_jV5j5ns

If you want to retry when NAK is returned, you need to set "bmNakPower".

//for reconnect
for(uint8_t i=epDataInIndex; i<=epDataOutIndex; i++) {
epInfo[i].epAddr = (i==epDataInIndex) ? 0x81 : 0x01;
epInfo[i].maxPktSize = 0;
epInfo[i].bmSndToggle = 0;
epInfo[i].bmRcvToggle = 0;
}

        //for reconnect
        for(uint8_t i=epDataInIndex; i<=epDataOutIndex; i++) {
                epInfo[i].epAddr      = (i==epDataInIndex) ? 0x81 : 0x01;
                epInfo[i].maxPktSize  = 0;
                epInfo[i].bmSndToggle = 0;
                epInfo[i].bmRcvToggle = 0;
                // fix for NAK issue
                epInfo[i].bmNakPower  = (i==epDataOutIndex) ? 10 : USB_NAK_NOWAIT;    //<- add this line
        }

However, one slow device gets in the way and impacts performance.

https://youtu.be/bgKOMSGbiBI

Yes, I have seen both problems from both videos.. When it fails, data start being one step behind, just like on your first video.
Now, I don't understand what I need to do. I am a beginner, remember? :)
Thank you

@jhsa
Copy link
Author

jhsa commented Mar 5, 2021

Ahh, wait, just need to add one line to .cpp ? Will do and test.. Then report.

@YuuichiAkagawa
Copy link
Contributor

Yes. Add a line after line 124 in usbh_midi.cpp.

@jhsa
Copy link
Author

jhsa commented Mar 8, 2021

Nope, that didn't fix the problem. As long as I send so´me midi with a note on or control change to my DIY controller, it starts staying one message behind.
What I find strange is that I have built some MIDI to USB converters using the same midi code as my controller, as well as the same processor, and I don't see this problem :(

@noahcgreen
Copy link

Has the original issue here (reconnecting the USB device without rebooting the Arduino) been solved, and if so, how? Also it would be helpful to know how and why a VBUS power switch would solve that issue.

@xxxajk
Copy link
Contributor

xxxajk commented Jul 24, 2021

Because it limits the inrush current.

@Lauszus
Copy link
Collaborator

Lauszus commented Jul 26, 2021

#653 might fix this issue.

@jhsa
Copy link
Author

jhsa commented Jul 30, 2021

#653 might fix this issue.

Was this already added to the library?
Thanks

@Lauszus
Copy link
Collaborator

Lauszus commented Jul 30, 2021

@jhsa no not yet.

It would help out a lot if you could download the code here: https://github.com/tmk/USB_Host_Shield_2.0/archive/refs/heads/upstream_fix_busprobe.zip and report back if it solves the issue.

@jhsa
Copy link
Author

jhsa commented Jul 31, 2021

@jhsa no not yet.

It would help out a lot if you could download the code here: https://github.com/tmk/USB_Host_Shield_2.0/archive/refs/heads/upstream_fix_busprobe.zip and report back if it solves the issue.

Thanks. This is the complete library that should replace the original, right?

@jhsa
Copy link
Author

jhsa commented Aug 2, 2021

Ok, quick test. removing and reconnecting a device seems to be working, at least with my setup. I didn't use it for a while due to other problems and had a couple problems to make it work. bad connections on the breadboard, etc.
Let's see if any of the other problems were fixed :) Thank you

@StureKn
Copy link

StureKn commented Feb 8, 2022

I had this problem with arduino uno and USB Host Shield 2.0 and found the fix here
https://forum.arduino.cc/t/sparkfun-usb-host-shield-working-with-oleg-usb-host-shield-2-0/73034/3

In fact, the hangs every time I touch D7

@jhsa
Copy link
Author

jhsa commented Feb 8, 2022

I have built my unit and put it in an enclosure. The fix provided above by Lauszus seemed to have done the trick.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants