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

Thread: easy way to get the name of a device connected to the USB host ?

  1. #1
    Member
    Join Date
    Sep 2019
    Location
    Sevilla, Spain
    Posts
    55

    easy way to get the name of a device connected to the USB host ?

    Hello, I would like to make some special function if a device is connected to the Teensy 4.1 though the USB host,
    uncommenting this line in USBHost_t36.h shows the device name as 'product ' in the serial monitor, but I have no idea how to make my code to get that info, which is probably pretty easy
    Code:
    #define USBHOST_PRINT_DEBUG
    any help would be much appreciated
    thanks!

  2. #2
    Senior Member+ KurtE's Avatar
    Join Date
    Jan 2014
    Posts
    9,034
    If you wish to get the product name of a device that has connected to one of your USB Host objects, there are methods on them to do so:

    Most of the examples with the library have code like:
    Code:
      for (uint8_t i = 0; i < CNT_DEVICES; i++) {
        if (*drivers[i] != driver_active[i]) {
          if (driver_active[i]) {
            Serial.printf("*** Device %s - disconnected ***\n", driver_names[i]);
            driver_active[i] = false;
          } else {
            Serial.printf("*** Device %s %x:%x - connected ***\n", driver_names[i], drivers[i]->idVendor(), drivers[i]->idProduct());
            driver_active[i] = true;
    
            const uint8_t *psz = drivers[i]->manufacturer();
            if (psz && *psz) Serial.printf("  manufacturer: %s\n", psz);
            psz = drivers[i]->product();
            if (psz && *psz) Serial.printf("  product: %s\n", psz);
            psz = drivers[i]->serialNumber();
            if (psz && *psz) Serial.printf("  Serial: %s\n", psz);
          }
        }
      }
    
      for (uint8_t i = 0; i < CNT_HIDDEVICES; i++) {
        if (*hiddrivers[i] != hid_driver_active[i]) {
          if (hid_driver_active[i]) {
            Serial.printf("*** HID Device %s - disconnected ***\n", hid_driver_names[i]);
            hid_driver_active[i] = false;
          } else {
            Serial.printf("*** HID Device %s %x:%x - connected ***\n", hid_driver_names[i], hiddrivers[i]->idVendor(), hiddrivers[i]->idProduct());
            hid_driver_active[i] = true;
    
            const uint8_t *psz = hiddrivers[i]->manufacturer();
            if (psz && *psz) Serial.printf("  manufacturer: %s\n", psz);
            psz = hiddrivers[i]->product();
            if (psz && *psz) Serial.printf("  product: %s\n", psz);
            psz = hiddrivers[i]->serialNumber();
            if (psz && *psz) Serial.printf("  Serial: %s\n", psz);
          }
        }
      }
    The first loop prints out all of the top level object that have connected. By top level, these are ones that connect up at the USBDriver level, like keyboard, hub, ...

    The second loop are those who then connect up at a HID level (Human Interface Device). That is ones who are driven by a table that is loaded from the device that describes the format of the data. This often includes ones like Mouse, joystick, ... At times it is hard to know the differentiation between these groups, as for example some Joysticks may work at HID level others directly... This code does not show it but there is a third version, of those that connect up through bluetooth... There are examples that show this as well.

    Now if you are wanting to see the name of a device that connects that tries to connect that no driver claims, I am not sure we exported anything to do so. Probably could if needed.

  3. #3
    Member
    Join Date
    Sep 2019
    Location
    Sevilla, Spain
    Posts
    55
    yes, I've seen that example, indeed I tried something with no luck
    Code:
    USBHost myusb;
    USBHub hub1(myusb);
    USBDriver *drivers = &hub1;
    
    ...
    
    const uint8_t *psz = drivers->product();
    if (psz && *psz) Serial.printf("  product: % s\n", psz);
    it does not print anything after " product:"
    maybe is a HID device,

  4. #4
    Senior Member+ KurtE's Avatar
    Join Date
    Jan 2014
    Posts
    9,034
    Again this only works if that hub1 is actually connected as a USBHub. AND that it actually has a name that they put into their USB Descriptor, which is optional. Some devices do not.

    From your above:
    Code:
    USBHost myusb;
    USBHub hub1(myusb);
    
    ...
    
    if (hub1) {
        const uint8_t *psz = hub1.product();
        if (psz && *psz) Serial.printf("  product: % s\n", psz);
    Now the original code has a list of devices and remembers if that device as connected previously or not and tries to only print the data once...

  5. #5
    Member
    Join Date
    Sep 2019
    Location
    Sevilla, Spain
    Posts
    55
    @KurtE I've try that too, without success.
    For the record, I finally solved this by using the VID and DID instead of the USB names, and did it with a simplified version of the USBDeviceInfo class from the HIDDeviceInfo example in the Teensy library,
    when a USB device is connected it sends the vendor and product id due to that 'claim' thing:

    USBDeviceInfo.h
    Code:
    /* USB Device Info class
     ...license...
     */
    
    // This simple class does nothing, but print out information about the device it
    // extracts from calls to claim... 
    
    #ifndef __USBDeviceInfo_h_
    #define __USBDeviceInfo_h_
    #include <Arduino.h>
    #include <USBHost_t36.h>
    
    class USBDeviceInfo : public USBDriver {
    public:
    	USBDeviceInfo(USBHost &host) { init();}
    
    protected:
    	virtual bool claim(Device_t *dev , int type , const uint8_t *descriptors, uint32_t len 
    	
    	);
    	virtual void disconnect() {};
    	void init();
    };
    #endif
    USBDeviceInfo.cpp
    Code:
    /* USB Device Info class
     ...license...
     */
    
    // This simple class does nothing, but print out information about the device it
    // extracts from calls to claim... 
    
    #include <Arduino.h>
    #include <USBHost_t36.h>
    #include "USBDeviceInfo.h"
    
    extern void vid_did(uint16_t vid, uint16_t did);
    
    void USBDeviceInfo::init()
    {
    	driver_ready_for_device(this);
    }
    // Again this class is solely to display as much information about a device as we can...
    // This all comes from the information passed to it through the claim method.
    bool USBDeviceInfo::claim(Device_t *dev , int type , const uint8_t *descriptors, uint32_t len) 
    {
    	if (type == 0) 
    	{
    		// At device level
            vid_did(dev->idVendor, dev->idProduct);
    		return false;
        }
    	return false;
    }
    this will not work without the USBHub
    Code:
    #include <USBHost_t36.h>
    USBHost myusb;
    USBHub hub1(myusb);
    #include "USBDeviceInfo.h"
    USBDeviceInfo dinfo(myusb);
    Maybe the variable used in the vid_did() function should be declared as volatile, but in my case it does work fine as is.

  6. #6
    Senior Member+ KurtE's Avatar
    Join Date
    Jan 2014
    Posts
    9,034
    As you mentioned the code assumes you have the device specified.

    Also the code the code like: const uint8_t *psz = hub1.product()
    Will only return a name if the product actually declared a string object in their USB descriptor for the product name. Some may not.

    But as mentioned they all will have a vendor id(VID) and product id(PID).

Posting Permissions

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