Skip to content
Snippets Groups Projects
Select Git revision
  • main
  • lima_internal_multi
  • master
  • release_3_5_19
  • release_3_5_18
  • release_3_5_17
  • release_3_5_16
  • release_3_5_15
  • bad_release_3_5_15
  • release_3_5_14
  • release_3_5_13
  • release_3_5_12
  • release_3_5_11
  • release_3_5_10
  • release_3_5_9
  • release_3_5_8
  • release_3_5_7
  • release_3_5_6
  • release_3_5_5
  • release_3_5_4
  • release_3_5_3
  • release_3_5_2
  • release_3_5_1
23 results

pom.xml

Blame
  • Code owners
    Assign users and groups as approvers for specific file changes. Learn more.
    Keithley_6485.cpp 10.35 KiB
    // ============================================================================
    //
    // = CONTEXT
    //    TANGO Project - SCPI KeithleyElectrometer Support Library
    //
    // = FILENAME
    //    Keithley_6485.cpp
    //
    // = AUTHOR
    //    X. Elattaoui
    //
    // ============================================================================
    
    // ============================================================================
    // DEPENDENCIES
    // ============================================================================
    #include <iostream>
    #include <sstream>
    #include <string>
    #include <math.h>   //- for ceil
    #include <Xstring.h>
    #include "Keithley_6485.h"
    #include "KeithleySCPIProtocol.h"
    /*
    * Valid Range values for a K_6485
    */
    static const std::string K6485_rangeValue[] = {"2E-9","2E-8","2E-7","2E-6","2E-5","2E-4","2E-3","2E-2"};
    /*
    * Max Index Range value for a K_6485
    */
    static const short K6485_rangeLimit = 7;
    
    // ============================================================================
    // Keithley_6485::Keithley_6485
    // ============================================================================
    Keithley_6485::Keithley_6485 (std::string& comLink_device_name)
    :   AbstractElectrometerClass(comLink_device_name)
    {
    	std::cout << "Keithley_6485::Keithley_6485 <-" << std::endl;
    	
      _numPLC     = 0;
      _trigCounts = 0;
      _size       = 0;
    	
    	std::cout << "Keithley_6485::Keithley_6485 ->" << std::endl;
    }
    
    // ============================================================================
    // Keithley_6485::~Keithley_6485
    // ============================================================================
    Keithley_6485::~Keithley_6485 (void)
    {
    	std::cout << "Keithley_6485::~Keithley_6485 <-" << std::endl;
    	
    	std::cout << "Keithley_6485::~Keithley_6485 ->" << std::endl;
    }
    
    // ============================================================================
    // Keithley_6485::init_protocol
    // ============================================================================
    bool Keithley_6485::init_protocol (void)
    {
      std::string description("");
      bool success = false;
    
      try
      {
    	  //- build the keithley Electrometer protocol obj
    	  _electrometerProtocol = new KeithleySCPIProtocol(_device_proxy_name);
    
        if (_electrometerProtocol)
        {
    	    //- this model supports different mode (OhmMeter, VoltMeter and so on )
    	    KeithleySCPIProtocol* _kscpi = dynamic_cast<KeithleySCPIProtocol*>(_electrometerProtocol);
    	    if(_kscpi)
    		    _kscpi->set_isDiffSuportedMode(false);
            
          success = _electrometerProtocol->build_communicationLink();
        }
      }
      catch(Tango::DevFailed& df)
      {
    		description = "FAILED to create proxy on : " + _device_proxy_name;
    		
    		Tango::Except::re_throw_exception (df,
    			(const char*)"COMMUNICATION_ERROR",
    			description.c_str(),
    			(const char*)"Keithley_6485::init_protocol");
      }
      catch(...)
      {
    		description = "FAILED to create proxy on : " + _device_proxy_name + ". Caught [...].";
    		
    		Tango::Except::throw_exception (
    			(const char*)"COMMUNICATION_ERROR",
    			description.c_str(),
    			(const char*)"Keithley_6485::init_protocol");
      }
      return success;
    }
    
    // ============================================================================
    // Keithley_6485::range_up
    // ============================================================================
    void Keithley_6485::range_up (void) 
    {
    std::stringstream cmd_to_send;
    	
    	//- update range index from hardware
    	update_range( );
    
    	_range += 1;
    	
    	if(_range > K6485_rangeLimit)
    	{
    		_range = K6485_rangeLimit;
    		throw electrometer::ElectrometerException("OUT_OF_RANGE", 
    												"Range up limit reached.",
    												"Keithley_6485::range_up( ).");
    	}
    	
    	//- build and send the command
    	_rangeStr = K6485_rangeValue[_range];
    	cmd_to_send << _rangeStr << std::endl;
    	_electrometerProtocol->set_range(cmd_to_send.str());
    }
    
    // ============================================================================
    // Keithley_6485::range_down
    // ============================================================================
    void Keithley_6485::range_down (void) 
    {
    std::stringstream cmd_to_send;
    	
    	//- update range index from hardware
    	update_range( );
    
    	_range -= 1;
    	
    	if(_range < 0)
    	{
    		_range=0;
    		throw electrometer::ElectrometerException("OUT_OF_RANGE", 
    												"Range down limit reached.",
    												"Keithley_6485::range_down( ).");
    	}
    	//- build and send the command
    	_rangeStr = K6485_rangeValue[_range];
    	cmd_to_send << _rangeStr << std::endl;
    
      _electrometerProtocol->set_range(cmd_to_send.str());
    }
    
    // ============================================================================
    // Keithley_6485::update_range
    // ============================================================================
    void Keithley_6485::update_range (void) 
    {
    std::string range_str("");
    double rangeValueReturned	= 0;
    double rangeValueCalculated	= 0;
    double delta = 0;
    	
    	/**
    	*	NOTE : SCPI models return a range value +/- 5%
    	*/
    
    	//- get range from hardware
    	range_str = _electrometerProtocol->get_range( );
    	//- convert range in decimal value
    	rangeValueReturned = XString<double>::convertFromString(range_str);
    	
    	//- find and return the index
    	short idx = 0;
    	for(idx=0; idx<K6485_rangeLimit ; idx++)
    	{
    		rangeValueCalculated = XString<double>::convertFromString(K6485_rangeValue[idx]);
    		delta = rangeValueCalculated * 5 / 100;
    		if( (rangeValueCalculated + delta) >= rangeValueReturned && (rangeValueCalculated - delta) <= rangeValueReturned)
    			break;
    	}
    
    	//- throw if index not found
    	if(idx == K6485_rangeLimit)
    		throw electrometer::ElectrometerException("INTERNAL_ERROR", 
    			"Failed to get range index.",
    			"Keithley_6485::update_range( ).");
    
    	//- update range with index found
    	this->_range = idx;
    		
    }
    
    // ============================================================================
    // Keithley_6485::get_integratedValue
    // ============================================================================
    std::vector<double> Keithley_6485::get_integratedValue (void) 
    {
     	KeithleySCPIProtocol* _kscpi = dynamic_cast<KeithleySCPIProtocol*>(_electrometerProtocol);
    	if(!_kscpi)
    		throw electrometer::ElectrometerException("INTERNAL_ERROR", 
    												"Dynamic cast failed !.",
    												"Keithley_6485::get_integratedValue( ).");
    
      return 	_electrometerProtocol->get_integratedValue( );
    }  
    
    // ============================================================================
    // Keithley_6485::get_fetchValue
    // ============================================================================
    std::vector<double> Keithley_6485::get_fetchValue (void) 
    {
     	KeithleySCPIProtocol* _kscpi = dynamic_cast<KeithleySCPIProtocol*>(_electrometerProtocol);
    	if(!_kscpi)
    		throw electrometer::ElectrometerException("INTERNAL_ERROR", 
    												"Dynamic cast failed !.",
    												"Keithley_6485::get_fetchValue( ).");
    
      return 	_kscpi->get_fetchValue( );
    }  
    
    // ============================================================================
    // Keithley_6485::set_knplc
    // ============================================================================
    void Keithley_6485::set_knplc (double numPLC) 
    {
    std::stringstream cmd_to_send;
    
      if(numPLC <= 0 || numPLC > 5.0)
    	{
    //    std::cout << "Keithley_6485::set_knplc -> " << numPLC << std::endl;
    		throw electrometer::ElectrometerException("OUT_OF_RANGE", 
    												"Invalid number of PLC.\n Please enter a value in the range 0.01 to 5.0.",
    												"Keithley_6485::set_knplc( ).");
    	}
      //- just for internal use
      _numPLC = numPLC;
    
      cmd_to_send << numPLC << std::endl;
      //- default conversion rate
      _electrometerProtocol->set_knplc(cmd_to_send.str());
    }  
    
    // ============================================================================
    // Keithley_6485::set_triggercount
    // ============================================================================
    void Keithley_6485::set_triggercount (short trigCounts) 
    {
    std::stringstream cmd_to_send;
    
      if(trigCounts == 0 || trigCounts > 2500)
    	{
    		throw electrometer::ElectrometerException("OUT_OF_RANGE", 
    												"Invalid trigger count.\n Please enter a value in the range 1 to 2500 or set -1 for INFinite.",
    												"Keithley_6485::set_triggercount( ).");
    	}
      if(trigCounts < 0)
        cmd_to_send << "INF" << std::endl;
      else
        cmd_to_send << trigCounts << std::endl;
    
      //- just for internal use
      _trigCounts = trigCounts;
      //- default conversion rate
      _electrometerProtocol->set_triggercount(cmd_to_send.str());
    }  
    
    // ============================================================================
    // Keithley_6485::set_buffer_size
    // ============================================================================
    void Keithley_6485::set_buffer_size (short size) 
    {
    std::stringstream cmd_to_send;
    
      if(size < 1 || size > 2500)
    	{
    		throw electrometer::ElectrometerException("OUT_OF_RANGE", 
    												"Invalid buffer size. \nPlease enter a value in the range 1 to 2500.",
    												"Keithley_6485::set_buffer_size( ).");
    	}
      //- just for internal use
      _size = size;
    
      cmd_to_send << size << std::endl;
      //- default conversion rate
      _electrometerProtocol->set_buffer_size(cmd_to_send.str());
    }  
    
    // ============================================================================
    // Keithley_6485::set_integrationTime
    // ============================================================================
    void Keithley_6485::set_integrationTime (double seconds) 
    {
      //- set the number of Power Line Cycle(s) -> Fast integration
      _numPLC = 0.05;
      //- set the number of trigger(s) ~ buffer size
      _trigCounts = (short)ceil(seconds / _numPLC);
    
      if(_trigCounts > 2500)
        _trigCounts = 2500;
    }
    
    // ============================================================================
    // Keithley_6485::init_keithley : command to perform an integration cycle
    // ============================================================================
    void Keithley_6485::init_keithley (void) 
    {
      //- clear all registers
      _electrometerProtocol->clear_registers();
      //- get data only (no timestamp info ... wanted!)
      _electrometerProtocol->read_data_with_no_timestamp();
      //- Set integration rate in line cycles
      this->set_knplc(_numPLC);
      //- Set trigger model to take to N readings
      this->set_triggercount(_trigCounts);
      //- Set buffer size
      this->set_buffer_size(_size);
      //- clear previous data
      _electrometerProtocol->clear_buffer();
      //- Store raw input
      _electrometerProtocol->store_raw_input();
      //- Start storing on next reading
      _electrometerProtocol->start_storing();
      //- Enable SRQ on buffer full
      _electrometerProtocol->enable_SRQBufferFull();
      //- Trigger readings
      _electrometerProtocol->init_keithley();
    }