Main Page | Namespace List | Class List | File List | Namespace Members | Class Members | Examples

k195a.cxx

/*
 * K195A Keithley digital multimeter control program
 *
 * This program demonstrates the use of the INES GPIB 
 * native C++ API for instrument control purposes.
 * 
 * (c) 2005, 2006
 */

#include <iostream>     /* for console messages */
#include <assert.h>     /* to catch the unexpected ... */

/*
 * inclusion of the API header files
 */
#include "gpib/gu_c.hxx"
#include "umi/umi_k.hxx"


  namespace Gif=INdepGpib100;           /* namespace shorthands         */
  namespace Umi=INdepUmi100;

  UMI_KERNEL_INIT;                      /* kernel interface initializer         */

  int k195a(Gif::GpibControl *pgc);     /* forward declaration */

  /*
   * main() function
   *
   * one invocation argument is required (the interface descriptor),
   * which tells us which GPIB interface to work with.
   *
   * the format of the interface descriptor depends on the operating system 
   * and the particular interface adaptor used.
   */

  int main(int argc, char **argv) {
    if (argc < 2) {
      std::cerr << "usage: " << argv[0] << " <interface>" << std::endl;

      /* can't work without interface descriptor */
      return 2;
    }

    /*
     * Gif::GpibInterfaceControl is a factory class, i.e. is
     * required to construct the API object.
     *
     * It requires the interface descriptor string as it's argument.
     */
    Gif::GpibInterfaceControl gi(argv[1]);

    if (!gi) {
      /*
       * The creation of the API object may fail. For this case
       * an error message is provided.
       */
      std::cerr << argv[0] << ": can't open " << argv[1] << ' ' << gi << std::endl;

      /* can't work without API object */
      return 2;
    }

    /*
     * Now, as we are sure to have an interface to work with,
     * call the instrument handler. The API object to
     * work with is read from the factory 'gi' by the member pGuc()
     */
    return k195a(gi.pGuc());                    
  }

  /*
   * definition the the controller GPIB address (GAD_CO)
   * and the instrument address (GAD_K195A). 
   *
   * Instrument addresses are set up at the instruments control panels or 
   * switches.
   *
   * For the controller address, any non-conflicting, valid GPIB address 
   * may be used. 
   *
   */
  #define GAD_CO  0x1e
  #define GAD_K195A  9


  /* 
   * failed() sends an error message composed from several sources
   * to the user. It returns an int to make it convenient to return
   * from a function in a single line, e.g. return failed(...);
   */
  int failed( const Gif::GpibControl *pgc, const char *sz, int iLine=0 ) {
    std::cerr << *pgc << std::endl;
    return 2;
  }

  /*
   * k195a() -- The instrument handler.
   *
   * pgc - Controller API object to work with.
   * 
   * return 0 on success, nonzero otherwise.
   */
  int k195a(Gif::GpibControl *pgc) {
      /* 
       * Initialize the interface and provide the interface (controller) address
       */
      if (!pgc->open( true, GAD_CO)) return failed(pgc, "open");

      /*
       * Send the interface clear signal. This resets the interfaces
       * of the connected devices. 
       */
      if (!pgc->ifc(UmiTime(1,0))) return failed(pgc, "ifc");


      /* 
       * Set the REMOTE ENABLE line true. This
       * makes all instruments ready for remote control.
       */
      if (!pgc->ren( true)) return failed(pgc,"ren");


      /* 
       * Optionally enable logging to the supplied std::ostream 
       * Use this option to trace bus operations.
       */
      pgc->setLog(&std::cerr);  

      /*
       * Send the SDC (Selected Device Clear) to the addressed
       * instrument. This should clear (reset) the instruments
       * functions.
       */
      if (!pgc->clear(GAD_K195A, UmiTime(1,0))) return failed(pgc, "clear");



      int cRun;                 /* counter */
      for (cRun=0; cRun<10; cRun++ ) {  

        /* 
         * Send data from a \0 terminated string to the instrument.
         *
         * These data are instrument specific and _not_ defined by the IEEE488.1
         * standard. See the documents provided with your instrument(s).
         */
        if (!pgc->sendsz(GAD_K195A, "F0R7Z0P0Q0X")) return failed(pgc, "send", __LINE__);

        /* 
         * Receive data (measurement samples) from the K195A DMM
         */
        char mpch[2048];        /* buffer */
        unsigned c=sizeof(mpch); /* size  */
        if (!pgc->receive(mpch, &c, GAD_K195A)) return failed(pgc, "receive", __LINE__); 

        /* show the data */
        std::cout.write((char*)mpch, c);
        std::cout.flush();

        /* 
         * Read pending SRQ (Service Request) indications from the instrument.
         * The timeout is 0, thus the wait returns immediately, 
         * regardless if there was any indication.
         */
        pgc->wait(Gif::E_SRQI, 0);


        if (1) {        
          /* Sample into internal buffer */
          if (!pgc->sendsz(GAD_K195A, "D  RUNX")) return failed(pgc, "send", __LINE__);

          /* High speed sample until buffer full */
          if (!pgc->sendsz(GAD_K195A, "S0M4X")) return failed(pgc, "send", __LINE__);

          /* Enable auto range */
          if (!pgc->sendsz(GAD_K195A, "R0X")) return failed(pgc, "send", __LINE__);

          /* Clear buffer */
          if (!pgc->sendsz(GAD_K195A, "Q0X")) return failed(pgc, "send", __LINE__);

          /* No delay */
          if (!pgc->sendsz(GAD_K195A, "Q01X")) return failed(pgc, "send", __LINE__);
        }

        /*
         * Wait for the buffer to fill, but not longer than 10 sec.
         */
        std::cout << "wait..." << std::endl;
        if (!pgc->wait(Gif::E_SRQI, Umi::Time(10))) return failed(pgc, "wait", __LINE__);
        std::cout << "done" << std::endl;

        if (1) {
          /* 
           * Read the status byte (we do not evaluate) 
           * Required to reset the SRQ indication
           */
          char ch;
          if (!pgc->readStatusByte(&ch, GAD_K195A)) return failed(pgc, "spoll", __LINE__);
          std::cout << std::hex << (int)((unsigned char)ch) << std::endl;

          /* Read complete buffer on next transfer */
          if (!pgc->sendsz(GAD_K195A, "B1X")) return failed(pgc, "send", __LINE__);

          /*
           * Read the buffer data
           */
          c=sizeof(mpch);
          if (!pgc->receive(mpch, &c, GAD_K195A)) return failed(pgc, "receive", __LINE__);

          /* show the data */
          std::cout.write((char*)mpch, 24) << std::endl;
          std::cout << std::dec << c << std::endl;
        }
      }

      /*
       * Send 'raw' commands to the bus.
       *
       * Here, the GPIB commands UNL and UNT (ASCII codes '?' and '_' ) 
       * are sent to unaddress all interfaces.
       */
      pgc->cmd("?_", 2, Umi::Time(1,0));
      if (pgc->isFail()) return failed(pgc, "cmd");

      std::cout << cRun << " done " << std::endl;

      /*
       * Close the interface. 
       */
      if (!pgc->close()) return failed(pgc, "close");

      /*
       * Now we're done
       */
      return 0;
    }


Generated on Wed Jul 18 16:50:57 2007 for gpibapi by doxygen 1.3.6