The Rulbus Device Class Library consists of one or more classes for each Rulbus module. These classes are published in C++ header files, one for each Rulbus module, for example rb8510_dac12.h
. You normally need to only call methods for the Rulbus modules you want to use (but also see Handling Errors).
Rulbus modules are used according to the pattern: create -- use -- destroy, for example:
#include "rdcl/rb8510_dac12.h" int main() { Rulbus::RB8510_Dac12 dac( "mydac", ... ); // create device dac.setVoltage( ... ); // use it ... // even more // // dac goes out of scope here; it is destroyed automatically // }
Note that the classes reside in the namespace Rulbus.
Besides the Rulbus module related classes, there are general Rulbus device methods. The latter are part of class RulbusDevice. Class names appear in the following forms:
RByydd_
... -- specific Rulbus module related classes, like RB8510_Dac12RulbusDevice
-- general Rulbus device methods, like RulbusDevice::printInterface()Another way to create and use Rulbus devices is presented in Support for the Rulbus Device Library (DLL).
In the following command, {include-path} specifies the directory with the header files and {library-path} specifies the directory with rulbusdcl-omf-static.lib
and winutils-omf-static.lib
.
To create the program, compile as follows:
C:\>bcc32 -tWM -I(include-path) -L{library-path} {program}.cpp \ rulbusdcl-omf-static.lib winutils-omf-static.lib
Option -tWM
specifies that the program must be linked with the multi-threaded C runtime library.
All classes in the Rulbus Device Class Library use the same error handling pattern: they throw an exception when something is not in order. Exceptions may be divided into:
A properly written program should always catch the exceptions that may arise to see if the method calls where successful and it should act accordingly. Failing to do so may crudely abort the program giving an "Abnormal program termination" message.
When an error occurred, a string explaining the error condition may be obtained from the exception with method what(). The exception can also be printed on a stream as in the following example.
#include <iostream> // for std::cerr #include "rdcl/rb8510_dac12.h" // for class RB8510_Dac12 int main() { try { /* * create a dac at an invalid Rulbus address (0x123), * an environmental error: */ Rulbus::RB8510_Dac12 dac( "mydac", 0x123, 7 ); // ... } catch ( const std::exception& e ) { std::cerr << e; } }
The program gives:
Rulbus: cannot open rulbus device 'mydac' at [7:0x123]
For more information on design-by-contract, see [DBC]
Several fundamental types and std
namespace classes and all classes of this library are made available with standardized names for (const) pointer types and (const) reference types.
typedef type Type; typedef type* TypePtr; typedef const type* TypeCptr; typedef type& TypeRef; typedef const type& TypeCref;
The following compiler dependent types are defined:
The following fundamental library types are defined:
DECLARE_TYPE( uInt8 , Byte ); DECLARE_TYPE( uInt16 , Word ); DECLARE_TYPE( uInt32 , Quad ); DECLARE_TYPE( char , Char ); DECLARE_TYPE( int , Int ); DECLARE_TYPE( int16 , Int16 ); DECLARE_TYPE( int32 , Int32 ); DECLARE_TYPE( double , Real ); DECLARE_TYPE( float32, Real32 ); DECLARE_TYPE( float64, Real64 );
The following convenience types are defined:
DECLARE_TYPE( std::string , String ); DECLARE_TYPE( std::exception, StdException );
For each class 'myClass', the following types are defined via macro DECLARE_CLASS():
class myClass; typedef myClass* myClassPtr; typedef const myClass* myClassCptr; typedef myClass& myClassRef; typedef const myClass& myClassCref;
The following example program creates (opens) a DAC, generates a staircase voltage and destroys (closes) the DAC again.
/* * dac.cpp - generate a staircase voltage. * * Compile: bcc32 -tWM dac.cpp rulbusdcl-omf-static.lib winutils-omf-static.lib */ #include <iostream> // for std::cout etc. #include <cstdlib> // for std::strtol() #include <windows.h> // for Sleep() #include "rdcl/rb8510_dac12.h" // header static int usage(); // print program usage, return EXIT_FAILURE /* * main - handle commandline arguments and generate staircase voltage on DAC. */ int main( int argc, char *argv[] ) { try { /* * handle commandline arguments: */ if ( argc < 4 ) return usage(); /* * for rack and Rulbus address, let strtol() determine the radix of the input: * octal for 012, decimal for 12, hexadecimal for 0x12. */ char *name = argv[1]; int rack = std::strtol( argv[2], 0, 0 ); int addr = std::strtol( argv[3], 0, 0 ); const int bipolar = 1; // bipolar const float vpb = 5e-3; // volt-per-bit /* * create the DAC: */ Rulbus::RB8510_Dac12 dac( name, addr, rack, bipolar, vpb ); /* * generate 11 one volt steps, one per second: * * Note that the last step generates a RulbusRangeError, because the * voltage is outside [-10.235 .. +10.24 V]. */ for ( int i = 0; i <= 11; i++ ) { std::cout << '[' << i << ']'; dac.setVoltage( i ); Sleep( 1000 ); // delay one second } /* * dac goes out of scope and is destroyed: */ } catch ( const std::exception& e ) { std::cout << std::endl << e << std::endl; } return EXIT_SUCCESS; } /* * usage - print program usage. */ static int usage() { std::cout << "Usage: dac device-name rulbus-rack rulbus-address" << std::endl; return EXIT_FAILURE; }
previous | top | next |