read-write to USB devices (e.g. GPS, other devices with USB.. etcc)

timcurtin

Member
Joined
Dec 13, 2013
Messages
16
Programming Experience
5-10
Hello All,

So, how does someone go about reading and writing to devices (to be clear, hardware devices) with USB hardware interfaces? For example: If I want to read NMEA data from my Garmin GPS (yes, I know about setting the Garmin to NMEA TXT OUT), but in general, how do I read and write to a device that uses USB like I would with using a plain ole SerialPort control?

Thanks.
 

Herman

Well-known member
Joined
Oct 18, 2011
Messages
882
Location
Montreal, QC, CA
Programming Experience
10+
You have to go through the driver, user-space programs cannot talk directly to the hardware. Well except through HID, but even then you are using the Windows HID driver. If the GPS outputs NMEA-0183 packets, there are plenty of free libraries out there that will read it (google is your friend...). Garmin also has their own proprietary API which you can learn about on their developers website.
 

timcurtin

Member
Joined
Dec 13, 2013
Messages
16
Programming Experience
5-10
Hi Herman,

I am very familiar with NMEA-0183 and have written many Arduino and VB projects that interact with my own assembled GPS and other Dev Board (via Serial Port) GPS devices. Just to be clear however, what I am wanting to do for example is:

1. read-write to any device via it's USB-A or USB-B port, assuming that the device in question allows anything more than read. One example might be my amateur radio equipment or perhaps another device. So I need from what our saying, is an interface driver to talk to which will handle all calls for read-write to and from the device.

2. One project I'd like to write as a test is a test USB driver. Any ideas? Do I need anything special to undertake such a project? I am using at present VS 2012 but will have 2013 or whatever is out next in February of 2014.

THanks again Herman
 

Herman

Well-known member
Joined
Oct 18, 2011
Messages
882
Location
Montreal, QC, CA
Programming Experience
10+
1- It depends what the device is. If it has a Windows driver, you must use it to talk to the device. If the device is an HID device (like most development boards), you can use a generic driver included with Windows to talk to it. All that does however is provide a communications channel, you have to look up the device's documentation to figure out what commands do what... Some HID devices also have a specific driver (like keyboards and mice), and if you want to talk to those, you need to use that driver. Attached is a .Net wrapper I wrote for an old Microchip HID library, along with a test project. mcHID.dll is free, although I wouldn't know where to find the original installation nowadays. Just keep a copy of it along with mcHIDInterface.dll when you distribute. This library will let you talk to any generic HID device that has no driver loaded in Windows.

2- Developing a driver is entirely different to developing an application. First you need to download, install, and learn the Windows SDK, and learn C++.
 

Attachments

  • mcHIDInterface.zip
    384.8 KB · Views: 32

timcurtin

Member
Joined
Dec 13, 2013
Messages
16
Programming Experience
5-10
Thanks Herman,

Is there documentation included with your mcHID.dll library?

Also, how can I get a list of all drivers tied to each USB device attached to my Windows PC without going through Device Manager and searching through each item?

Thanks again.
 

Herman

Well-known member
Joined
Oct 18, 2011
Messages
882
Location
Montreal, QC, CA
Programming Experience
10+
Sorry, no real documentation, but the wrapper is simple enough to understand by looking at the code. mcHID.dll is itself an unmanaged wrapper to the usbhid.dll Win32 library. It was kind of hard to use and bulky to support in terms of code, so I wrote a managed wrapper for it.

To instantiate it:

Dim WithEvents USBDevice As New mcHIDInterface.HIDDevice

' Set these to the desired device's VID and PID
USBDevice.hidVendorID = &H0128
USBDevice.hidProductID = &H03A6

' This unhooks the previous device and hooks the new one
USBDevice.hidChangeDevice()


From there, you have a few events you can handle:

USBDevice.hidPlugged ' This event is raised when the desired device is plugged in and enumerated by Windows
USBDevice.hidUnplugged ' This event is raised when the desired device is disconnected
USBDevice.hidDataReady ' This event is raised when data was received from the device
USBDevice.hidDataRXError ' This event is raised when there was an error while receiving data from the device
USBDevice.hidDataSent ' This event is raised after calling SendBuffer() and after the data was successfully sent
USBDevice.hidDataTXError ' This event is raised when there was an error sending data to the device

And a few properties containing the device's descriptor items:

hidVendorID
hidProductID
hidProductName
hidVendorName
hidSerialNumber
hidVersion
hidInputReportLength
hidOutputReportLength

To send data to the device, you load the data into the output buffer and call SendBuffer(). Incoming data from the device raises the hidDataReady event, in which you can read the data from the input buffer.

As for getting a list of all drivers tied to each USB device, I'm sure it's possible, probably even easy through a WMI query, but I never attempted it... To get a list of all HID devices (including keyboards, mice, joysticks, which you cannot interact with...), click the "Ping all devices" button in the demo application, it will output a list of all HID devices currently connected, along with their VID, PID, and input and output report lengths.

For more information, a thorough read (or two) of the USB 2.0 standard (usb_20.pdf, especially chapters 4, 5 and 9...) is always a big help.
 

timcurtin

Member
Joined
Dec 13, 2013
Messages
16
Programming Experience
5-10
Hi Herman,

I'll play around with your demo application this week. So to be clear from reading your message, I CANNOT interact with ANY HID device on my WIndows PC or those of persons using my Applications? One thing my son would like me to attempt it to take devices such as Saitek Joystick's and panel devices and retrieve data from them and send data to them. and create some custom hardware, not available, and then integrate it with the Saitek items along with the new custom hardware. Mainly switch panels and POT panels etc.

I'd like to write if possible test App that will allow me to read input from my X-52 Saitek for example or other HID edvice, but I think you are saying I CANNOT interact with them. Correct? I think you are say9ing I have to use the vendor specific provided DLL / driver to interact with a given HID or other non-HID USB device, correct?

Thanks again Herman...
 

Herman

Well-known member
Joined
Oct 18, 2011
Messages
882
Location
Montreal, QC, CA
Programming Experience
10+
To read input from a mouse, keyboard, or joystick, you should use the DirectInput API, not try to talk to it directly. You CAN talk to a custom device, so long as you setup that device's USB descriptors as HID. If however what you want is design another input device (like a throttle pedal or steering wheel for example), then you need to give that device descriptors for a generic joystick more probably. This way Windows will detect it as a joystick to begin with, and you can map the buttons in games and such. I would probably get a cheap gamepad with analog sticks, take it apart, and hack the new controls into the original board (route every axis and button to a connector and plug in your devices; analog wheels to analog joystick axis, throttle pedals to analog triggers, buttons to buttons, etc... You could even use the force feedback (vibration) triggers off the original controller to drive some LEDs or gauges...). It's easier to emulate a 4-20ma analog signal or a voltage divider than a full USB joystick.
 
Last edited:
Top Bottom