[C++]communicating with a USB device made by me

Started by
9 comments, last by Hassanbasil 13 years, 7 months ago
Hello everyone,

I want to make a simple device, which is just a button (or possibly several ones), and i want to be able to get the state of these buttons (down-up) in my C++ application, problem is, i have never done such thing before (or lets say, i have never tried to use hardware with my apps)

So i suppose it should be something like this: the device should have a usb cable, and i need to write a driver for it, and the driver sends info to my application

my questions are:
1- how to create the driver?
2- after creation, how do the driver communicate with my application?

I' be really thankful if someone coul point me in the right direction, as i dont even know where to start


using windows 7 32-bit
the only language i know is C++, so i hope i dont need to learn another in order to do this


regards
-Hassan
Advertisement
I would recommend you get something like the minipac. Very easy to use. It registers itself as a USB keyboard so no special drivers need. Also it is programmable so you can set the jumpers to map to whatever keys you want. Just hook up your micro-switches and go.

edit:
If for some reason you don't like the idea of mapping your switches to keyboard input, you can look at something like the U401 from USBMicro. Again, no need to write a driver. They have sample code that shows you how to interface with the device. The U401 also has output capabilities, so you could use to drive another device if you wanted.
"When you die, if you get a choice between going to regular heaven or pie heaven, choose pie heaven. It might be a trick, but if it's not, mmmmmmm, boy."
How to Ask Questions the Smart Way.
For something as simple as a set of buttons, you don't need to write a full-fledged driver yourself. The windows USB-HID (Human Interface Driver) driver is capable of taking care of that for you. For communicating with a HID device, the only thing you actually need is actually the CreateFile function.

The tricky part (from the client side) is finding out what device address to pass to CreateFile, for which you would use SetupDiEnumDeviceInterfaces and friends from the Windows Driver Kit.

Once you've opened a file on the correct device address, the only thing you actually needs to do to exchange data with the USB device in question is the plain file I/O read and write functions for sending and receiving messages in the format that is defined by the USB device.

Lakeview research's HID page have more information regarding developing (for) USB HID devices. The generic_hid project in particular may be of interest.

Of course, the above explanation is only for the client side of the communication. You would then either have find a suitable existing device and find out what data format it uses by dumping the device descriptors and decoding them. While that isn't exactly rocket science, it does require some fundamental understanding of the USB protocol specification.

That is, if you don't build the device yourself, in which case you would require quite a bit more than just a fundamental understanding of USB devices.
-LuctusIn the beginning the Universe was created. This has made a lot of people very angry and been widely regarded as a bad move - Douglas Adams
If you fancy a more DIY approach than the minipac then you could use an AVR with V-USB to implement a HID.

[Website] [+++ Divide By Cucumber Error. Please Reinstall Universe And Reboot +++]

The absolute easiest way to do this would be to buy a cheap USB gamepad, tear it apart, and attach your buttons to the existing push-button contacts on the PCB. Then you could use the standard XInput interface to read input from it like any other gamepad.
Quote:Original post by Sneftel
The absolute easiest way to do this would be to buy a cheap USB gamepad, tear it apart, and attach your buttons to the existing push-button contacts on the PCB. Then you could use the standard XInput interface to read input from it like any other gamepad.


That won't work with XInput, XInput is for Xbox360 (and -alike) controllers only.
For normal gamepads, you could use DirectInput or winmm.
But yeah, that would be the easiest way I could think of. You can get a usb gamepad for less than 5 bucks nowadays.
thanks for the replies everyone

The problem is that i need multiple buttons, lets say i bought 3 gamepads and i teared it apart and made it look like a button, and i plugged all 3 gamepads to my pc, pressing it will send the info to directinput, but the application will not know which pad sent it (which is essential for my project)

so i thought i could try creating my own device which has 3 buttons (buttons are not close to each other, there should be a wire connecting each one to the device), an it sends each button's id and state to the computer through the usb port, the problem is that i dont know how to make the hardware nor the software, hardware might not be a big problem as i know some engineers, but creating a driver looks like a pain (realized this from reading the replies)

Luctus, could you give me some more information about this? how to pass the device address? in lpFileName? how can i get that from SetupDiEnumDeviceInterfaces?
And what will actually happen? the handle i will have is a handle to a file which contains information about the device? do the device have to have some specific configurations to write to that file?

Even though i really want to learn about how to use hardware with my apps, yet i only need the buttons thing (mentioned above), thus if you find an easy solution for it (i mean for being able to detect the sender of the button press message), i would be thankful if you could let me know about it.

regards
-Hassan
The generic_hid project I linked to earlier contains the entire process from enumerating all USB HID devices to opening them with CreateFile. Look in the CUsbhidiocDlg::FindTheHID() function in usbhidiocDlg.cpp file from the Usbhidio_vc6 Visual C++ project on that page.
-LuctusIn the beginning the Universe was created. This has made a lot of people very angry and been widely regarded as a bad move - Douglas Adams
Quote:Original post by Hassanbasil
The problem is that i need multiple buttons, lets say i bought 3 gamepads and i teared it apart and made it look like a button, and i plugged all 3 gamepads to my pc, pressing it will send the info to directinput, but the application will not know which pad sent it (which is essential for my project)
Why wouldn't it? It's not like games can't tell what input is coming from which gamepad. You just check each gamepad in turn. It does seem wasteful, though, why not have three buttons coming off the one gamepad?
@Luctus: Oh i didn't look deeply in it, that's great! thanks for the link! so, all i need is a vendor id and a product id? Well well, do you, by any chance, know a guide to create a device (hardware) and give it the ID's? or know a place (forum) to ask such question(s)?

thanks once again that was really helpful!


@Sneftel: i havn't really used directinput before as everyone says that it's bad compared to windows api input (through the windproc)(unless you want to get a joysttick's info), i thought it's just like GetAsyncKeyState api function, call some function/method to check if key x is pressed, anyway it seems to work in a different way

if i wont be able to create my own device, i will try to do this, it seems the simplest

"why not have three buttons coming off the one gamepad?"
well because each button should be in a different room or a different desk, connected (wire or wireless, depends on how it goes) to one PC

This topic is closed to new replies.

Advertisement