A number of users expressed an interest in using these popular response pads in their own applications. This document offers some technical information needed in order to write your own code and sample C++ code.
The RB Series response pads send one and only one byte every time the state of one of the keys changes. See The RB Series Response Pads Protocol for information on the byte format.
For the RB-400 or RB-600 response pads, open the serial port using 8-N-1 parameters at 2400 baud.
For the RB-410 or RB-610 response pads, open the serial port using 8-N-1 parameters at 9600 baud.
For the RB-420 or RB-620 response pads, open the serial port using 8-N-1 parameters at 9600, 19200, or 38400 baud, depending on the DIP switch settings.
Here is a sample source code on how to program the RB-4×0 and RB-6×0 response pads. This sample consists of the following four functions:
CedrusOpenSerialPort
CedrusCloseSerialPort
CedrusFlushSerialPort
CedrusGetButtonResponse. This function does not return until a key has been pressed.
The sample code shown here is written for Windows 95 or later. The essential part is in the CedrusGetButtonResponse function. For other platforms, the main changes affect how the serial port is opened, read, and closed:
• For Windows 3.1, you need to call the functions OpenComm, ReadComm, and CloseComm.
• On the Macintosh, the needed functions are OpenDriver, SerSetBuf, SerGetBuf, FSRead, and CloseDriver.
The following code is for controlling the serial port:
#include "windows.h"
// A few definitions to make the C code a
// little more readable
#define EQ ==
#define NE !=
#define LT <
#define LE <=
#define GE >=
#define GT >
#define AND && // Logical operators
#define OR ||
#define NOT !
#define bAND & // Binary operators
#define bOR |
#define bNOT ~
#define bXOR ^
// Function prototypes
HANDLE CedrusOpenSerialPort (int nPortNum, int nBaudRate);
int CedrusFlushSerialPort (HANDLE nPortHandle);
void CedrusCloseSerialPort (HANDLE nPortHandle);
int CedrusGetButtonResponse (HANDLE nPortHandle, int nRBModel);
HANDLE CedrusOpenSerialPort (int nPortNum, int nBaudRate)
{
// -- nPortNum should be set to 1 to open COM1,
// 2 to open COM2, etc.
// -- nBaudRate should be a valid baud rate,
// e.g. 2400 or 9600
//
// This function returns -1 if it fails. If
// successful, it returns a "port handle" that
// is passed to other functions afterwards
// to access or close the serial port.
char port_name[8];
HANDLE port_handle;
wsprintf (port_name, "COM%d", nPortNum);
port_handle = CreateFile (port_name,
GENERIC_READ | GENERIC_WRITE,
0, NULL, OPEN_EXISTING, 0, NULL);
if (port_handle EQ INVALID_HANDLE_VALUE)
{
port_handle = (HANDLE) -1; // Return error
}
else
{
DCB dcb;
int status;
COMMTIMEOUTS ct;
status = GetCommState (port_handle, &dcb);
// Setup serial port for 8-N-1
// (8 bits, no parity, 1 stop bit)
if (status NE 0)
{
dcb.BaudRate = nBaudRate;
dcb.ByteSize = (unsigned char) 8;
dcb.Parity = 0;
dcb.StopBits = 0;
dcb.fBinary = 1; // No EOF check
status = SetCommState (port_handle, &dcb);
}
// Setup timeouts
ct.ReadIntervalTimeout = MAXDWORD;
ct.ReadTotalTimeoutMultiplier = 0;
ct.ReadTotalTimeoutConstant = 0;
ct.WriteTotalTimeoutMultiplier = 0;
ct.WriteTotalTimeoutConstant = 5000;
SetCommTimeouts (port_handle, &ct);
status = SetupComm (port_handle, 128, 128);
CedrusFlushSerialPort (port_handle);
}
return port_handle;
}
int CedrusFlushSerialPort (HANDLE nPortHandle)
{
int status = 0;
short done = FALSE;
char serial_buff[100];
DWORD bytes_read;
while (NOT done)
{
status = ReadFile (nPortHandle, serial_buff,
sizeof(serial_buff),
&bytes_read, NULL);
if (status EQ 0)
done = TRUE; // Error?!
if (status NE 0 AND
bytes_read LT sizeof(serial_buff))
{
done = TRUE;
}
}
return status;
}
void CedrusCloseSerialPort (HANDLE nPortHandle)
{
CloseHandle (nPortHandle);
}
The following code keeps looping until a pushbutton has been pressed on the response pad:
int CedrusGetButtonResponse (HANDLE nPortHandle, int nRBModel)
{
// nRBModel should be 1 for RB-400/RB-410, or
// 2 for RB-600/RB-610
short rb4x0[6] = {-1, -1, 0, 1, 2, 3 };
short rb6x0[6] = {0, 5, 1, 2, 3, 4 };
int num_bytes;
int i, k;
int button_pressed = FALSE;
short buttons_status;
short status;
char serial_buff[6];
DWORD comm_status;
CedrusFlushSerialPort (nPortHandle);
while (NOT button_pressed)
{
k = -1;
serial_buff[0] = '\0';
num_bytes = 0;
buttons_status = 0;
// See if a byte come from the serial port
status = ReadFile (nPortHandle, serial_buff,
1, &comm_status, NULL);
if (status NE 0)
num_bytes = (short) comm_status;
// Clear any overflow or other erros that might occur
if (status EQ 0)
ClearCommError (nPortHandle, &comm_status, NULL);
// Convert to positive logic w/o the negative sign
if (num_bytes GT 0)
buttons_status = (bNOT serial_buff[0]) bAND 0x003f;
if (buttons_status GT 0)
{
i = 0;
// This loop converts from an integer
// to a bit number from 0 to 5
while (i LT 6)
{
if ((1 << i) bAND buttons_status)
{
k = i;
break;
}
i++;
}
// Re-map bit number to actual
// button, depending on model
if (nRBModel EQ 2)
button_pressed = rb6x0[k] + 1;
else
button_pressed = rb4x0[k] + 1;
}
}
return button_pressed;
}
That's it. The following sample code will simply call the functions shown above to illustrate how they are called and used:
void CedrusTestResponseBox (void)
{
HANDLE hPort;
// Demo code for the RB-610
// Open COM2 at 9600 baud (use 2400 for RB-400/RB-600)
hPort = CedrusOpenSerialPort (2, 9600);
if (hPort NE (HANDLE) -1)
{
int key_pressed;
char ch_buff[100];
// Get response from RB-610. Change second
// parameter from 2 to 1 if using the RB-400
// or RB-410.
key_pressed = CedrusGetButtonResponse (hPort, 1);
// Display a message to show the result
wsprintf (ch_buff, "Button number %d was pressed!",
key_pressed);
MessageBox (NULL, ch_buff, "Cedrus Code Snippet",
MB_OK | MB_ICONINFORMATION);
CedrusCloseSerialPort (hPort);
}
}
This code sample has been compiled and tested using Visual C++ 5.0.
Last revision: July 25, 2002
PRODUCTS
SUPPORT
STAY IN TOUCH
© Copyright 2024 Cedrus Corporation, P.O. Box 6309, San Pedro, CA 90734 - USA
Phone: +1-310-548-9595. Send us an email. See privacy policy.
qwerasdf