vrpn 07.35
Virtual Reality Peripheral Network
Loading...
Searching...
No Matches
vrpn_Button_NI_DIO24.C
Go to the documentation of this file.
1// vrpn_Button_NI_DIO24.C
2//
3// This is a driver for National Instruments DAQCard
4// DIO-24, a PCMCIA card, which provides 24-bit digital I/O.
5// The I/O is accessed in 3 "ports" with 8 bits per port,
6// though the user is protected from that detail. The
7// user of this class need only request inputs 1 through 24.
8//
9// Unlike the other National Instrument devices currently
10// in vrpn, this uses their new "mx" library. To access
11// that library, install their software from the NI-DAQmx
12// CD. Then uncomment the following line in vrpn_configure.h:
13// #define VRPN_USE_NATIONAL_INSTRUMENTS_MX
14//
15// Note that because the 3rd party library is used, this class
16// will only work under Windows.
17//
18// You must also include the following in your compilers include
19// path for the 'vrpn' and 'vrpn_server' projects:
20// $(SYSTEMDRIVE)\Program Files\National Instruments\NI-DAQ\DAQmx ANSI C DEV\include
21//
22// Finally, the following must be included in vrpn.cfg to use
23// the generic server:
24//
25// ################################################################################
26// # This is a driver for National Instruments DAQCard-
27// # DIO-24, a PCMCIA card, which provides 24-bit digital I/O.
28// #
29// # Arguments:
30// # char name_of_this_device[]
31// # int number_of_channls to read: 1-24 (optional. default=24)
32//
33// vrpn_Button_NI_DIO24 Button0 1
34//
35// This code was written in October 2006 by Bill West, based on some example
36// code provided by National Instruments.
37
39
41#ifdef VRPN_USE_NATIONAL_INSTRUMENTS_MX
42extern "C" {
43#include <NIDAQmx.h>
44}
45#else
46typedef vrpn_int32 int32;
47#endif
48#include <stdio.h> // for fprintf, sprintf, stderr, etc
49
50// Constants used by this class
52 (24<vrpn_BUTTON_MAX_BUTTONS) ? 24 : vrpn_BUTTON_MAX_BUTTONS ; // pick the least
53
56 vrpn_int32 numChannels) :
57vrpn_Button_Filter (name, c)
58{
59 char portName[127] ;
60
61 this->setNumChannels( numChannels );
62
63 // Check if we got a connection.
64 if (d_connection == NULL) {
65 fprintf(stderr,"vrpn_Button_NI_DIO24: Can't get connection!\n");
66 }
67
68 // Initialize the task handles
69#ifdef VRPN_USE_NATIONAL_INSTRUMENTS_MX
70 _taskHandle = 0 ;
71#else
72 fprintf(stderr,"vrpn_Button_NI_DIO24::vrpn_Button_NI_DIO24(): Not compiled into VRPN, edit vrpn_Configure.h and define VRPN_USE_NATIONAL_INSTRUMENTS_MX and then recompile VRPN.\n");
73#endif
74
75 // Initialize the DAQCard-DIO-24 for each of the ports used
76 // Define various names the library needs
77 sprintf(portName,"Dev1/line0:%d", num_buttons-1) ;
78
79 /*********************************************/
80 // DAQmx Configure Code
81 /*********************************************/
82#ifdef VRPN_USE_NATIONAL_INSTRUMENTS_MX
83 int32 error=0;
84 error = DAQmxCreateTask(d_servicename,&_taskHandle);
85
86 if (!error)
87 error = DAQmxCreateDIChan(_taskHandle,portName,"",DAQmx_Val_ChanForAllLines);
88#endif
89
90/* The following code *should* make the 0's into 1's, and vice versa, but it only works
91 * for one channel, and even then, it causes the 1's (button pressed) to "flicker" 1-0-1.
92 * National Instruments can't explain it. Furthermore, if you try to set this property
93 * for all inputs, it errors out.
94 *
95 * if (!error)
96 * error = DAQmxSetDIInvertLines(_taskHandle, portName, true) ;
97 */
98
99 /*********************************************/
100 // DAQmx Start Code
101 /*********************************************/
102#ifdef VRPN_USE_NATIONAL_INSTRUMENTS_MX
103 if (!error)
104 error = DAQmxStartTask(_taskHandle);
105
106 // If error, report it and exit
107 if (error)
108 reportError(error, vrpn_true) ;
109#endif
110
111} // constructor
112
113// This destructor closes out the SEI bus, and deallocates memory
115{
116#ifdef VRPN_USE_NATIONAL_INSTRUMENTS_MX
117 if( _taskHandle!=0 )
118 {
119 /*********************************************/
120 // DAQmx Stop Code
121 /*********************************************/
122 DAQmxStopTask(_taskHandle);
123 DAQmxClearTask(_taskHandle);
124 _taskHandle = 0 ;
125 }
126#endif
127} // destructor
128
137{
138
139 server_mainloop(); // let the server do its stuff
140
141 // Read the data from the available ports
142 /*********************************************/
143 // DAQmx Read Code
144 /*********************************************/
145#ifdef VRPN_USE_NATIONAL_INSTRUMENTS_MX
146 int32 error ;
147 int32 bytesRead,bytesPerSamp;
148 error = DAQmxReadDigitalLines(_taskHandle,1,5.0,DAQmx_Val_GroupByChannel,
150 &bytesPerSamp,&bytesRead,NULL);
151
152 // check for obvious errors
153 if (bytesRead < num_buttons)
154 fprintf(stderr,
155 "vrpn_Button_NI_DIO24: Warning, number of bytes read was %d, not %d as expected.\n",
156 bytesRead, num_buttons) ;
157 // If other error, report it and sleep
158 if (error)
159 reportError(error, vrpn_false) ;
160#endif
161
162 // Finally, the point of all this, deliver the data
164
165} // mainloop
166
167vrpn_int32 vrpn_Button_NI_DIO24::setNumChannels (vrpn_int32 sizeRequested)
168{
169 // Set the number of buttons we have to read
170 // If the number is invalid, default to the maximum
171 if (sizeRequested<1 || sizeRequested > vrpn_Button_NI_DIO24::vrpn_Button_NI_DIO24_CHANNEL_MAX)
173 else
174 num_buttons = sizeRequested;
175
176 this->set_all_momentary() ; // as the default case anyway
177
178 return num_buttons;
179
180} // setNumChannels
181
182// This handles error reporting
183#ifdef VRPN_USE_NATIONAL_INSTRUMENTS_MX
184void vrpn_Button_NI_DIO24::reportError(int32 errnumber, vrpn_bool exitProgram)
185{
186 char errBuff[2048]={'\0'};
187
188 if( DAQmxFailed(errnumber) )
189 {
190 DAQmxGetExtendedErrorInfo(errBuff,2048);
191 printf("DAQmx Error: %s\n",errBuff);
192 if (exitProgram==vrpn_true)
193 {
194 printf("Exiting...\n") ;
195 throw(errnumber) ; // this will quit, cause the destructor to be called
196 }
197 else
198 {
199 printf("Sleeping...\n") ;
200 vrpn_SleepMsecs(1000.0*1) ; // so at least the log will slow down so someone can see the error
201 }
202 }
203} // reportError
204#endif
205
vrpn_Connection * d_connection
Connection that this object talks to.
void server_mainloop(void)
Handles functions that all servers should provide in their mainloop() (ping/pong, for example) Should...
char * d_servicename
Name of this device, not including the connection part.
All button servers should derive from this class, which provides the ability to turn any of the butto...
Definition vrpn_Button.h:66
virtual void report_changes(void)
virtual void set_all_momentary(void)
vrpn_Button_NI_DIO24(const char *name, vrpn_Connection *c, vrpn_int32 numChannels=vrpn_Button_NI_DIO24_CHANNEL_MAX)
virtual void mainloop()
This routine is called each time through the server's main loop.
static const vrpn_int32 vrpn_Button_NI_DIO24_CHANNEL_MAX
vrpn_int32 num_buttons
Definition vrpn_Button.h:48
unsigned char buttons[vrpn_BUTTON_MAX_BUTTONS]
Definition vrpn_Button.h:45
Generic connection class not specific to the transport mechanism.
const int vrpn_BUTTON_MAX_BUTTONS
Definition vrpn_Button.h:13
#define VRPN_API
void vrpn_SleepMsecs(double dMilliSecs)