i
i
i
i
i
i
i
i
17.5. Interfacing Custom VR Hardware with the Applications 497
your own device driver for Windows or Linux. Of course, it is possible to
do both—see [8] and [13]—but for all but the highest-speed interfaces, the
universal serial bus (USB) will do the job. With a bit of clever programming,
one can fool Windows into believing that it already has all the drivers it n eeds
and is dealing with a joystick. Interfacing to a PC via USB could be the
subject of several books in itself, so here we will only give an outline view of
the hardware and explain how an application program written in C/C++ can
read and write directly to a USB device.
17.5.1 A Brief Look at USB
The USB interface uses a serial protocol, and the h ardware connections con-
sist of four wires: +5V power and ground and two data lines called D+
and D. The interface, depending on how it is configured, can be low,
full or high speed. Low-speed transfers operate at 1.5 Mbits/s, full-speed at
12 Mbits/s and high-speed 480 Mbits/s. However, in addition to data, the
bus has to carry control, status and error-checking signals, thus making the
actual data rates lower than these values. Therefore, the maximum data rates
are only 800 bytes per second for low speed, 1.2 megabits per second for full
speed and 53 megabits per second for high speed. The USB Implementers Fo-
rum
3
provides a comprehensive set of documentation on USB and has many
links to other useful resources.
There are four types of data transfers possible, each suited to different
applications, which may or may not be available to low-speed devices. These
transfers are control, bulk, interrupt and isochronous. Devices such as key-
boards, mice and joysticks are low-speed devices, and use interrupt data trans-
fer. The maximum possible transfer of data for this combination is 8 bytes
per 10 milliseconds.
When a peripheral device is connected to a PC via USB, a process called
enumeration takes place. During enumeration, the devices interface must
send several pieces of information called descriptors to the PC. The descriptors
are sets of data that completely describe the USB device’s capabilities and
how the device will be used. A class of USB devices falls into a category
called human interface devices (HIDs), not surprisingly because these devices
interact directly with people. Examples of HIDs are keyboards, mice and
joysticks. Using the HID protocol, an application program can detect when
someone moves a joystick, or the PC might send a force-feedback effect that
the user can feel.
3
http://www.usb.org/.
i
i
i
i
i
i
i
i
498 17. Programming Input and Force Feedback
With many custom-made USB devices, the user has to create a driver for
Windows. However, Windows has supported the HID class of USB devices
since Windows 98. Therefore, when a USB HID is plugged into a PC run-
ning Windows, it will build a custom driver for the device. As a result, if we
can construct a simple device that fools Windows into believing it is dealing
with an HID, there will be no need to write custom device drivers and we can
use DirectInput or write our own high-level language interface in only a few
lines of code.
17.5.2 USB Interfacing
For anyone working on R&D in VR applications, it can be frustrating to find
that what you want to do is just not possible with any commercially available
equipment. This may be because it is just not viable for a manufacturer to go
to the expense of bringing a product to market for a specialized application.
Or it may be that until you convince the manufacturer that your idea works,
they will not be interested. In these circumstances, one has only two alter-
natives, compromise on the hardware, for example use a force joystick where
what you really want is a six-degrees-of-freedom haptic system with a work-
ing volume of four cubic meters, or build your own hardware. If one does
decide to DIY it then the question is how to interface the device to the virtual
world in the computer. In the early days of PC systems, developers turned to
the serial and parallel I/O ports because they were easy to access and control
from a high-level language program such as C. Nowadays, PC hardware has
become much more complicated and the interfaces much more difficult to
get at from an application program. Or have they?
The USB and HID interfaces offer a real alternative, since a number of
programmable interrupt controllers (PICs) now offer a USB interface and
have built in analog-to-digital (A/D) converters. This has put the software
engineer back in control, because devices such as the Microchip 167865 PIC
require only a few components and some embedded software to turn 6/8
analog voltages into a data stream which even a program executing without
any special system privileges can access at a rate that is high enough to control
the servo mechanism of a 3D haptic device. Figure 17.4 illustrates just such
an interface built by Mack [5].
Books by Axelson [1] and Hyde [3] provide good starting points with
guidelines for building interface devices for a PC using USB.
Once one has a way to measure and set several voltage levels in an external
device under the control of an application program and at a high enough
i
i
i
i
i
i
i
i
17.5. Interfacing Custom VR Hardware with the Applications 499
Figure 17.4. A USB to analog voltage interface using a PIC. On the left is the circuit
diagram of the device which converts the analog voltage on five potentiometers and
one thumb wheel switch into a USB compatible data frame of nine bytes delivered to
the PC at a rate of 1K bytes/s. No external power supply is necessary and the voltage
scale of [ 0 , 5V ] is conver ted to an unsigned byte value ([0, 255]).
speed, the places to which you can take your virtual world are only restricted
by your imagination and the ability to constr uct your human interface device
design. Apart from soldering a few electronic components, perhaps the hardest
thing to do is write, develop and test the firmware that has to be written for
the PIC. A good development system is essential. For example, the Proton+
Compiler [11] and some practical guidance may also be found in the PIC
microcontroller project book [4].
At the core of the microcontroller code must lie routines that allow its
USB interface to be enumerated correctly by Windows when it connects to
the PC. This is done in a series of stages by passing back data structures
called descriptors. Mack [5] gives a full program listing for PIC microcode
that enumerates itself as a joystick to Windows. During enumeration, the
PC requests descriptors concerning increasingly small elements of the USB
device. The descriptors that have to be provided for a HID device so that it
appears to Windows as a joystick are:
The device descriptor has 14 fields occupying 18 bytes. The fields tell
the PC which type of USB interface it provides, e.g., version 1.00.
If a USB product is to be marketed commercially, a vendor ID (VID)
must be allocated by the USB Implementers Forum. For hardware
that will never be released commercially, a dummy value can be used.
For example, if we assign
0x03E8 as the VID then an application
program may look for it in order to detect our device (see List-
ing 17.7).
i
i
i
i
i
i
i
i
500 17. Programming Input and Force Feedback
#include "setupapi.h" // header file from Windows DDK
#include "hidsdi.h" // header file from Windows DDK
// HIDs appear as normal Windows files
HANDLE h1=INVALID_HANDLE_VALUE,
// when open - use this handle to read/write.
h2=INVALID_HANDLE_VALUE;
// are the reading threads running ?
BOOL bLoop=FALSE;
// initialize TWO Human Interfaces Devices
BOOL InitHIDs(void){
if((h1=FindUSBHID(0x04D8,0x0064,0x0001)) == INVALID_HANDLE_VALUE)return FALSE;
if((h2=FindUSBHID(0x04D8,0x00C8,0x0001)) == INVALID_HANDLE_VALUE)return FALSE;
_beginthread(UpdateHID1,0,(PVOID)NULL); // start a thread to handle each device
_beginthread(UpdateHID2,0,(PVOID)NULL);
return TRUE;
}
BOOL FreeHIDs(void){ // release the devices
bLoop=FALSE; Sleep(100); // give the reading thread time to exit
if(h1 != INVALID_HANDLE_VALUE)CloseHandle(h1);
if(h2 != INVALID_HANDLE_VALUE)CloseHandle(h2);
return TRUE;
}
HANDLE FindUSBHID( // Find the USB device
DWORD vendorID, // We identify our HID joystick emulating devices by
DWORD productID, // looking for a unique vendor and product ID and version
// number.
DWORD versionNumber){// These are set in the USB PIC’s EEPROM.
HANDLE deviceHandle = INVALID_HANDLE_VALUE;
// HIDs are identified by an interger in range 0 - N=number installed
DWORD index = 0;
HIDD_ATTRIBUTES deviceAttributes;
// Go through all possible HID devices until the one we want is found
// the code for function FindHID() is in the project code on the CD
while((deviceHandle = FindHID(index++)) != INVALID_HANDLE_VALUE){
// fill the attributes structure for this HID
if (!HidD_GetAttributes(deviceHandle, &deviceAttributes))return
INVALID_HANDLE_VALUE;
if ((vendorID == 0 || deviceAttributes.VendorID == vendorID) &&
(productID == 0 || deviceAttributes.ProductID == productID) &&
(versionNumber == 0 || deviceAttributes.VersionNumber == versionNumber))
return deviceHandle; // we have the one we want - return handle
CloseHandle (deviceHandle);
}
return INVALID_HANDLE_VALUE;
}
Listing 17.7. Functions to initialize the USB device, acquire file handles to be used
for reading data from the device, and start the thread functions that carry out the
reading operation.
i
i
i
i
i
i
i
i
17.5. Interfacing Custom VR Hardware with the Applications 501
The configuration descriptor has 8 fields occupying 9 bytes. This pro-
vides information on such things as whether the device is bus-powered.
If the PC determines that the requested current is not available, it will
not allow the device to be configured.
The interface descriptor has 9 fields occupying 9 bytes. It tells the host
that this device is an HID and to expect additional descriptors to pro-
vide details of the HID and how it presents its reports. (For example,
in the case of a joystick, the report describes how the nine-byte data
frame is formatted to represent the x-, y-, z-coordinates, button presses
etc.)
Field Value Description Attribute
Usage page 0x05 Generic Desktop 0x01
Usage 0x09 Joystick 0x04
Collection 0xA1 Application 0x01
Usage page 0x05 Simulation controls 0x02
Usage 0x09 Throttle 0xBB
Logical Minimum 0x15 0 0x00
Logical Maximum 0x26 255 0x00FF
Physical Minimum 0x35 0 0x00
Physical Maximum 0x46 255 0x00FF
Report size 0x75 Number of bits = 8 0x08
Report count 0x95 Number of above usages = 1 0x01
Input 0x81 Data, variable, absolute 0x02
Usage page 0x05 Generic Desktop 0x01
Usage 0x09 Pointer 0x01
Collection 0xA1 Physical 0x00
Usage 0x09 x-axis 0x30
Usage 0x09 y-axis 0x31
Usage 0x09 z-axis 0x32
Usage 0x09 Slider 0x36
Usage 0x09 RZ 0x35
Report count 0x95 Number of above usages = 5 0x05
Input 0x81 Data, variable, absolute 0x02
End collection 0xC0
End collection 0xC0
Table 17.1. The report descriptor of a USB HID that is interpreted as emanating
from a three-axis joystick. The value parameter tells the enumerating host what is
being defined and the Attribute parameter tells the host what it is being defined as.
For example, a descriptor field value of
0x09 tells the host that a joystick axis is being
defined and an attribute of
0x30 says it is an x-axis.
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.118.12.157