The following program demonstrates how to open a driver to a single PCI
        board, setup the controller, start an exposure, keep track of the read
        progress, write the image data to a FITS file, and then close the driver.
        NOTE: The SetDots function is purely for producing a visual effect when
        displaying the output to the user.
        

        #include <iostream>
        #include <iomanip>
        #include "CController.h"
        #include "CDeinterlace.h"
        #include "CFitsFile.h"

        using namespace std;
        using namespace arc;

        //
        // Camera specific data (dsp file, dimensions, expose time)
        //
        #define TIM_FILE	"tim.lod"
        #define EXP_TIME	5000
        #define IMG_ROWS	512
        #define IMG_COLS	600

        void Expose( CController &cController );
        std::string SetDots( const char *cStr );

        //
        // Main program
        //
        int main()
        {
	        //
	        // Create an instance of the ARC controller API
	        //
	        CController cController;

	        cout << endl;

	        try
	        {
		        //
		        // Find all ARC pci device
		        //
		        cout << SetDots( "Getting device bindings" );
		        cController.GetDeviceBindings();
		        cout << "done!" << endl;

		        //
		        // Open a driver/device connection
		        //
		        cout << SetDots( "Opening PCI driver" );
		        cController.OpenDriver( 0, 4200 * 4200 * sizeof( unsigned short ) );
		        cout << "done!" << endl;

		        //
		        // Setup the controller
		        //
		        cout << SetDots( "Setting up controller" );
		        cController.SetupController( true,          // Reset Controller
		                                     true,          // Test Data Link ( TDL )
		                                     true,          // Power On
		                                     IMG_ROWS,      // Image row size
		                                     IMG_COLS,      // Image col size
		                                     TIM_FILE );    // DSP timing file
		        cout << "done!" << endl;

		        //
		        // Expose
		        //
		        Expose( cController );

		        //
		        // Deinterlace the image
		        //
		        cout << SetDots( "Deinterlacing image" );
		        CDeinterlace cDeint;

		        cDeint.RunAlg( cController.mapFd,
		                       IMG_ROWS,
		                       IMG_COLS,
		                       CDeinterlace::DEINTERLACE_SERIAL );

		        cout << "done!" << endl;

		        //
		        // Save the image to FITS
		        //
		        cout << SetDots( "Writing FITS" );
		        CFitsFile cFits( "Image.fit", IMG_ROWS, IMG_COLS );
		        cFits.Write( cController.mapFd );
		        cout << "done!" << endl;

		        //
		        // Close the driver/device connection
		        //
		        cout << SetDots( "Closing PCI driver" );
		        cController.CloseDriver();
		        cout << "done!" << endl;
	        }
	        catch ( std::runtime_error &e )
	        {
		        cout << "failed!" << endl;
		        cerr << endl << e.what() << endl;
		        cController.CloseDriver();
	        }
	        catch ( ... )
	        {
		        cerr << endl << "Error: unknown exception occurred!!!" << endl;
		        cController.CloseDriver();
	        }
        }

        void Expose( CController &cController )
        {
	        long lPixCnt		= 0;
	        long lReply			= 0;
	        long lCnt			= 0;
	        long lElapsedTime	= 0;
	        long lExpTime		= EXP_TIME;

	        // Set exposure time - set to 5 sec
	        //
	        cout << SetDots( "Setting exposure time" );
	        lReply = cController.Command( TIM_ID, SET, lExpTime );
	        cController.CheckReply( lReply );
	        cout  << "done!" << endl;

	        // Set shutter postion; true to open shutter; false
	        // otherwise.
	        //
	        cout << SetDots( "Setting shutter position" );
	        cController.SetOpenShutter( true );
	        cout  << "done!" << endl;

	        // Start the exposure
	        //
	        cout << SetDots( "Starting exposure" );
	        lReply = cController.Command( TIM_ID, SEX );
	        cController.CheckReply( lReply );
	        cout  << "done!" << endl;

	        while ( lPixCnt < ( IMG_ROWS * IMG_COLS ) )
	        {
		        lPixCnt = cController.GetPixelCount();

		        if ( !cController.IsReadout() && lPixCnt == 0 && lExpTime > 1000 )
		        {
			        if ( lCnt > 5 )
			        {
				        long lReply = cController.Command( TIM_ID, RET );
				        lElapsedTime = ( lExpTime/1000 ) - ( lReply/1000 );

				        cout << SetDots( "Elapsed Time" ) << setfill( '0' )
				             << setw( 8 ) << lElapsedTime << '\r'; 

				        lCnt = 0;
			        }
			        lCnt++;

        #ifdef WIN32
			        Sleep( 25 );
        #else
			        usleep( 250 );
        #endif
			        continue;
		        }

		        cout << SetDots( "Pixels Read" ) << setfill( '0' )
		             << setw( 8 ) << lPixCnt << '\r'; 
	        }

	        cout << endl;
        }

        std::string SetDots( const char *cStr )
        {
	        std::string sStr( cStr );

	        for ( int i=sStr.length(); i<40; i++ )
		        sStr.append( "." );

	        return sStr;
        }