vrpn  07.33
Virtual Reality Peripheral Network
vrpn_OmegaTemperature.C
Go to the documentation of this file.
1 // vrpn_OmegaTemperature.C
2 // This is a driver for the OmegaTemperature temperature controller.
3 // It was written in April 2014 by Russ Taylor.
4 
5 // INFO about how the device communicates, taken from the user manual:
6 // This information comes from the Bulletin E-90-OCN publication, which is
7 // the manual for the Omega Series CN7200, CN7600, CN7800, CN7500 microprocessor
8 // based temperature process control. It was developed for a CN7800.
9 // It communicates over RS-485 using the MODBUS ASCII/RTU communications
10 // protocol. The driver is written for the ASCII protocol.
11 // A Windows application to test communication with the device can be found
12 // at http://www.omega.com/Software/CN7-a_r.html
13 
14 // A Modbus ASCII frame is as follows (Wikipedia) (big-endian):
15 // Colon ':' character.
16 // 2-character station address
17 // 2-character function code
18 // (0x03 read register, 0x02 read data bits, 0x06 write register, 0x05 write bit)
19 // n-character data + length
20 // 2-character checksum
21 // 2-character CR/LF (0x0d 0x0a)
22 
23 // Modbus application protocol specification:
24 // http://www.modbus.com/docs/Modbus_Application_Protocol_V1_1b.pdf
25 // Modbus over serial line document:
26 // http://modbus.org/docs/Modbus_over_serial_line_V1_02.pdf
27 
28 // libmodbus: libmodbus.org has a Modbus library for various operating
29 // systems. It has ominous statements in the release notes about Windows
30 // support being broken even in the latest version (3.1.1 on 2013-10-06).
31 // The latest stable version is 3.0.5; it does not say that it has broken
32 // support on Windows. It seems to support the serial RTU protocol.
33 // However, the configure script reports that VC++ support has not been
34 // tested in a long time; it can be configured and built under Cygwin.
35 
36 /* XXX The code has not been changed from the Biosciences code yet,
37  only the names have been changed. */
38 
39 /*
40 Using a standard DB-9 cable (female-female connectors on both ends with
41 straight-through connections from each pin)
42 connect the controller (middle DB-9 connector) to a serial port of your computer.
43 Set the serial port at 115,200 speed, 8 bits, 1 stop bit,
44 NONE parity, and Hardware flow control.
45 The following is the list of text commands supported.
46 NOTE: Each command should follow by \r <CR> code:
47 (The following notes LIE: There is no space before the . or before the C,
48  and sometimes the C is an E. Also, the order is incorrect. The actual
49  order is stage 1, bath 1, external 1, stage 2, bath 2, external 2.)
50 T1<CR> returns temperature readings from STAGE1 sensor: 37 .1 C
51 T2<CR> returns temperature readings from BATH1 sensor: 36 .9 C
52 T5<CR> returns SET temperature: 37 .0 C
53 T3<CR> returns temperature readings from STAGE2 sensor: 37 .1 C
54 T4<CR> returns temperature readings from BATH2 sensor: 36 .9 C
55 T6<CR> returns SET temperature: 37 .0 C
56 CTn<CR> returns readings from n (n=1 - STAGE1, 2 - BATH1, 3 - STAGE2, 4 - BATH2) sensor: 37 .1 C
57 ON<CR> turns temperature control ON
58 OFF<CR> turns temperature control OFF
59 S1 037 0<CR> sets reference temperature for channel I (NOTE: all four digits should be sent to the controller)
60 S2 037 0<CR> sets reference temperature for channel II
61 */
62 
63 #include <stddef.h> // for size_t
64 #include <stdio.h> // for sprintf, fprintf, stderr, etc
65 #include <string.h> // for strlen, NULL
66 
67 #include "vrpn_BaseClass.h" // for ::vrpn_TEXT_ERROR, etc
68 #include "vrpn_OmegaTemperature.h"
69 #include "vrpn_Serial.h" // for vrpn_write_characters, etc
70 #include "vrpn_Shared.h" // for vrpn_unbuffer, timeval, etc
71 #include "vrpn_MessageMacros.h" // for VRPN_MSG_INFO, VRPN_MSG_WARNING, VRPN_MSG_ERROR
72 
74 
75 #if defined(VRPN_USE_MODBUS) && defined(VRPN_USE_WINSOCK2)
76 
77 #undef VERBOSE
78 
79 // Defines the modes in which the device can find itself.
80 #define STATUS_RESETTING (-1) // Resetting the device
81 #define STATUS_SYNCING (0) // Looking for the first character of report
82 #define STATUS_READING (1) // Looking for the rest of the report
83 
84 #define TIMEOUT_TIME_INTERVAL (2000000L) // max time between reports (usec)
85 
86 
87 // This creates a vrpn_OmegaTemperature. It opens
88 // the serial device using the code in the vrpn_Serial_Analog constructor.
89 // It uses hardware flow control.
90 
91 vrpn_OmegaTemperature::vrpn_OmegaTemperature (const char * name, vrpn_Connection * c,
92  const char * port, float temp1, float temp2, bool control_on):
93  vrpn_Serial_Analog(name, c, port, 115200, 8, vrpn_SER_PARITY_NONE, true),
94  vrpn_Analog_Output(name, c),
95  vrpn_Button_Filter(name, c)
96 {
97  // XXX Make this configurable?
98  int baud = 38400;
99  char parity = 'n'; // XXX What should this be?
100  int stop_bits = 1;
101  d_modbus = modbus_new_rtu(port, baud, parity, 8, stop_bits);
102  // XXX No code below has been changed yet.
103 
104  num_channel = 6;
105  o_num_channel = 3;
106  num_buttons = 1;
107  buttons[0] = control_on;
108 
109  // Fill in the arguments to send to the device at reset time.
110  o_channel[0] = temp1;
111  o_channel[1] = temp2;
112  o_channel[2] = control_on;
113 
114  // Set the mode to reset
116 
117  // Register to receive the message to request changes and to receive connection
118  // messages.
119  if (d_connection != NULL) {
121  this, d_sender_id)) {
122  fprintf(stderr,"vrpn_OmegaTemperature: can't register handler\n");
123  d_connection = NULL;
124  }
126  this, d_sender_id)) {
127  fprintf(stderr,"vrpn_OmegaTemperature: can't register handler\n");
128  d_connection = NULL;
129  }
131  this, d_sender_id)) {
132  fprintf(stderr,"vrpn_OmegaTemperature: can't register handler\n");
133  d_connection = NULL;
134  }
135  } else {
136  fprintf(stderr,"vrpn_OmegaTemperature: Can't get connection!\n");
137  }
138 
139 }
140 
141 // Command format described in document:
142 // S1 037 0<CR> sets reference temperature for channel 1
143 // (NOTE: all four digits should be sent to the controller)
144 // Actual command format:
145 // S1 0370<CR> Sets reference temperature for channel 1 to 37.0 deg C
146 // S2 0421<CR> Sets reference temperature for channel 2 to 42.1 deg C
147 
148 bool vrpn_OmegaTemperature::set_reference_temperature(unsigned channel, float value)
149 {
150  char command[128];
151 
152  // Fill in the command with the zero-padded integer output for
153  // above the decimal and then a single value for the first point
154  // past the decimal.
155  int whole = static_cast<int>(value);
156  int dec = static_cast<int>(value*10) - whole*10;
157  sprintf(command, "S%d %03d%d\r", channel+1, whole,dec);
158 
159  // Send the command to the serial port
160  return (vrpn_write_characters(serial_fd, (unsigned char *)(command), strlen(command)) == strlen(command));
161 }
162 
163 // Command format:
164 // ON<CR> sets control on
165 // OFF<CR> sets control off
166 
167 bool vrpn_OmegaTemperature::set_control_status(bool on)
168 {
169  char command[128];
170 
171  if (on) {
172  sprintf(command, "ON\r");
173  } else {
174  sprintf(command, "OFF\r");
175  }
176 
177  // Send the command to the serial port
178  return (vrpn_write_characters(serial_fd, (unsigned char *)(command), strlen(command)) == strlen(command));
179 }
180 
181 // Command format:
182 // T1<CR> returns temperature readings from STAGE1 sensor: 37.1C
183 // T2<CR> returns temperature readings from BATH1 sensor: 36.9C
184 // T5<CR> returns SET temperature: 37.0C
185 // T3<CR> returns temperature readings from STAGE2 sensor: 37.1C
186 // T4<CR> returns temperature readings from BATH2 sensor: 36.9C
187 // T6<CR> returns SET temperature: 37.0C
188 // NOTE: Sometimes the C is an E when there is no reading.
189 
190 bool vrpn_OmegaTemperature::request_temperature(unsigned channel)
191 {
192  char command[128];
193 
194  sprintf(command, "T%d\r", channel+1);
195 #ifdef VERBOSE
196  printf("Sending command: %s", command);
197 #endif
198 
199  // Send the command to the serial port
200  return (vrpn_write_characters(serial_fd, (unsigned char *)(command), strlen(command)) == strlen(command));
201 }
202 
203 // Convert the four bytes that have been read into a signed integer value.
204 // The format (no quotes) looks like: "- 37.1C\r" or " 000.00E\r".
205 // I don't think that the - means a minus sign, and it has a space
206 // between it and the number.
207 // Returns -1000 if there is an error.
208 float vrpn_OmegaTemperature::convert_bytes_to_reading(const char *buf)
209 {
210  float val;
211  char c;
212 
213  // Skip any leading minus sign.
214  if (*buf == '-') { buf++; }
215 
216  // Read a fractional number.
217  if (sscanf(buf, "%f%c", &val, &c) != 2) {
218  return -1000;
219  }
220 
221  // See if we get and E or C after the number,
222  // or (since E can be part of a floating-point
223  // number) if we get \r.
224  if ( (c != 'E') && (c != 'C') && (c != '\r') ) {
225  return -1000;
226  }
227 
228  return val;
229 }
230 
231 
232 int vrpn_OmegaTemperature::reset(void)
233 {
234  //-----------------------------------------------------------------------
235  // Sleep less thana second and then drain the input buffer to make sure we start
236  // with a fresh slate.
237  vrpn_SleepMsecs(200);
238  vrpn_flush_input_buffer(serial_fd);
239 
240  //-----------------------------------------------------------------------
241  // Set the temperatures for channel 1 and 2 and then set the temperature
242  // control to be on or off depending on what we've been asked to do.
243  if (!set_reference_temperature(0, static_cast<float>(o_channel[0]))) {
244  fprintf(stderr,"vrpn_OmegaTemperature::reset(): Cannot send set ref temp 0, trying again\n");
245  return -1;
246  }
247  if (!set_reference_temperature(1, static_cast<float>(o_channel[1]))) {
248  fprintf(stderr,"vrpn_OmegaTemperature::reset(): Cannot send set ref temp 1, trying again\n");
249  return -1;
250  }
251  if (!set_control_status(o_channel[0] != 0)) {
252  fprintf(stderr,"vrpn_OmegaTemperature::reset(): Cannot send set control status, trying again\n");
253  return -1;
254  }
255 
256  //-----------------------------------------------------------------------
257  // Send the command to request input from the first channel, and set up
258  // the finite-state machine so we know which thing to request next.
259  d_next_channel_to_read = 0;
260  if (!request_temperature(d_next_channel_to_read)) {
261  fprintf(stderr,"vrpn_OmegaTemperature::reset(): Cannot request temperature, trying again\n");
262  return -1;
263  }
264 
265  // We're now waiting for any responses from devices
266  status = STATUS_SYNCING;
267  VRPN_MSG_WARNING("reset complete (this is normal)");
268  vrpn_gettimeofday(&timestamp, NULL); // Set watchdog now
269  return 0;
270 }
271 
272 // This function will read characters until it has a full report, then
273 // put that report into analog fields and call the report methods on these.
274 // The time stored is that of the first character received as part of the
275 // report.
276 
277 int vrpn_OmegaTemperature::get_report(void)
278 {
279  int ret; // Return value from function call to be checked
280 
281  //--------------------------------------------------------------------
282  // If we're SYNCing, then the next character we get should be the start
283  // of a report. If we recognize it, go into READing mode and tell how
284  // many characters we expect total. If we don't recognize it, then we
285  // must have misinterpreted a command or something; reset
286  // and start over
287  //--------------------------------------------------------------------
288 
289  if (status == STATUS_SYNCING) {
290  // Try to get a character. If none, just return.
291  if (vrpn_read_available_characters(serial_fd, (unsigned char *)(d_buffer), 1) != 1) {
292  return 0;
293  }
294 
295  // Got the first character of a report -- go into READING mode
296  // and record that we got one character at this time. Clear the
297  // rest of the buffer to 0's so that we won't be looking at old
298  // data when we parse.
299  // The time stored here is as close as possible to when the
300  // report was generated.
301  d_bufcount = 1;
302  vrpn_gettimeofday(&timestamp, NULL);
303  status = STATUS_READING;
304  size_t i;
305  for (i = 1; i < sizeof(d_buffer); i++) {
306  d_buffer[i] = 0;
307  }
308 #ifdef VERBOSE
309  printf("... Got the 1st char\n");
310 #endif
311  }
312 
313  //--------------------------------------------------------------------
314  // Read as many bytes of this report as we can, storing them
315  // in the buffer.
316  //--------------------------------------------------------------------
317 
318  while ( 1 == (ret = vrpn_read_available_characters(serial_fd, (unsigned char *)(&d_buffer[d_bufcount]), 1))) {
319  d_bufcount++;
320  }
321  if (ret == -1) {
322  VRPN_MSG_ERROR("Error reading");
323  status = STATUS_RESETTING;
324  return 0;
325  }
326 #ifdef VERBOSE
327  if (ret != 0) printf("... got %d total characters\n", d_bufcount);
328 #endif
329  if (d_buffer[d_bufcount-1] != '\r') { // Not done -- go back for more
330  return 0;
331  }
332 
333  //--------------------------------------------------------------------
334  // We now have enough characters to make a full report. Check to make
335  // sure that its format matches what we expect. If it does, the next
336  // section will parse it.
337  // Store the report into the appropriate analog channel.
338  //--------------------------------------------------------------------
339 
340 #ifdef VERBOSE
341  printf(" Complete report: \n%s\n",d_buffer);
342 #endif
343  float value = convert_bytes_to_reading(d_buffer);
344  if (value == -1000) {
345  char msg[256];
346  sprintf(msg,"Invalid report, channel %d, resetting", d_next_channel_to_read);
347  VRPN_MSG_ERROR(msg);
348  status = STATUS_RESETTING;
349  }
350  channel[d_next_channel_to_read] = value;
351 
352 #ifdef VERBOSE
353  printf("got a complete report (%d chars)!\n", d_bufcount);
354 #endif
355 
356  //--------------------------------------------------------------------
357  // Request a reading from the next channe.
358  //--------------------------------------------------------------------
359 
360  d_next_channel_to_read = (d_next_channel_to_read + 1) % 6;
361  if (!request_temperature(d_next_channel_to_read)) {
362  char msg[256];
363  sprintf(msg,"Can't request reading, channel %d, resetting", d_next_channel_to_read);
364  VRPN_MSG_ERROR(msg);
365  status = STATUS_RESETTING;
366  }
367 
368  //--------------------------------------------------------------------
369  // Done with the decoding, send the reports and go back to syncing
370  //--------------------------------------------------------------------
371 
372  report_changes();
373  status = STATUS_SYNCING;
374  d_bufcount = 0;
375 
376  return 1;
377 }
378 
379 bool vrpn_OmegaTemperature::set_specified_channel(unsigned channel, vrpn_float64 value)
380 {
381  // XXX Check return status of the set commands?
382  switch (channel) {
383  case 0: // Reference temperature for channels 1 and 2
384  case 1: // Reference temperature for channels 1 and 2
385  set_reference_temperature(channel, static_cast<float>(value));
386  o_channel[channel] = value;
387  break;
388  case 2: // Turn on temperature control if this is nonzero.
389  o_channel[2] = value;
390  buttons[0] = ( value != 0 );
391  set_control_status( value != 0);
392  break;
393  default:
394  return false;
395  }
396  return true;
397 }
398 
399 int vrpn_OmegaTemperature::handle_request_message(void *userdata, vrpn_HANDLERPARAM p)
400 {
401  const char *bufptr = p.buffer;
402  vrpn_int32 chan_num;
403  vrpn_int32 pad;
404  vrpn_float64 value;
405  vrpn_OmegaTemperature *me = (vrpn_OmegaTemperature *)userdata;
406 
407  // Read the parameters from the buffer
408  vrpn_unbuffer(&bufptr, &chan_num);
409  vrpn_unbuffer(&bufptr, &pad);
410  vrpn_unbuffer(&bufptr, &value);
411 
412  // Set the appropriate value, if the channel number is in the
413  // range of the ones we have.
414  if ( (chan_num < 0) || (chan_num >= me->o_num_channel) ) {
415  char msg[1024];
416  sprintf(msg,"vrpn_OmegaTemperature::handle_request_message(): Index out of bounds (%d of %d), value %lg\n",
417  chan_num, me->num_channel, value);
418  me->send_text_message(msg, me->timestamp, vrpn_TEXT_ERROR);
419  return 0;
420  }
421 
422  me->set_specified_channel(chan_num, value);
423  return 0;
424 }
425 
426 int vrpn_OmegaTemperature::handle_request_channels_message(void* userdata, vrpn_HANDLERPARAM p)
427 {
428  int i;
429  const char* bufptr = p.buffer;
430  vrpn_int32 num;
431  vrpn_int32 pad;
432  vrpn_OmegaTemperature* me = (vrpn_OmegaTemperature *)userdata;
433 
434  // Read the values from the buffer
435  vrpn_unbuffer(&bufptr, &num);
436  vrpn_unbuffer(&bufptr, &pad);
437  if (num > me->o_num_channel) {
438  char msg[1024];
439  sprintf(msg,"vrpn_OmegaTemperature::handle_request_channels_message(): Index out of bounds (%d of %d), clipping\n",
440  num, me->o_num_channel);
441  me->send_text_message(msg, me->timestamp, vrpn_TEXT_ERROR);
442  num = me->o_num_channel;
443  }
444  for (i = 0; i < num; i++) {
445  vrpn_unbuffer(&bufptr, &(me->o_channel[i]));
446  me->set_specified_channel(i, me->o_channel[i]);
447  }
448 
449  return 0;
450 }
451 
454 int vrpn_OmegaTemperature::handle_connect_message(void *userdata, vrpn_HANDLERPARAM)
455 {
456  vrpn_OmegaTemperature *me = (vrpn_OmegaTemperature *)userdata;
457 
458  me->report(vrpn_CONNECTION_RELIABLE);
459  return 0;
460 }
461 
462 void vrpn_OmegaTemperature::report_changes(vrpn_uint32 class_of_service)
463 {
464  vrpn_Analog::timestamp = timestamp;
465  vrpn_Analog::report_changes(class_of_service);
467 }
468 
469 void vrpn_OmegaTemperature::report(vrpn_uint32 class_of_service)
470 {
471  vrpn_Analog::timestamp = timestamp;
472  vrpn_Analog::report(class_of_service);
474 }
475 
483 void vrpn_OmegaTemperature::mainloop()
484 {
485  char errmsg[256];
486 
487  server_mainloop();
488 
489  switch(status) {
490  case STATUS_RESETTING:
491  reset();
492  break;
493 
494  case STATUS_SYNCING:
495  case STATUS_READING:
496  {
497  // It turns out to be important to get the report before checking
498  // to see if it has been too long since the last report. This is
499  // because there is the possibility that some other device running
500  // in the same server may have taken a long time on its last pass
501  // through mainloop(). Trackers that are resetting do this. When
502  // this happens, you can get an infinite loop -- where one tracker
503  // resets and causes the other to timeout, and then it returns the
504  // favor. By checking for the report here, we reset the timestamp
505  // if there is a report ready (ie, if THIS device is still operating).
506  while (get_report()) {}; // Keep getting reports so long as there are more
507 
508  struct timeval current_time;
509  vrpn_gettimeofday(&current_time, NULL);
510  if ( vrpn_TimevalDuration(current_time,timestamp) > TIMEOUT_TIME_INTERVAL) {
511  sprintf(errmsg,"Timeout... current_time=%ld:%ld, timestamp=%ld:%ld",
512  current_time.tv_sec, static_cast<long>(current_time.tv_usec),
513  timestamp.tv_sec, static_cast<long>(timestamp.tv_usec));
514  VRPN_MSG_ERROR(errmsg);
515  status = STATUS_RESETTING;
516  }
517  }
518  break;
519 
520  default:
521  VRPN_MSG_ERROR("Unknown mode (internal error)");
522  break;
523  }
524 }
525 
526 #endif
vrpn_BaseClassUnique::register_autodeleted_handler
int register_autodeleted_handler(vrpn_int32 type, vrpn_MESSAGEHANDLER handler, void *userdata, vrpn_int32 sender=vrpn_ANY_SENDER)
Registers a handler with the connection, and remembers to delete at destruction.
Definition: vrpn_BaseClass.C:503
vrpn_Serial_Analog
Definition: vrpn_Analog.h:63
vrpn_Button::report_changes
virtual void report_changes(void)
Definition: vrpn_Button.C:422
vrpn_Analog::status
int status
Definition: vrpn_Analog.h:43
vrpn_BaseClass.h
vrpn_TimevalDuration
unsigned long vrpn_TimevalDuration(struct timeval endT, struct timeval startT)
Return number of microseconds between startT and endT.
Definition: vrpn_Shared.C:129
vrpn_BaseClassUnique::d_ping_message_id
vrpn_int32 d_ping_message_id
Ask the server if they are there.
Definition: vrpn_BaseClass.h:230
vrpn_SER_PARITY_NONE
Definition: vrpn_Serial.h:16
vrpn_Analog::report
virtual void report(vrpn_uint32 class_of_service=vrpn_CONNECTION_LOW_LATENCY, const struct timeval time=vrpn_ANALOG_NOW)
Send a report whether something has changed or not (for servers) Optionally, tell what time to stamp ...
Definition: vrpn_Analog.C:94
STATUS_SYNCING
#define STATUS_SYNCING
Definition: vrpn_3DMicroscribe.C:27
vrpn_Analog_Output::o_num_channel
vrpn_int32 o_num_channel
Definition: vrpn_Analog_Output.h:37
vrpn_Analog::timestamp
struct timeval timestamp
Definition: vrpn_Analog.h:41
vrpn_Analog_Output
Definition: vrpn_Analog_Output.h:26
vrpn_Serial.h
vrpn_Serial: Pulls all the serial port routines into one file to make porting to new operating system...
vrpn_Nikon_Controls::handle_connect_message
static int VRPN_CALLBACK handle_connect_message(void *userdata, vrpn_HANDLERPARAM p)
Responds to a connection request with a report of the values.
Definition: vrpn_nikon_controls.C:422
vrpn_unbuffer
VRPN_API int vrpn_unbuffer(const char **buffer, timeval *t)
Utility routine for taking a struct timeval from a buffer that was sent as a message.
Definition: vrpn_Shared.C:312
vrpn_BaseClassUnique::d_connection
vrpn_Connection * d_connection
Connection that this object talks to.
Definition: vrpn_BaseClass.h:224
vrpn_HANDLERPARAM::buffer
const char * buffer
Definition: vrpn_Connection.h:49
vrpn_TEXT_ERROR
Definition: vrpn_BaseClass.h:103
vrpn_flush_input_buffer
int vrpn_flush_input_buffer(int comm)
Throw out any characters within the input buffer.
Definition: vrpn_Serial.C:435
vrpn_CONNECTION_RELIABLE
const vrpn_uint32 vrpn_CONNECTION_RELIABLE
Classes of service for messages, specify multiple by ORing them together Priority of satisfying these...
Definition: vrpn_Connection.h:120
vrpn_SleepMsecs
void vrpn_SleepMsecs(double dMsecs)
Definition: vrpn_Shared.C:157
vrpn_HANDLERPARAM
This structure is what is passed to a vrpn_Connection message callback.
Definition: vrpn_Connection.h:44
VRPN_MSG_WARNING
#define VRPN_MSG_WARNING(msg)
Definition: vrpn_MessageMacros.h:39
vrpn_Shared.h
vrpn_BaseClassUnique::d_sender_id
vrpn_int32 d_sender_id
Sender ID registered with the connection.
Definition: vrpn_BaseClass.h:228
vrpn_Nikon_Controls::handle_request_message
static int VRPN_CALLBACK handle_request_message(void *userdata, vrpn_HANDLERPARAM p)
Responds to a request to change one of the values by setting the channel to that value.
Definition: vrpn_nikon_controls.C:376
vrpn_Nikon_Controls::handle_request_channels_message
static int VRPN_CALLBACK handle_request_channels_message(void *userdata, vrpn_HANDLERPARAM p)
Responds to a request to change multiple channels at once.
Definition: vrpn_nikon_controls.C:394
vrpn_Connection
Generic connection class not specific to the transport mechanism.
Definition: vrpn_Connection.h:510
vrpn_Analog::num_channel
vrpn_int32 num_channel
Definition: vrpn_Analog.h:40
vrpn_gettimeofday
#define vrpn_gettimeofday
Definition: vrpn_Shared.h:89
STATUS_RESETTING
#define STATUS_RESETTING
Definition: vrpn_3DMicroscribe.C:26
vrpn_read_available_characters
int vrpn_read_available_characters(int comm, unsigned char *buffer, size_t bytes)
Definition: vrpn_Serial.C:512
TIMEOUT_TIME_INTERVAL
#define TIMEOUT_TIME_INTERVAL
Definition: vrpn_BiosciencesTools.C:51
vrpn_OmegaTemperature.h
vrpn_Analog_Output::o_channel
vrpn_float64 o_channel[vrpn_CHANNEL_MAX]
Definition: vrpn_Analog_Output.h:36
vrpn_MessageMacros.h
Header containing macros formerly duplicated in a lot of implementation files.
vrpn_write_characters
int vrpn_write_characters(int comm, const unsigned char *buffer, size_t bytes)
Write the buffer to the serial port.
Definition: vrpn_Serial.C:643
vrpn_Analog::report_changes
virtual void report_changes(vrpn_uint32 class_of_service=vrpn_CONNECTION_LOW_LATENCY, const struct timeval time=vrpn_ANALOG_NOW)
Send a report only if something has changed (for servers) Optionally, tell what time to stamp the val...
Definition: vrpn_Analog.C:71
VRPN_SUPPRESS_EMPTY_OBJECT_WARNING
#define VRPN_SUPPRESS_EMPTY_OBJECT_WARNING()
Definition: vrpn_Configure.h:495
vrpn_Analog_Output::request_channels_m_id
vrpn_int32 request_channels_m_id
Definition: vrpn_Analog_Output.h:40
vrpn_Analog_Output::request_m_id
vrpn_int32 request_m_id
Definition: vrpn_Analog_Output.h:39
STATUS_READING
#define STATUS_READING
Definition: vrpn_3DMicroscribe.C:28
VRPN_MSG_ERROR
#define VRPN_MSG_ERROR(msg)
Definition: vrpn_MessageMacros.h:46
vrpn_Button_Filter
All button servers should derive from this class, which provides the ability to turn any of the butto...
Definition: vrpn_Button.h:65