Code owners
Assign users and groups as approvers for specific file changes. Learn more.
Keithley_6517.cpp 10.07 KiB
// ============================================================================
//
// = CONTEXT
// TANGO Project - SCPI KeithleyElectrometer Support Library
//
// = FILENAME
// Keithley_6517.cpp
//
// = AUTHOR
// X. Elattaoui
//
// ============================================================================
static long KEITHLEY_MODEL = 6517;
// ============================================================================
// DEPENDENCIES
// ============================================================================
#include <iostream>
#include <sstream>
#include <string>
#include <Xstring.h>
#include "Keithley_6517.h"
#include "KeithleySCPIProtocol.h"
/*
* Valid Range values for a K_6517
*/
static const std::string K6517_AMP_rangeStr[] = {"2E-11","2E-10","2E-9","2E-8","2E-7","2E-6","2E-5","2E-4","2E-3","2E-2"};
static const std::string K6517_VOLT_rangeStr[]= {"2","20","200"};
static const std::string K6517_OHM_rangeStr[] = {"2E14","2E13","2E12","2E11","2E10","2E9","2E8","2E7","2E6","2E5"};
static const std::string K6517_COU_rangeStr[] = {"2E-9","2E-8","2E-7","2E-6"};
/*
* Max Index Range value for a K_6517
*/
static const short K6517_AMP_rangeLimit = 9;
static const short K6517_VOLT_rangeLimit= 2;
static const short K6517_OHM_rangeLimit = 9;
static const short K6517_COU_rangeLimit = 3;
// ============================================================================
// Keithley_6517::Keithley_6517
// ============================================================================
Keithley_6517::Keithley_6517 (std::string& comLink_device_name):
AbstractElectrometerClass(comLink_device_name),
_kmode("")
{
std::cout << "Keithley_6517::Keithley_6517 <-" << std::endl;
//- build the keithley Electrometer obj
_electrometerProtocol = new KeithleySCPIProtocol(_device_proxy_name);
//- this model supports different mode (OhmMeter, VoltMeter and so on )
KeithleySCPIProtocol* _kscpi = dynamic_cast<KeithleySCPIProtocol*>(_electrometerProtocol);
if(_kscpi)
_kscpi->set_isDiffSuportedMode(true);
std::cout << "Keithley_6517::Keithley_6517 ->" << std::endl;
}
// ============================================================================
// Keithley_6517::~Keithley_6517
// ============================================================================
Keithley_6517::~Keithley_6517 (void)
{
std::cout << "Keithley_6517::~Keithley_6517 <-" << std::endl;
std::cout << "Keithley_6517::~Keithley_6517 ->" << std::endl;
}
// ============================================================================
// Keithley_6517::range_up
// ============================================================================
void Keithley_6517::range_up (void)
{
std::stringstream cmd_to_send;
//- update range value from hardware
update_range( );
_range += 1;
//- check range validity
if(_kmode.find("CURR") != std::string::npos)
{
if(_range > K6517_AMP_rangeLimit)
{
_range = K6517_AMP_rangeLimit;
throw electrometer::ElectrometerException("OUT_OF_RANGE",
"Range up limit reached.",
"Keithley_6517::range_up( ).");
}
_rangeStr = K6517_AMP_rangeStr[_range];
}
else
if (_kmode.find("VOLT") != std::string::npos)
{
if(_range > K6517_VOLT_rangeLimit)
{
_range = K6517_VOLT_rangeLimit;
throw electrometer::ElectrometerException("OUT_OF_RANGE",
"Range up limit reached.",
"Keithley_6517::range_up( ).");
}
_rangeStr = K6517_VOLT_rangeStr[_range];
}
else
if (_kmode.find("RES") != std::string::npos)
{
if(_range > K6517_OHM_rangeLimit)
{
_range = K6517_OHM_rangeLimit;
throw electrometer::ElectrometerException("OUT_OF_RANGE",
"Range up limit reached.",
"Keithley_6517::range_up( ).");
}
_rangeStr = K6517_OHM_rangeStr[_range];
}
else if (_kmode.find("CHAR") != std::string::npos)
{
if(_range > K6517_COU_rangeLimit)
{
_range = K6517_COU_rangeLimit;
throw electrometer::ElectrometerException("OUT_OF_RANGE",
"Range up limit reached.",
"Keithley_6517::range_up( ).");
}
_rangeStr = K6517_COU_rangeStr[_range];
}
else
throw electrometer::ElectrometerException("UNKNOWN_MODE",
"Unable to find the electrometer mode used.",
"Keithley_6517::range_up( ).");
//- build and send the command
cmd_to_send << _rangeStr << std::endl;
_electrometerProtocol->set_range(cmd_to_send.str());
}
// ============================================================================
// Keithley_6517::range_down
// ============================================================================
void Keithley_6517::range_down (void)
{
std::stringstream cmd_to_send;
//- update range value from hardware
update_range( );
_range -= 1;
if(_range < 0)
{
_range = 0;
throw electrometer::ElectrometerException("OUT_OF_RANGE",
"Range down limit reached.",
"Keithley_6517::range_down( ).");
}
//- check range validity
if(_kmode.find("CURR") != std::string::npos)
cmd_to_send << K6517_AMP_rangeStr[_range] << std::endl;
else if (_kmode.find("VOLT") != std::string::npos)
cmd_to_send << K6517_VOLT_rangeStr[_range] << std::endl;
else if (_kmode.find("RES") != std::string::npos)
cmd_to_send << K6517_OHM_rangeStr[_range] << std::endl;
else if (_kmode.find("CHAR") != std::string::npos)
cmd_to_send << K6517_COU_rangeStr[_range] << std::endl;
else
throw electrometer::ElectrometerException("UNKNOWN_MODE",
"Unable to find the electrometer mode used.",
"Keithley_6517::range_down( ).");
//- build and send the command
_electrometerProtocol->set_range(cmd_to_send.str());
}
// ============================================================================
// Keithley_6517::get_integratedValue
// ============================================================================
std::vector<double> Keithley_6517::get_integratedValue (void)
{
return _electrometerProtocol->get_integratedValue( );
}
// ============================================================================
// Keithley_6517::get_fetchValue
// ============================================================================
std::vector<double> Keithley_6517::get_fetchValue (void)
{
return _electrometerProtocol->get_fetchValue( );
}
// ============================================================================
// Keithley_6517::setAmperMeterMode
// ============================================================================
void Keithley_6517::setAmperMeterMode (void)
{
_electrometerProtocol->setAmperMeterMode( );
}
// ============================================================================
// Keithley_6517::setVoltMeterMode
// ============================================================================
void Keithley_6517::setVoltMeterMode (void)
{
_electrometerProtocol->setVoltMeterMode( );
}
// ============================================================================
// Keithley_6517::setOhmMeterMode
// ============================================================================
void Keithley_6517::setOhmMeterMode (void)
{
_electrometerProtocol->setOhmMeterMode( );
}
// ============================================================================
// Keithley_6517::setCoulombMeterMode
// ============================================================================
void Keithley_6517::setCoulombMeterMode (void)
{
_electrometerProtocol->setCoulombMeterMode( );
}
// ============================================================================
// Keithley_6487::update_range
// ============================================================================
void Keithley_6517::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 device mode
_kmode = get_ElectroMeterMode();
//- 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;
short idx_limit = 0;
if(_kmode.find("CURR") != std::string::npos)
idx_limit = K6517_AMP_rangeLimit;
else if (_kmode.find("VOLT") != std::string::npos)
idx_limit = K6517_VOLT_rangeLimit;
else if (_kmode.find("RES") != std::string::npos)
idx_limit = K6517_OHM_rangeLimit;
else if (_kmode.find("CHAR") != std::string::npos)
idx_limit = K6517_COU_rangeLimit;
else
throw electrometer::ElectrometerException("UNKNOWN_MODE",
"Unable to find the electrometer mode used.",
"Keithley_6517::update_range( ).");
//- find the range index
for(idx=0; idx<idx_limit ; idx++)
{
if(_kmode.find("CURR") != std::string::npos)
{
rangeValueCalculated = XString<double>::convertFromString(K6517_AMP_rangeStr[idx]);
delta = rangeValueCalculated * 5 / 100;
if( (rangeValueCalculated + delta) >= rangeValueReturned && (rangeValueCalculated - delta) <= rangeValueReturned)
break;
}
else if (_kmode.find("VOLT") != std::string::npos)
{
rangeValueCalculated = XString<double>::convertFromString(K6517_VOLT_rangeStr[idx]);
delta = rangeValueCalculated * 5 / 100;
if( (rangeValueCalculated + delta) >= rangeValueReturned && (rangeValueCalculated - delta) <= rangeValueReturned)
break;
}
else if (_kmode.find("RES") != std::string::npos)
{
rangeValueCalculated = XString<double>::convertFromString(K6517_OHM_rangeStr[idx]);
delta = rangeValueCalculated * 5 / 100;
if( (rangeValueCalculated + delta) >= rangeValueReturned && (rangeValueCalculated - delta) <= rangeValueReturned)
break;
}
else if (_kmode.find("CHAR") != std::string::npos)
{
rangeValueCalculated = XString<double>::convertFromString(K6517_COU_rangeStr[idx]);
delta = rangeValueCalculated * 5 / 100;
if( (rangeValueCalculated + delta) >= rangeValueReturned && (rangeValueCalculated - delta) <= rangeValueReturned)
break;
}
}
//- throw if index not found
if(idx == idx_limit)
throw electrometer::ElectrometerException("INTERNAL_ERROR",
"Failed to get range index.",
"Keithley_6517::update_range( ).");
//- update the range with the index found
this->_range = idx;
}