From 75ad7e2c38e227476b46ecb7b95f68f2d473ccbc Mon Sep 17 00:00:00 2001 From: Xavier Elattaoui <xavier.elattaoui@synchrotron-soleil.fr> Date: Tue, 25 Sep 2007 14:45:54 +0000 Subject: [PATCH] xavier : support added for Keithley 6517 --- include/Keithley_6514.h | 2 +- include/Keithley_6517.h | 73 ++++++++ src/KeithleySCPIProtocol.cpp | 2 +- src/Keithley_6514.cpp | 2 +- src/Keithley_6517.cpp | 319 +++++++++++++++++++++++++++++++++++ src/Makefile.linux | 36 ++-- src/Makefile.vc | 1 + 7 files changed, 416 insertions(+), 19 deletions(-) create mode 100644 include/Keithley_6517.h create mode 100644 src/Keithley_6517.cpp diff --git a/include/Keithley_6514.h b/include/Keithley_6514.h index e2e3c0d..d844e27 100644 --- a/include/Keithley_6514.h +++ b/include/Keithley_6514.h @@ -48,7 +48,7 @@ public: void range_up (void); void range_down (void); - std::vector<double> get_integratedValue (void); + std::vector<double> get_integratedValue (void); std::vector<double> get_fetchValue (void); /** * \brief Electrometer Mode. diff --git a/include/Keithley_6517.h b/include/Keithley_6517.h new file mode 100644 index 0000000..833a992 --- /dev/null +++ b/include/Keithley_6517.h @@ -0,0 +1,73 @@ +// ============================================================================ +// +// = CONTEXT +// TANGO Project - SCPI Keithley Electrometer Support Library +// +// = FILENAME +// Keithley_6517.h +// +// = AUTHOR +// X. Elattaoui +// +// ============================================================================ + +#ifndef _Keithley_6517_H_ +#define _Keithley_6517_H_ + +#include "AbstractElectrometerClass.h" + +/** + * \addtogroup SCPI Keithley + * @{ + */ + +/** + * \brief This class manage 6517 Keithley type + * + * \author Xavier Elattaoui + * \date 09-2007 + */ + +class Keithley_6517 : public AbstractElectrometerClass +{ +public: + + /** + * \brief Initialization. + */ + Keithley_6517 (std::string& comLink_device_name); + + /** + * \brief Release resources. + */ + virtual ~Keithley_6517 (void); + + /** + * \brief Device dependent commands. + */ + void range_up (void); + void range_down (void); + + std::vector<double> get_integratedValue (void); + std::vector<double> get_fetchValue (void); + /** + * \brief Electrometer Mode. + */ + void setAmperMeterMode (void); + void setVoltMeterMode (void); + void setOhmMeterMode (void); + void setCoulombMeterMode (void); + + //- TODO : + // SCPI_Filters* _ddcFilters; + // SCPI_Triggers* _ddcTriggers; +private: + //- method to obtain the range index + void update_range (void); + std::string _kmode; + +}; + +/** @} */ //- end addtogroup + +#endif // _Keithley_6517_H_ diff --git a/src/KeithleySCPIProtocol.cpp b/src/KeithleySCPIProtocol.cpp index 62af3ae..85987f9 100644 --- a/src/KeithleySCPIProtocol.cpp +++ b/src/KeithleySCPIProtocol.cpp @@ -368,7 +368,7 @@ std::string cmd_to_send(""); std::string tmp(""); //- This command queries the last value(s) - cmd_to_send = "FETch?" ; + cmd_to_send = "FETCh?" ; tmp = _communication_link->write_read(cmd_to_send); //- extract all data diff --git a/src/Keithley_6514.cpp b/src/Keithley_6514.cpp index 54ed372..fc32817 100644 --- a/src/Keithley_6514.cpp +++ b/src/Keithley_6514.cpp @@ -27,7 +27,7 @@ static long KEITHLEY_MODEL = 6514; static const std::string K6514_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 K6514_VOLT_rangeStr[]= {"2","20","200"}; static const std::string K6514_OHM_rangeStr[] = {"2E3","2E4","2E5","2E6","2E7","2E8","2E9","2E10","2E11"}; -static const std::string K6514_COU_rangeStr[] = {"2E-7","2E-6","2E-5","2E-4"}; +static const std::string K6514_COU_rangeStr[] = {"2E-8","2E-7","2E-6","2E-5"}; /* * Max Index Range value for a K_6514 */ diff --git a/src/Keithley_6517.cpp b/src/Keithley_6517.cpp new file mode 100644 index 0000000..8701639 --- /dev/null +++ b/src/Keithley_6517.cpp @@ -0,0 +1,319 @@ +// ============================================================================ +// +// = 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; +} diff --git a/src/Makefile.linux b/src/Makefile.linux index e526e8d..026801d 100644 --- a/src/Makefile.linux +++ b/src/Makefile.linux @@ -1,25 +1,28 @@ #============================================================================= # -# file : Makefile.h +# file : Makefile.h # # description : Makefile for DeviceServer # -# $Author: stephle $ +# $Author: xavela $ # -# $Revision: 1.1 $ +# $Revision: 1.2 $ # # $Log: not supported by cvs2svn $ -# Revision 1.3 2006/03/21 16:59:13 hardion +# Revision 1.1 2007/07/09 13:20:37 stephle +# initial import +# +# Revision 1.3 2006/03/21 16:59:13 hardion # * Add Software Support to Makefile process # -# Revision 1.2 2006/03/21 15:25:20 hardion +# Revision 1.2 2006/03/21 15:25:20 hardion # * Update Pogo # * fix bug in Makefile process # -# Revision 1.3 2006/03/14 14:57:34 hardion +# Revision 1.3 2006/03/14 14:57:34 hardion # * Update Makefile process to allow compilation of library # -# Revision 1.2 2006/01/05 16:51:30 hardion +# Revision 1.2 2006/01/05 16:51:30 hardion # * Update Makefile.linux and tango.opt for library use # # @@ -32,9 +35,9 @@ # - 'STATIC_LIB' for a static library (.a) # - 'DYNAMIC_LIB' for a dynamic library (.so) # - 'DEVICE' for a device server (will automatically include and link -# with Tango dependencies) +# with Tango dependencies) # - 'SIMPLE_EXE' for an executable with no dependency (for exemple the test tool -# of a library with no Tango dependencies) +# of a library with no Tango dependencies) # OUTPUT_TYPE = STATIC_LIB @@ -129,17 +132,17 @@ include $(SOLEIL_ROOT)/env/tango.opt #============================================================================= # SVC_OBJS is the list of all objects needed to make the output # -SVC_OBJS = $(OBJDIR)/CommunicationLink.o \ - $(OBJDIR)/TangoGpibLink.o \ - $(OBJDIR)/TangoSerialLink.o \ +SVC_OBJS = $(OBJDIR)/CommunicationLink.o \ + $(OBJDIR)/TangoGpibLink.o \ + $(OBJDIR)/TangoSerialLink.o \ $(OBJDIR)/ElectrometerProtocol.o \ $(OBJDIR)/KeithleyDDCProtocol.o \ $(OBJDIR)/KeithleySCPIProtocol.o \ - $(OBJDIR)/NovelecProtocol.o \ + $(OBJDIR)/NovelecProtocol.o \ $(OBJDIR)/AbstractElectrometerClass.o \ - $(OBJDIR)/Novelec_MCCE2.o \ - $(OBJDIR)/N_PhotoVoltaique.o \ - $(OBJDIR)/N_PhotoConducteur.o \ + $(OBJDIR)/Novelec_MCCE2.o \ + $(OBJDIR)/N_PhotoVoltaique.o \ + $(OBJDIR)/N_PhotoConducteur.o \ $(OBJDIR)/Keithley_485.o \ $(OBJDIR)/Keithley_486.o \ $(OBJDIR)/Keithley_487.o \ @@ -148,6 +151,7 @@ SVC_OBJS = $(OBJDIR)/CommunicationLink.o \ $(OBJDIR)/Keithley_6485.o \ $(OBJDIR)/Keithley_6487.o \ $(OBJDIR)/Keithley_6514.o \ + $(OBJDIR)/Keithley_6517.o \ $(OBJDIR)/ElectrometerException.o # diff --git a/src/Makefile.vc b/src/Makefile.vc index bc34104..a398570 100644 --- a/src/Makefile.vc +++ b/src/Makefile.vc @@ -50,6 +50,7 @@ LISTEOBJ = \ $(OBJDIR)\Keithley_6485.OBJ \ $(OBJDIR)\Keithley_6487.OBJ \ $(OBJDIR)\Keithley_6514.OBJ \ + $(OBJDIR)\Keithley_6517.OBJ \ $(OBJDIR)\ElectrometerException.OBJ -- GitLab