Cedrus logo
Click on icon to search our website (not including the store).

Support    RB-x20 Series   Programming for the RB Series Response Pads

Summary

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.

Programming Notes

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.

Programming Example

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.

Controlling the Serial Port

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);

}

Checking the Status of the Buttons

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