PDA

View Full Version : Windows USB example



gavagai
22nd March 2011, 22:08
This program is an example of how to use an USB device in Qt.
It is limited only to the HID devices class (joystick, mouse, keyboard...)
It uses the standard Microsoft HID driver. If you use another driver you must know how it works.
It demonstrates how to:
-recognize a device by VID&PID
-read/write
-attach/detach notification
Two examples are provided:
-first example reads the XY position of a joystick
-second example sends a message to the device and waits for the answer.

See comments in source for details.

Licence: GPL.

I hope that this program can be useful to someone.

high_flyer
23rd March 2011, 09:20
Excellent!
It might be a good idea if you'd add it to the examples section in the wiki, here it gets lost among the many other threads...
http://www.qtcentre.org/wiki/index.php?title=Category:Examples

wysota
23rd March 2011, 10:50
I don't like the idea of using global variables. And threads access those variables without a proper protection. This is bound to blow up sooner or later.

high_flyer
23rd March 2011, 10:52
I haven't looked at the code.

squidge
23rd March 2011, 20:41
When you say:



QString s;
//to find a better way for this...
while(lpdbv->dbcc_name[i] != 0)
{
s.append(lpdbv->dbcc_name[i]);
i++;
}
s = s.toUpper();


Have you tried:



QString s = QString::fromWCharArray(lpdbv->dbcc_name).toUpper();


Don't know if it'll work, it's just something that sprung into mind when I read your code/comment.

gavagai
25th March 2011, 22:30
hi squidge,
thanks for your suggestion. Yes, it works!
I had not seen this static function to convert wchar_t in QString.
Thanks again.

pavanbarot
31st March 2011, 08:25
Thanks for Share awesome Example for USB Communication...
but i have problem to devide...... The "Device Class GUID" is {6bdd1fc6-810f-11d0-bec7-08002be2092f}
can u please explain me more.

i'll try this type #define HID_CLASSGUID {0x6bdd1fc6, 0x810f, 0x11d0,{ 0x08, 0x00, 0x2b, 0xe2, 0x09, 0x2f }}
but result is same not connected ....

please help me, i m waiting for u r kindly reply...
thanks in advance.

