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