gavagai
31st March 2011, 23:07
Don't use the class GUID returned by device manager, it don't works. It is the device SETUP GUID class. We need the device INTERFACE GUID class (see http://msdn.microsoft.com/en-us/library/ff549460(v=vs.85).aspx).
Try this:
- be sure that your device is installed and recognized in the system
- start regedit and search for your vid&pid (VID_XXXX&PID_XXXX) in the following key: HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Contro l\DeviceClasses. You can get more of a result.
- Try to use the parent class GUID where the descriptor starts with the type of device (##?#HID#VID... or ##?#IMAGE#VID...).
For more informations see the examples in http://msdn.microsoft.com/en-us/library/ff551069.aspx

Your device seems to be an image device. I do not know if endpoint size (InputBuffer and OutputBuffer size) is correct for this device. Depends on the driver.

Good luck

pavanbarot
1st April 2011, 06:24
Thanks a lot it's works fine....

gavagai
1st April 2011, 22:05
ok, it works but I think it is not exactly correct.
Your image shows a generic class GUID for all USB devices (##?# USB VID # ...).
Better to use a GUID for a specific class of devices.
Search again to find something like # #? # IMAGE # VID_XXXX&PID_XXXX and uses its GUID.
Maybe I'm wrong, but I think for read / write operations you must use a more specific GUID.

purnima
4th April 2011, 13:36
I am new member to this forum. So this information is useful for me. I will try this.

caodungviet
27th April 2011, 18:31
sorry but i don't understand about The "Device Class GUID", please you help me?? for example,
#define HID_CLASSGUID {0x6bdd1fc6, 0x810f, 0x11d0,{ 0x08, 0x00, 0x2b, 0xe2, 0x09, 0x2f }}
so :{ 0x08, 0x00, 0x2b, 0xe2, 0x09, 0x2f }.what is it??
please explain for me,i don't understand about it. what it means?? sorry ,because my english is not good

squidge
27th April 2011, 19:18
They are device class GUIDs used in device detection and classification. See the Windows DDK for more information and other GUIDs.

kuzulis
27th April 2011, 19:46
Hi all.
And why different descriptors for reading and writing device?
(You can also open once a one descriptor for reading and writing!)

squidge
27th April 2011, 21:16
Hi all.
And why different descriptors for reading and writing device?
(You can also open once a one descriptor for reading and writing!)

You can but that will not work across all devices. Some devices for example are read-only, so if you try to open them as read/write the call will fail, but if you have seperate read and write only the write will fail, so you know the device is read-only and don't need to do additional work (such as reopening as read only and setting a read-only flag). Typically however you will know this before writing code but as an example it is impossible to know this in advance.

kuzulis
27th April 2011, 22:10
aah, I understand, thank you.

caodungviet
28th April 2011, 10:19
i can conect with USB, but when i open it ,so my computer is broke dow,, why such that??

squidge
28th April 2011, 10:32
Please rephrase. Don't understand.

caodungviet
28th April 2011, 11:32
sorry, because my english is not good..i can connect this project with USB,but when i open this project ,my computer can't run.
please help me!!

wysota
28th April 2011, 11:37
You mean it reboots?

caodungviet
2nd June 2011, 15:48
sorry but i can't understand how you can search HID_CLASSGUID {0x6bdd1fc6, 0x810f, 0x11d0,{ 0x08, 0x00, 0x2b, 0xe2, 0x09, 0x2f }},.everytime i have searched and i allway search "{a5dcbf10-6530-11d2-901f-00c04fb951ed}" with the another USB.
please help me!! thanks
Please give me the directions by images!!

squidge
2nd June 2011, 17:21
I don't understand your question. This example is made for HID devices, a5dcbf10-6530-11d2-901f-00c04fb951ed is USB raw device ?

caodungviet
3rd June 2011, 10:01
sorry, i wrong. However how can you find PID and VID of a USB HID?? please help me!!

squidge
3rd June 2011, 10:25
Use SetupDi API

bigblondewolf
4th August 2011, 19:14
Hi there

I'm a newbie in c++ programming, I'm doing my thesis and stealing code from here and there.... So thanks for the example first!

I noted that the ReadThread is actually eating one CPU because it's in an endless loop, checking for events. I added a sleep statement that lets it run once per second and CPU usage dropped dramatically. Of course you lose responsiveness and you get a notification a second after the device is plugged in, but I don't think it's a major drawback.

EDIT: My bad, I'm looking from the perspective of my device (a thermometer) that really doesn't run in realtime. Following joystick movement requires more frequent updates. Still some delay of 0.01sec won't be noticeable and should reduce CPU usage too.

stringer
21st December 2011, 12:56
Hi, all!
First of all I want to tell "Thanks" for this example!
Now I write project for using Magnetic Stripe Reader that recognized by Windows as USB HID Device:

##?#HID#VID_1136&PID_3003#6&2b575f1c&0&0000#{4d1e55b2-f16f-11cf-88cb-001111000030}
But in this example it always return INVALID_HANDLE_VALUE in usbexample.cpp:273 on:

ReadHandle = CreateFile((DetailedInterfaceDataStructure->DevicePath), GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, 0);
And DevicePath is correct:

qDebug() << QString::fromWCharArray(DetailedInterfaceDataStruc ture->DevicePath);
return

\\?\hid#vid_1136&pid_3003#6&2b575f1c&0&0000#{4d1e55b2-f16f-11cf-88cb-001111000030}

What's wrong?

pavanbarot
21st December 2011, 13:11
Hi stringer,

try following code might it help's you.


HANDLE hFile = CreateFile( DetailedInterfaceDataStructure->DevicePath, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL );

stringer
21st December 2011, 15:16
Thanks for quick reply!
But nope!

Added after 32 minutes:

When I call GetLastError() after CreateFile, I get number 5. Google tell me that this is ERROR_ACCESS_DENIED. Why?
My System is Windows 7 x64 with disabled UAC.

stringer
22nd December 2011, 15:35
Assignment of WriteHandle goes well, but ReadHandle generate error ERROR_ACCESS_DENIED.
Maybe, for my task, use RAW Input Devices like here: http://msdn.microsoft.com/en-us/library/windows/desktop/ms645546(v=vs.85).aspx ?
But I don't know how. Can anybody help me?

stringer
22nd December 2011, 21:43
Hooray! I get the example to WORK!
I just needed to switch MSR (Magnetic Stripe Reader) Mode from "Keyboard Emulation Mode" to "HID Mode" via 3rd Party Utility which absent in box for MSR.

arunpk
6th January 2012, 06:37
i am trying to develop qt application using USB to control relay board..... I was trying this windows USB Example...
always getting an error message " :: error: No rule to make target `../../qt/2010.05/qt/mkspecs/win32-g++/qmake.conf', needed by `makefile'. Stop." Can anyone please give suggestion how to recover from this error.........Is there any sample application available using USB in windows.....

arunpk
6th January 2012, 13:07
please reply to my post......can any one help me to overcome this problem.....

wysota
6th January 2012, 14:56
Call qmake. This has nothing to do with USB.

arunpk
7th February 2012, 13:25
Please help me regarding this !!!!!!!!!!!!!... i have entered correct VID & PID for the device but this application is not showing the device connected......
i tried to connect USB relay board which uses Microchip Pic 18 series.... I want to control those relays through USB......

wysota
7th February 2012, 14:26
Are you sure your device is compliant with this example?

arunpk
8th February 2012, 09:32
My device is getting connected with this app....... now the proble is that, wen am creating file ReadHandle and WriteHandle bot are getting value 0xffffffff...... i tried by changing the values but no use..... when i tried to display device path its showing correct only...... CreateFile function always returns 0xffffffff only..............

galrub
9th February 2012, 16:33
Hello, I am using this example and it seems to be recognizing my HID device just fine in the checkUSB(),
but, in the winEvent I am getting wParam = 7 all the time, both when I connect or disconnect the device, so it doesn't catch these events:
DBT_DEVICEARRIVAL = 0x8000 and DBT_DEVICEREMOVECOMPLETE = 0x8004.

any ideas?
Thanks

stringer
9th February 2012, 19:22
My device is getting connected with this app....... now the proble is that, wen am creating file ReadHandle and WriteHandle bot are getting value 0xffffffff...... i tried by changing the values but no use..... when i tried to display device path its showing correct only...... CreateFile function always returns 0xffffffff only..............
Try to use this libraries and demos: microchip.com (http://www.microchip.com/stellent/idcplg?IdcService=SS_GET_PAGE&nodeId=2680&dDocName=en547784)

Added after 6 minutes:


Hello, I am using this example and it seems to be recognizing my HID device just fine in the checkUSB(),
but, in the winEvent I am getting wParam = 7 all the time, both when I connect or disconnect the device, so it doesn't catch these events:
DBT_DEVICEARRIVAL = 0x8000 and DBT_DEVICEREMOVECOMPLETE = 0x8004.

any ideas?
Thanks

Try to add this line into .pro file:

DEFINES += _WIN32_WINNT=0x0501

galrub
9th February 2012, 21:03
Try to use this libraries and demos: microchip.com (http://www.microchip.com/stellent/idcplg?IdcService=SS_GET_PAGE&nodeId=2680&dDocName=en547784)

Added after 6 minutes:



Try to add this line into .pro file:

DEFINES += _WIN32_WINNT=0x0501

well, it's just a part of the issue, I just realized that the USB hub for the front panel of this PC is, well, not a very 'well built' one,
so this is why I get the wParam = 7, I tried using the USB socket in the back... no problem there.
thanks.

SteveH
16th February 2012, 10:21
Hi All,

I've followed this thread with great interest and with Gavagai's very usefull initial sourcefiles and everyone else's additions I finally managed to get a working usb interface between my PIC 4550 chip and a pc. I've attached my sources for both ends of the link so that others might find them useful. I also added some extra error trapping to make my life easier.

Note the PIC end is on a Mikroelectronica EasyPIC4 board using their C Pro software.

Marc van der Kamp
14th March 2012, 07:27
Hi All,
After I found this example I was very happy and even before trying I modified it to match with my application... then I found out that device detection worked properly but write failed.
I get a proper read and write handle, no errors at write, but... it seems to send nothing.

I went back to the example changed nothing but MY_DEVICE_VIDPID and added a debug message after WriteFile to check BytesWritten
It may be clear that the protocol to my device differs, but I should at least be able to send something even when it is wrong -- or not?
If I only received an error would help already :)

any ideas?
Thanks

---
BytesWritten always 0

Marc van der Kamp
14th March 2012, 13:56
Oops... inverted my error checking, WriteFile did give an error (87)

SibelLa
29th March 2012, 13:19
Hi there,
I have the same error..I am wondering if you managed to fix it!!
Thanks

ommharidaas
27th April 2012, 06:34
Don't use the class GUID returned by device manager, it don't works. It is the device SETUP GUID class. We need the device INTERFACE GUID class (see http://msdn.microsoft.com/en-us/library/ff549460(v=vs.85).aspx).
Try this:
- be sure that your device is installed and recognized in the system
- start regedit and search for your vid&pid (VID_XXXX&PID_XXXX) in the following key: HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Contro l\DeviceClasses. You can get more of a result.
- Try to use the parent class GUID where the descriptor starts with the type of device (##?#HID#VID... or ##?#IMAGE#VID...).
For more informations see the examples in http://msdn.microsoft.com/en-us/library/ff551069.aspx

Your device seems to be an image device. I do not know if endpoint size (InputBuffer and OutputBuffer size) is correct for this device. Depends on the driver.

Good luck

Hi gavagai,
First of all thanks for the great upload.
I am tryint to build qt application to detect a usb device(Not necessarily a HID) when plugged in.
Now, i have two HIDs connected to my PC a keyboard and a mouse.
how do i know which VID/PID is for which device? Coz its really confusing even when i navigate to registry location you mentioned above.
how does HID differs from Mass storage device in terms of VID/PID?
Just want to put me in the right direction.
Thnx.

SibelLa
22nd June 2012, 13:56
Hi Marc van der Kamp,

I am still getting error 87.. Have you fixed it ? I really need to make it work..
Please help me..

Many thanks


Oops... inverted my error checking, WriteFile did give an error (87)

Hi Marc van der Kamp,

I am still getting error 87.. Have you fixed it ? I really need to make it work..
Please help me..

Many thanks

TapsaA
3rd December 2014, 09:03
Thanks for great example. With Qt 5 you should use code like:

To header:
bool nativeEvent(const QByteArray & eventType, void * message, long *result);

And to CPP:
bool USBexample::nativeEvent(const QByteArray & eventType, void * message, long *result)
{
MSG* msg = reinterpret_cast<MSG*>(message);
...
}

fazel459
7th June 2015, 10:00
Hi
How i can get product name of HID device?
Thanks