From 2d86ff79f02b860ce92b3e09f7dc305f17a95b3a Mon Sep 17 00:00:00 2001
From: ELATTAOUI <xavier.elattaoui@synchrotron-soleil.fr>
Date: Tue, 13 Feb 2024 09:55:35 +0100
Subject: [PATCH] Jira CTRLDESK-31034 done.

---
 include/AbstractElectrometerClass.h |   9 +-
 include/ElectrometerProtocol.h      |   7 +-
 include/KeithleySCPIProtocol.h      |   1 +
 include/Keithley_485.h              |   2 +
 include/Keithley_486.h              |   2 +
 include/Keithley_487.h              |   2 +
 include/Keithley_617.h              |   2 +
 include/Keithley_6485.h             |   2 +
 include/Keithley_6487.h             |   2 +
 include/Keithley_6512.h             |   2 +
 include/Keithley_6514.h             |   2 +
 include/Keithley_6517.h             |   6 +-
 pom.xml                             |   2 +-
 src/AbstractElectrometerClass.cpp   |  18 +++-
 src/ElectrometerProtocol.cpp        |  26 ++++-
 src/KeithleySCPIProtocol.cpp        |  29 ++++++
 src/Keithley_485.cpp                |  30 +++++-
 src/Keithley_486.cpp                |  30 +++++-
 src/Keithley_487.cpp                |  30 +++++-
 src/Keithley_617.cpp                |  86 +++++++++++++++--
 src/Keithley_6485.cpp               |  30 +++++-
 src/Keithley_6487.cpp               |  30 +++++-
 src/Keithley_6512.cpp               |  84 +++++++++++++++-
 src/Keithley_6514.cpp               |  87 ++++++++++++++++-
 src/Keithley_6517.cpp               | 142 ++++++++++++++++++++++------
 25 files changed, 602 insertions(+), 61 deletions(-)
 mode change 100644 => 100755 pom.xml

diff --git a/include/AbstractElectrometerClass.h b/include/AbstractElectrometerClass.h
index 44005f6..a1d68dd 100644
--- a/include/AbstractElectrometerClass.h
+++ b/include/AbstractElectrometerClass.h
@@ -170,13 +170,15 @@ public:
 	*  \brief Keithley Electrometer methods
 	*/
 	void autoRange_on		  (void);
+	std::string is_autoRange_on(void);
+	
 	void zero_check_on		(void);
 	void zero_check_off		(void);
 	void zero_correct_on	(void);
 	void zero_correct_off	(void);
+	virtual void autoRange_off		(void);
 	virtual void auto_zero_on		  (void);
 	virtual void auto_zero_off		(void);
-	virtual void autoRange_off		(void);
 	virtual void setAmperMeterMode(void);
 	virtual void setVoltMeterMode	(void);
 	virtual void setOhmMeterMode	(void);
@@ -216,6 +218,7 @@ public:
 	virtual void set_integrationTime	(double);
 	virtual short get_buffer_size			(void);
 	virtual short get_triggerMode			(void) { return _trigMod;}
+// 	virtual void set_range(std::size_t idx) = 0;
 
 	/**
 	*  \brief  VSource operations (only for K_6517)
@@ -246,7 +249,8 @@ public:
 	virtual std::string get_ElectroMeterFrequency (void);
 	virtual std::string get_ElectroMeterGain      (void);
 	virtual unsigned short get_ElectroChannel	    (void);
-	virtual void set_ElectroMeterRange			(std::string rang);
+    virtual void set_ElectroMeterRange          (std::string rangeStr);
+    virtual void set_ElectroMeterRange          (std::size_t rangeIdx);
 	virtual void set_ElectroMeterPolarity		(std::string pola);
 	virtual void set_ElectroMeterFrequency	(std::string freq);
 	virtual void set_ElectroMeterGain			  (std::string gain);
@@ -268,6 +272,7 @@ public:
 	*/
 	virtual std::string get_ElectroMeterMode	(void);
 	virtual std::string get_ElectroMeterRange	(void);
+    virtual std::vector<std::string> ranges_list(void)=0;
 
 
 protected :
diff --git a/include/ElectrometerProtocol.h b/include/ElectrometerProtocol.h
index 6935716..278d1b9 100644
--- a/include/ElectrometerProtocol.h
+++ b/include/ElectrometerProtocol.h
@@ -132,7 +132,8 @@ public:
 	/**
 	*  \brief Common Electrometer Functions.
 	*/
-	virtual void set_range (std::string val)= 0;
+    virtual void set_range (std::string val)= 0;
+    virtual void set_range (std::size_t val);
 	virtual void reset			(void) = 0; 
 	virtual void local			(void); 
 	virtual void remote			(void); 
@@ -142,7 +143,7 @@ public:
 	*/
 	virtual std::string get_value(void)		= 0;
 	virtual std::string get_mode (void)		= 0;
-	virtual std::string get_range(void)		= 0;
+    virtual std::string get_range(void)     = 0;
 	virtual std::vector<double> get_integratedValue		(void);
 	virtual std::vector<double> get_fetchValue		    (void);
 	virtual bool SRQLineState             (void); //- used to know if the integration cycle is done! 
@@ -187,7 +188,7 @@ public:
 	virtual void setCoulombMeterMode(void);
 	virtual void autoRange_on		  (void);
 	virtual void autoRange_off		(void);
-	
+	virtual std::string is_autoRange_on  (void);
 	virtual void zero_check_on		(void);
 	virtual void zero_check_off		(void);
 	virtual void zero_correct_on	(void);
diff --git a/include/KeithleySCPIProtocol.h b/include/KeithleySCPIProtocol.h
index 80e0b50..de32810 100644
--- a/include/KeithleySCPIProtocol.h
+++ b/include/KeithleySCPIProtocol.h
@@ -63,6 +63,7 @@ public:
 	void set_range			  (std::string value) ;
 	void autoRange_on		  (void);
 	void autoRange_off		(void);
+	std::string is_autoRange_on(void);
 
 	void zero_check_on		(void);
 	void zero_check_off		(void);
diff --git a/include/Keithley_485.h b/include/Keithley_485.h
index 90ce6bb..c32b4e2 100644
--- a/include/Keithley_485.h
+++ b/include/Keithley_485.h
@@ -62,6 +62,8 @@ public:
 	*  \brief getter(s) & setter(s)	
 	*/
 	std::string get_ElectroMeterRange(void);
+    std::vector<std::string> ranges_list(void);
+    void set_ElectroMeterRange (std::size_t rangeIdx);
 	
 	/**
 	*  \brief Electrometer Status.
diff --git a/include/Keithley_486.h b/include/Keithley_486.h
index 1f74840..9b5bd81 100644
--- a/include/Keithley_486.h
+++ b/include/Keithley_486.h
@@ -67,6 +67,8 @@ public:
 	*  \brief getter(s) & setter(s)	
 	*/
 	std::string get_ElectroMeterRange(void);
+    std::vector<std::string> ranges_list(void);
+    void set_ElectroMeterRange (std::size_t rangeIdx);
 	
 	/**
 	*  \brief Electrometer status.
diff --git a/include/Keithley_487.h b/include/Keithley_487.h
index 33baa33..84f5ce5 100644
--- a/include/Keithley_487.h
+++ b/include/Keithley_487.h
@@ -68,6 +68,8 @@ public:
 	*/
 	std::string get_ElectroMeterMode(void);
 	std::string get_ElectroMeterRange(void);
+    std::vector<std::string> ranges_list(void);
+    void set_ElectroMeterRange (std::size_t rangeIdx);
 	
 	/**
 	*  \brief The integration time (sec).
diff --git a/include/Keithley_617.h b/include/Keithley_617.h
index d90bf9f..7fbd83b 100644
--- a/include/Keithley_617.h
+++ b/include/Keithley_617.h
@@ -70,6 +70,8 @@ public:
 	*/
 	std::string get_ElectroMeterMode (void);
 	std::string get_ElectroMeterRange(void);
+    std::vector<std::string> ranges_list(void);
+    void set_ElectroMeterRange (std::size_t rangeIdx);
 
   /**
 	*  \brief Electrometer status.
diff --git a/include/Keithley_6485.h b/include/Keithley_6485.h
index b32b9d6..2f6ab42 100644
--- a/include/Keithley_6485.h
+++ b/include/Keithley_6485.h
@@ -66,6 +66,8 @@ public:
 	void range_up   (void);
 	void range_down (void);
   std::string get_ElectroMeterRange (void);
+    std::vector<std::string> ranges_list(void);
+    void set_ElectroMeterRange (std::size_t rangeIdx);
 
 	/**
 	*  \brief Methods to configure the integration mode.
diff --git a/include/Keithley_6487.h b/include/Keithley_6487.h
index 3823bd6..cfb6272 100644
--- a/include/Keithley_6487.h
+++ b/include/Keithley_6487.h
@@ -59,6 +59,8 @@ public:
 	void range_up (void);
 	void range_down (void);
   std::string get_ElectroMeterRange (void);
+    std::vector<std::string> ranges_list(void);
+    void set_ElectroMeterRange (std::size_t rangeIdx);
 	
   std::vector<double> get_integratedValue (void);
 	std::vector<double> get_fetchValue      (void);
diff --git a/include/Keithley_6512.h b/include/Keithley_6512.h
index e834aa2..8117941 100644
--- a/include/Keithley_6512.h
+++ b/include/Keithley_6512.h
@@ -70,6 +70,8 @@ public:
 	*/
 	std::string get_ElectroMeterMode (void);
 	std::string get_ElectroMeterRange(void);
+    std::vector<std::string> ranges_list(void);
+    void set_ElectroMeterRange (std::size_t rangeIdx);
 	
 	/**
 	*  \brief Electrometer status.
diff --git a/include/Keithley_6514.h b/include/Keithley_6514.h
index 14384f9..3f3c32e 100644
--- a/include/Keithley_6514.h
+++ b/include/Keithley_6514.h
@@ -59,6 +59,8 @@ public:
 	void range_up (void);
 	void range_down (void);
   std::string get_ElectroMeterRange (void) ;
+    std::vector<std::string> ranges_list(void);
+    void set_ElectroMeterRange (std::size_t rangeIdx);
 	
 	std::vector<double> get_integratedValue (void);
 	std::vector<double> get_fetchValue      (void);
diff --git a/include/Keithley_6517.h b/include/Keithley_6517.h
index 7eb5f62..b2acfc5 100644
--- a/include/Keithley_6517.h
+++ b/include/Keithley_6517.h
@@ -45,7 +45,7 @@ public:
 	/**
 	*  \brief protocole initailisation.
 	*/
-  bool init_protocol (void);
+    bool init_protocol (void);
 
 	/**
 	*  \brief Functions to save/restore specifics configuration.
@@ -58,7 +58,9 @@ public:
 	*/
 	void range_up   (void);
 	void range_down (void);
-  std::string get_ElectroMeterRange (void);
+    std::string get_ElectroMeterRange (void);
+    std::vector<std::string> ranges_list(void);
+    void set_ElectroMeterRange (std::size_t rangeIdx);
 	
 	std::vector<double> get_integratedValue (void);
 	std::vector<double> get_fetchValue      (void);
diff --git a/pom.xml b/pom.xml
old mode 100644
new mode 100755
index 9b3dfec..0e945cd
--- a/pom.xml
+++ b/pom.xml
@@ -8,7 +8,7 @@
    </parent>
    <groupId>fr.soleil.lib</groupId>
    <artifactId>Electrometers-${aol}-${library}-${mode}</artifactId>
-   <version>2.5.29</version>
+   <version>2.6.0</version>
    <packaging>nar</packaging>
    <name>Electrometers library</name>
    <description>Electrometers library</description>
diff --git a/src/AbstractElectrometerClass.cpp b/src/AbstractElectrometerClass.cpp
index 6695583..f1e4c0e 100644
--- a/src/AbstractElectrometerClass.cpp
+++ b/src/AbstractElectrometerClass.cpp
@@ -244,6 +244,14 @@ void AbstractElectrometerClass::autoRange_off (void)
 	_electrometerProtocol->autoRange_off( );
 }
 
+// ============================================================================
+// AbstractElectrometerClass::is_autoRange_on
+// ============================================================================
+std::string AbstractElectrometerClass::is_autoRange_on (void)
+{
+	return _electrometerProtocol->is_autoRange_on( );
+}
+
 // ============================================================================
 // AbstractElectrometerClass::auto_zero_on
 // ============================================================================
@@ -728,12 +736,20 @@ std::string AbstractElectrometerClass::get_ElectroMeterGain (void)
 	return _electrometerProtocol->get_gain( );
 }
 
+// ============================================================================
+// AbstractElectrometerClass::set_ElectroMeterRange
+// ============================================================================
+void AbstractElectrometerClass::set_ElectroMeterRange (std::size_t rangeIdx)
+{
+    _electrometerProtocol->set_range(rangeIdx);
+}
+
 // ============================================================================
 // AbstractElectrometerClass::set_ElectroMeterRange
 // ============================================================================
 void AbstractElectrometerClass::set_ElectroMeterRange (std::string rang)
 {
-	_electrometerProtocol->set_range(rang);
+    _electrometerProtocol->set_range(rang);
 }
 
 // ============================================================================
diff --git a/src/ElectrometerProtocol.cpp b/src/ElectrometerProtocol.cpp
index 07dd9ef..dca956f 100644
--- a/src/ElectrometerProtocol.cpp
+++ b/src/ElectrometerProtocol.cpp
@@ -66,9 +66,19 @@ void ElectrometerProtocol::remote (void)
 // ============================================================================
 std::vector<double> ElectrometerProtocol::get_integratedValue (void) 
 {
-	throw electrometer::ElectrometerException("COMMAND_NOT_SUPPORTED", 
-											"This Electrometer does not support this command.",
-											"ElectrometerProtocol::get_integratedValue( ).");
+    throw electrometer::ElectrometerException("COMMAND_NOT_SUPPORTED", 
+                                            "This Electrometer does not support this command.",
+                                            "ElectrometerProtocol::get_integratedValue( ).");
+}
+
+// ============================================================================
+// ElectrometerProtocol::set_range
+// ============================================================================
+void ElectrometerProtocol::set_range (std::size_t) 
+{
+    throw electrometer::ElectrometerException("COMMAND_NOT_SUPPORTED", 
+                                            "This Electrometer does not support this command.",
+                                            "ElectrometerProtocol::set_range( ).");
 }
 
 // ============================================================================
@@ -241,6 +251,16 @@ void ElectrometerProtocol::autoRange_off (void)
 											"ElectrometerProtocol::autoRange_off( ).");
 }
 
+// ============================================================================
+// ElectrometerProtocol::is_autoRange_on
+// ============================================================================
+std::string ElectrometerProtocol::is_autoRange_on (void) 
+{
+	throw electrometer::ElectrometerException("COMMAND_NOT_SUPPORTED", 
+											"Novelec does not support this command.",
+											"ElectrometerProtocol::is_autoRange_on( ).");
+}
+
 
 // ============================================================================
 // ElectrometerProtocol::zero_check_on
diff --git a/src/KeithleySCPIProtocol.cpp b/src/KeithleySCPIProtocol.cpp
index ef71f58..486abea 100644
--- a/src/KeithleySCPIProtocol.cpp
+++ b/src/KeithleySCPIProtocol.cpp
@@ -314,6 +314,35 @@ std::string tmpMode;
 
 }
 
+// ============================================================================
+// KeithleySCPIProtocol::is_autoRange_on
+// ============================================================================
+std::string KeithleySCPIProtocol::is_autoRange_on (void)
+{
+std::string cmd_to_send("");
+std::string tmpMode;
+
+	if( !this->_communication_link )
+	{
+		throw electrometer::ElectrometerException(
+												"INITIALIZATION_ERROR",
+												"No communication protocol available.",
+												"KeithleySCPIProtocol::is_autoRange_on()");
+	}
+
+	//- get electrometer mode
+	tmpMode = get_mode( );
+
+	//- erase bad caracters
+	tmpMode.erase(tmpMode.find("\n") );
+
+	//- send command
+	cmd_to_send = tmpMode + ":RANGe:AUTO?";
+	
+	return _communication_link->write_read(cmd_to_send);
+
+}
+
 // ============================================================================
 // KeithleySCPIProtocol::auto_zero_on
 // ============================================================================
diff --git a/src/Keithley_485.cpp b/src/Keithley_485.cpp
index 5a514d6..f972ddf 100644
--- a/src/Keithley_485.cpp
+++ b/src/Keithley_485.cpp
@@ -25,7 +25,7 @@
 /*
 * Valid Range values for a K_485
 */
-static const std::string K485_rangeValue[] = {"AUTO ON","2E-9","2E-8","2E-7","2E-6","2E-5","2E-4","2E-3"};
+static const std::vector<std::string> K485_rangeValue {"AUTO ON","2E-9","2E-8","2E-7","2E-6","2E-5","2E-4","2E-3"};
 
 /*
 * Range limit
@@ -154,6 +154,34 @@ std::string Keithley_485::get_ElectroMeterRange (void)
 	return _rangeStr;
 }
 
+// ============================================================================
+// Keithley_485::ranges_list
+// ============================================================================
+std::vector<std::string> Keithley_485::ranges_list (void)
+{
+  return K485_rangeValue;
+}
+
+// ============================================================================
+// Keithley_485::set_ElectroMeterRange
+// ============================================================================
+void Keithley_485::set_ElectroMeterRange (std::size_t rangeIdx)
+{
+  std::string range_str("");
+  std::size_t range_limit = 0;
+  
+  if ( rangeIdx >= K485_rangeLimit )
+  {
+    throw electrometer::ElectrometerException("OUT_OF_RANGE",
+                                              "Range index is above the max range value.",
+                                              "Keithley_485::set_ElectroMeterRange( ).");
+  }
+  
+  range_str = K485_rangeValue[rangeIdx];
+  
+  _electrometerProtocol->set_range(range_str);
+}
+
 // ============================================================================
 // Keithley_485::set_triggerMode
 // ============================================================================
diff --git a/src/Keithley_486.cpp b/src/Keithley_486.cpp
index ba2dcbe..a8cb2db 100644
--- a/src/Keithley_486.cpp
+++ b/src/Keithley_486.cpp
@@ -26,7 +26,7 @@
 /*
 * Valid Range values for a K_486
 */
-static const std::string K486_rangeValue[] = {"AUTO ON","2E-9","2E-8","2E-7","2E-6","2E-5","2E-4","2E-3", "AUTO OFF"};
+static const std::vector<std::string> K486_rangeValue {"AUTO ON","2E-9","2E-8","2E-7","2E-6","2E-5","2E-4","2E-3", "AUTO OFF"};
 /*
 * Range limit : no range for values R8 & R9 (R10 = AUTORANGE OFF)
 */
@@ -173,6 +173,34 @@ std::string Keithley_486::get_ElectroMeterRange (void)
 	return _rangeStr;
 }
 
+// ============================================================================
+// Keithley_486::ranges_list
+// ============================================================================
+std::vector<std::string> Keithley_486::ranges_list (void)
+{
+  return K486_rangeValue;
+}
+
+// ============================================================================
+// Keithley_486::set_ElectroMeterRange
+// ============================================================================
+void Keithley_486::set_ElectroMeterRange (std::size_t rangeIdx)
+{
+  std::string range_str("");
+  std::size_t range_limit = 0;
+  
+  if ( rangeIdx >= K486_rangeLimit)
+  {
+    throw electrometer::ElectrometerException("OUT_OF_RANGE",
+                                              "Range index is above the max range value.",
+                                              "Keithley_486::set_ElectroMeterRange( ).");
+  }
+  
+  range_str = K486_rangeValue[rangeIdx];
+  
+  _electrometerProtocol->set_range(range_str);
+}
+
 // ============================================================================
 // Keithley_486::set_buffer_size()
 // ============================================================================
diff --git a/src/Keithley_487.cpp b/src/Keithley_487.cpp
index fd0f17f..8a78ead 100644
--- a/src/Keithley_487.cpp
+++ b/src/Keithley_487.cpp
@@ -26,7 +26,7 @@
 /*
 * Valid Range values for a K_487
 */
-static const std::string K487_rangeValue[] = {"AUTO ON","2E-9","2E-8","2E-7","2E-6","2E-5","2E-4","2E-3", "AUTO OFF"};
+static const std::vector<std::string> K487_rangeValue {"AUTO ON","2E-9","2E-8","2E-7","2E-6","2E-5","2E-4","2E-3", "AUTO OFF"};
 /*
 * Range limit : no range for values R8 & R9 (R10 = AUTORANGE OFF)
 */
@@ -172,6 +172,34 @@ std::string Keithley_487::get_ElectroMeterRange (void)
 	return _rangeStr;
 }
 
+// ============================================================================
+// Keithley_487::ranges_list
+// ============================================================================
+std::vector<std::string> Keithley_487::ranges_list (void)
+{
+  return K487_rangeValue;
+}
+
+// ============================================================================
+// Keithley_487::set_ElectroMeterRange
+// ============================================================================
+void Keithley_487::set_ElectroMeterRange (std::size_t rangeIdx)
+{
+  std::string range_str("");
+  std::size_t range_limit = 0;
+  
+  if ( rangeIdx >= K487_rangeLimit )
+  {
+    throw electrometer::ElectrometerException("OUT_OF_RANGE",
+                                              "Range index is above the max range value.",
+                                              "Keithley_487::set_ElectroMeterRange( ).");
+  }
+  
+  range_str = K487_rangeValue[rangeIdx];
+  
+  _electrometerProtocol->set_range(range_str);
+}
+
 // ============================================================================
 // Keithley_487::set_buffer_size()
 // ============================================================================
diff --git a/src/Keithley_617.cpp b/src/Keithley_617.cpp
index dc70d18..1718830 100644
--- a/src/Keithley_617.cpp
+++ b/src/Keithley_617.cpp
@@ -25,12 +25,12 @@
 /*
 * Valid Range values for a K_617
 */
-static const std::string K617_AmpRangeValue[] = {"AUTO ON","2E-12","2E-11","2E-10","2E-9","2E-8","2E-7","2E-6","2E-5","2E-4","2E-3","2E-2", "AUTO OFF"};
-static const std::string K617_VoltRangeValue[]= {"AUTO ON","2E-1","2","20","200","200","200","200","200","200","200","200", "AUTO OFF"};
-static const std::string K617_OhmRangeValue[] = {"AUTO ON","2E3","2E4","2E5","2E6","2E7","2E8","2E9","2E10","2E11","2E11","2E11", "AUTO OFF"};
-static const std::string K617_CouRangeValue[] = {"AUTO ON","2E-10","2E-9","2E-10","2E-10","2E-10","2E-10","2E-10","2E-10","2E-10","2E-10","2E-10", "AUTO OFF"};
-static const std::string K617_XfdbRangeValue[]= {"AUTO ON","2E-1","2","20","20","20","20","20","20","20","20","20", "AUTO OFF"};
-static const std::string K617_VonIRangeValue[]= {"AUTO ON","200E12","20E12","2E12","200E9","20E9","2E9","200E6","20E6","2E6","200E3","200E3", "AUTO OFF"};
+static const std::vector<std::string> K617_AmpRangeValue {"AUTO ON","2E-12","2E-11","2E-10","2E-9","2E-8","2E-7","2E-6","2E-5","2E-4","2E-3","2E-2", "AUTO OFF"};
+static const std::vector<std::string> K617_VoltRangeValue {"AUTO ON","2E-1","2","20","200","200","200","200","200","200","200","200", "AUTO OFF"};
+static const std::vector<std::string> K617_OhmRangeValue {"AUTO ON","2E3","2E4","2E5","2E6","2E7","2E8","2E9","2E10","2E11","2E11","2E11", "AUTO OFF"};
+static const std::vector<std::string> K617_CouRangeValue {"AUTO ON","2E-10","2E-9","2E-10","2E-10","2E-10","2E-10","2E-10","2E-10","2E-10","2E-10","2E-10", "AUTO OFF"};
+static const std::vector<std::string> K617_XfdbRangeValue {"AUTO ON","2E-1","2","20","20","20","20","20","20","20","20","20", "AUTO OFF"};
+static const std::vector<std::string> K617_VonIRangeValue {"AUTO ON","200E12","20E12","2E12","200E9","20E9","2E9","200E6","20E6","2E6","200E3","200E3", "AUTO OFF"};
 /*
 * Range limit
 */
@@ -170,6 +170,80 @@ std::string Keithley_617::get_ElectroMeterRange (void)
   return _rangeStr;
 }
 
+// ============================================================================
+// Keithley_617::ranges_list
+// ============================================================================
+std::vector<std::string> Keithley_617::ranges_list (void)
+{
+  std::vector<std::string> vrangeslist;
+  
+  //- get device mode
+  _mode = AbstractElectrometerClass::get_ElectroMeterMode();
+
+  //- check range validity
+  if(_mode.find("CURR") != std::string::npos)
+  {
+    vrangeslist = K617_AmpRangeValue;
+  }
+  else if (_mode.find("VOLT") != std::string::npos)
+  {
+    vrangeslist = K617_VoltRangeValue;
+  }
+  else if (_mode.find("RES") != std::string::npos)
+  {
+    vrangeslist = K617_OhmRangeValue;
+  }
+  else if (_mode.find("CHAR") != std::string::npos)
+  {
+    vrangeslist = K617_CouRangeValue;
+  }
+  else
+      throw electrometer::ElectrometerException("UNKNOWN_MODE",
+                                              "Unable to find the electrometer mode used.",
+                                              "Keithley_617::ranges_list( ).");
+
+  return vrangeslist;
+}
+
+// ============================================================================
+// Keithley_617::set_ElectroMeterRange
+// ============================================================================
+void Keithley_617::set_ElectroMeterRange (std::size_t rangeIdx)
+{
+  std::string range_str("");
+  std::size_t range_limit = 0;
+  
+  //- get device mode
+  _mode = AbstractElectrometerClass::get_ElectroMeterMode();
+
+  if ( rangeIdx >= K617_rangeLimit)
+  {
+    throw electrometer::ElectrometerException("OUT_OF_RANGE",
+                                              "Range index is above the max range value.",
+                                              "Keithley_617::set_ElectroMeterRange( ).");
+  }
+
+  //- check range validity
+  if(_mode.find("CURR") != std::string::npos)
+  {
+    range_str = K617_AmpRangeValue[rangeIdx];
+  }
+  else if (_mode.find("VOLT") != std::string::npos)
+  {
+    range_str = K617_VoltRangeValue[rangeIdx];
+  }
+  else if (_mode.find("RES") != std::string::npos)
+  {
+    range_str = K617_OhmRangeValue[rangeIdx];
+  }
+  else if (_mode.find("CHAR") != std::string::npos)
+  {
+    range_str = K617_CouRangeValue[rangeIdx];
+  }
+  
+  _electrometerProtocol->set_range(range_str);
+}
+
 // ============================================================================
 // Keithley_617::set_buffer_size()
 // ============================================================================
diff --git a/src/Keithley_6485.cpp b/src/Keithley_6485.cpp
index 8e020df..86e8b10 100644
--- a/src/Keithley_6485.cpp
+++ b/src/Keithley_6485.cpp
@@ -24,7 +24,7 @@
 /*
 * 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"};
+static const std::vector<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
 */
@@ -191,6 +191,34 @@ std::string Keithley_6485::get_ElectroMeterRange (void)
   return range_str;
 }
 
+// ============================================================================
+// Keithley_6485::ranges_list
+// ============================================================================
+std::vector<std::string> Keithley_6485::ranges_list (void)
+{
+  return K6485_rangeValue;
+}
+
+// ============================================================================
+// Keithley_6485::set_ElectroMeterRange
+// ============================================================================
+void Keithley_6485::set_ElectroMeterRange (std::size_t rangeIdx)
+{
+  std::string range_str("");
+  std::size_t range_limit = 0;
+  
+  if ( rangeIdx >= K6485_rangeLimit )
+  {
+    throw electrometer::ElectrometerException("OUT_OF_RANGE",
+                                              "Range index is above the max range value.",
+                                              "Keithley_6485::set_ElectroMeterRange( ).");
+  }
+  
+  range_str = K6485_rangeValue[rangeIdx];
+  
+  _electrometerProtocol->set_range(range_str);
+}
+
 // ============================================================================
 // Keithley_6485::get_integratedValue
 // ============================================================================
diff --git a/src/Keithley_6487.cpp b/src/Keithley_6487.cpp
index e1709ef..a56009c 100644
--- a/src/Keithley_6487.cpp
+++ b/src/Keithley_6487.cpp
@@ -24,7 +24,7 @@
 /*
 * Valid Range values for a K_6487
 */
-static const std::string K6487_rangeValue[8] = {"2E-2","2E-3","2E-4","2E-5","2E-6","2E-7","2E-8","2E-9"};
+static const std::vector<std::string> K6487_rangeValue {"2E-2","2E-3","2E-4","2E-5","2E-6","2E-7","2E-8","2E-9"};
 /*
 * Max Index Range value for a K_6487
 */
@@ -151,6 +151,34 @@ std::stringstream cmd_to_send;
 	_electrometerProtocol->set_range(cmd_to_send.str());
 }
 
+// ============================================================================
+// Keithley_6487::ranges_list
+// ============================================================================
+std::vector<std::string> Keithley_6487::ranges_list (void)
+{
+  return K6487_rangeValue;
+}
+
+// ============================================================================
+// Keithley_6487::set_ElectroMeterRange
+// ============================================================================
+void Keithley_6487::set_ElectroMeterRange (std::size_t rangeIdx)
+{
+  std::string range_str("");
+  std::size_t range_limit = 0;
+  
+  if ( rangeIdx >= K6487_rangeLimit)
+  {
+    throw electrometer::ElectrometerException("OUT_OF_RANGE",
+                                              "Range index is above the max range value.",
+                                              "Keithley_6487::set_ElectroMeterRange( ).");
+  }
+  
+  range_str = K6487_rangeValue[rangeIdx];
+  
+  _electrometerProtocol->set_range(range_str);
+}
+
 // ============================================================================
 // Keithley_6487::setAmperMeterMode
 // ============================================================================
diff --git a/src/Keithley_6512.cpp b/src/Keithley_6512.cpp
index 8919229..f8aef9c 100644
--- a/src/Keithley_6512.cpp
+++ b/src/Keithley_6512.cpp
@@ -25,11 +25,11 @@
 /*
 * Valid Range values for a K_6512
 */
-static const std::string K6512_AmpRangeValue[] = {"AUTO ON","2E-12","2E-11","2E-10","2E-9","2E-8","2E-7","2E-6","2E-5","2E-4","2E-3","2E-2", "AUTO OFF"};
-static const std::string K6512_VoltRangeValue[]= {"AUTO ON","2E-1","2","20","200","200","200","200","200","200","200","200", "AUTO OFF"};
-static const std::string K6512_OhmRangeValue[] = {"AUTO ON","2E3","2E4","2E5","2E6","2E7","2E8","2E9","2E10","2E11","2E11","2E11", "AUTO OFF"};
-static const std::string K6512_CouRangeValue[] = {"AUTO ON","2E-10","2E-9","2E-10","2E-10","2E-10","2E-10","2E-10","2E-10","2E-10","2E-10","2E-10", "AUTO OFF"};
-static const std::string K6512_XfdbRangeValue[]= {"AUTO ON","2E-1","2","20","20","20","20","20","20","20","20","20", "AUTO OFF"};
+static const std::vector<std::string> K6512_AmpRangeValue {"AUTO ON","2E-12","2E-11","2E-10","2E-9","2E-8","2E-7","2E-6","2E-5","2E-4","2E-3","2E-2", "AUTO OFF"};
+static const std::vector<std::string> K6512_VoltRangeValue {"AUTO ON","2E-1","2","20","200","200","200","200","200","200","200","200", "AUTO OFF"};
+static const std::vector<std::string> K6512_OhmRangeValue {"AUTO ON","2E3","2E4","2E5","2E6","2E7","2E8","2E9","2E10","2E11","2E11","2E11", "AUTO OFF"};
+static const std::vector<std::string> K6512_CouRangeValue {"AUTO ON","2E-10","2E-9","2E-10","2E-10","2E-10","2E-10","2E-10","2E-10","2E-10","2E-10","2E-10", "AUTO OFF"};
+static const std::vector<std::string> K6512_XfdbRangeValue {"AUTO ON","2E-1","2","20","20","20","20","20","20","20","20","20", "AUTO OFF"};
 /*
 * Range limit
 */
@@ -169,6 +169,80 @@ std::string Keithley_6512::get_ElectroMeterRange (void)
 	return _rangeStr;
 }
 
+// ============================================================================
+// Keithley_6512::ranges_list
+// ============================================================================
+std::vector<std::string> Keithley_6512::ranges_list (void)
+{
+  std::vector<std::string> vrangeslist;
+  
+  //- get device mode
+  _mode = AbstractElectrometerClass::get_ElectroMeterMode();
+
+  //- check range validity
+  if(_mode.find("CURR") != std::string::npos)
+  {
+    vrangeslist = K6512_AmpRangeValue;
+  }
+  else if (_mode.find("VOLT") != std::string::npos)
+  {
+    vrangeslist = K6512_VoltRangeValue;
+  }
+  else if (_mode.find("RES") != std::string::npos)
+  {
+    vrangeslist = K6512_OhmRangeValue;
+  }
+  else if (_mode.find("CHAR") != std::string::npos)
+  {
+    vrangeslist = K6512_CouRangeValue;
+  }
+  else
+      throw electrometer::ElectrometerException("UNKNOWN_MODE",
+                                              "Unable to find the electrometer mode used.",
+                                              "Keithley_6512::ranges_list( ).");
+
+  return vrangeslist;
+}
+
+// ============================================================================
+// Keithley_6512::set_ElectroMeterRange
+// ============================================================================
+void Keithley_6512::set_ElectroMeterRange (std::size_t rangeIdx)
+{
+  std::string range_str("");
+  std::size_t range_limit = 0;
+  
+  //- get device mode
+  _mode = AbstractElectrometerClass::get_ElectroMeterMode();
+
+  if ( rangeIdx >= K6512_rangeLimit )
+  {
+    throw electrometer::ElectrometerException("OUT_OF_RANGE",
+                                              "Range index is above the max range value.",
+                                              "Keithley_6512::set_ElectroMeterRange( ).");
+  }
+  
+  //- check range validity
+  if(_mode.find("CURR") != std::string::npos)
+  {
+    range_str = K6512_AmpRangeValue[rangeIdx];
+  }
+  else if (_mode.find("VOLT") != std::string::npos)
+  {
+    range_str = K6512_VoltRangeValue[rangeIdx];
+  }
+  else if (_mode.find("RES") != std::string::npos)
+  {
+    range_str = K6512_OhmRangeValue[rangeIdx];
+  }
+  else if (_mode.find("CHAR") != std::string::npos)
+  {
+    range_str = K6512_CouRangeValue[rangeIdx];
+  }
+  
+  _electrometerProtocol->set_range(range_str);
+}
+
 // ============================================================================
 // Keithley_6512::set_buffer_size()
 // ============================================================================
diff --git a/src/Keithley_6514.cpp b/src/Keithley_6514.cpp
index 1d1c32d..a2427d1 100644
--- a/src/Keithley_6514.cpp
+++ b/src/Keithley_6514.cpp
@@ -25,10 +25,10 @@
 /*
 * Valid Range values for a K_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-8","2E-7","2E-6","2E-5"};
+static const std::vector<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::vector<std::string> K6514_VOLT_rangeStr {"2","20","200"};
+static const std::vector<std::string> K6514_OHM_rangeStr {"2E3","2E4","2E5","2E6","2E7","2E8","2E9","2E10","2E11"};
+static const std::vector<std::string> K6514_COU_rangeStr {"2E-8","2E-7","2E-6","2E-5"};
 /*
 * Max Index Range value for a K_6514
 */
@@ -222,6 +222,85 @@ std::stringstream cmd_to_send;
 	_electrometerProtocol->set_range(cmd_to_send.str());
 }
 
+// ============================================================================
+// Keithley_6514::ranges_list
+// ============================================================================
+std::vector<std::string> Keithley_6514::ranges_list (void)
+{
+  std::vector<std::string> vrangeslist;
+  
+  //- get device mode
+  _kmode = AbstractElectrometerClass::get_ElectroMeterMode();
+
+  //- check range validity
+  if(_kmode.find("CURR") != std::string::npos)
+  {
+    vrangeslist = K6514_AMP_rangeStr;
+  }
+  else if (_kmode.find("VOLT") != std::string::npos)
+  {
+    vrangeslist = K6514_VOLT_rangeStr;
+  }
+  else if (_kmode.find("RES") != std::string::npos)
+  {
+    vrangeslist = K6514_OHM_rangeStr;
+  }
+  else if (_kmode.find("CHAR") != std::string::npos)
+  {
+    vrangeslist = K6514_COU_rangeStr;
+  }
+  else
+      throw electrometer::ElectrometerException("UNKNOWN_MODE",
+                                              "Unable to find the electrometer mode used.",
+                                              "Keithley_6514::ranges_list( ).");
+
+  return vrangeslist;
+}
+
+// ============================================================================
+// Keithley_6514::set_ElectroMeterRange
+// ============================================================================
+void Keithley_6514::set_ElectroMeterRange (std::size_t rangeIdx)
+{
+  std::string range_str("");
+  std::size_t range_limit = 0;
+  
+  //- get device mode
+  _kmode = AbstractElectrometerClass::get_ElectroMeterMode();
+
+  //- check range validity
+  if(_kmode.find("CURR") != std::string::npos)
+  {
+    if ( range_limit <= K6514_AMP_rangeLimit)
+    {
+      range_str = K6514_AMP_rangeStr[rangeIdx];
+    }
+  }
+  else if (_kmode.find("VOLT") != std::string::npos)
+  {
+    if ( range_limit = K6514_VOLT_rangeLimit )
+    {
+      range_str = K6514_VOLT_rangeStr[rangeIdx];
+    }
+  }
+  else if (_kmode.find("RES") != std::string::npos)
+  {
+    if( range_limit = K6514_OHM_rangeLimit )
+    {
+      range_str = K6514_OHM_rangeStr[rangeIdx];
+    }
+  }
+  else if (_kmode.find("CHAR") != std::string::npos)
+  {
+    if ( range_limit = K6514_COU_rangeLimit )
+    {
+      range_str = K6514_COU_rangeStr[rangeIdx];
+    }
+  }
+  
+  _electrometerProtocol->set_range(range_str);
+}
+
 // ============================================================================
 // Keithley_6514::get_integratedValue
 // ============================================================================
diff --git a/src/Keithley_6517.cpp b/src/Keithley_6517.cpp
index d65dd9a..dc5a673 100644
--- a/src/Keithley_6517.cpp
+++ b/src/Keithley_6517.cpp
@@ -24,10 +24,11 @@
 /*
 * 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"};
+//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::vector<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::vector<std::string> K6517_VOLT_rangeStr {"2","20","200"};
+static const std::vector<std::string> K6517_OHM_rangeStr {"2E14","2E13","2E12","2E11","2E10","2E9","2E8","2E7","2E6","2E5"};
+static const std::vector<std::string> K6517_COU_rangeStr {"2E-9","2E-8","2E-7","2E-6"};
 /*
 * Max Index Range value for a K_6517
 */
@@ -183,37 +184,120 @@ void Keithley_6517::range_down (void)
 
 std::stringstream cmd_to_send;
 
-	//- update range value from hardware
-	this->get_ElectroMeterRange( );
+    //- update range value from hardware
+    this->get_ElectroMeterRange( );
 
-	_range -= 1;
+    _range -= 1;
 
-	if(_range < 0)
-	{
-		_range = 0;
+    if(_range < 0)
+    {
+        _range = 0;
 
-		throw electrometer::ElectrometerException("OUT_OF_RANGE",
-												"Range down limit reached.",
-												"Keithley_6517::range_down( ).");
-	}
+        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( ).");
+    //- 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::ranges_list
+// ============================================================================
+std::vector<std::string> Keithley_6517::ranges_list (void)
+{
+  std::vector<std::string> vrangeslist;
+  std::size_t nb_ranges = 0;
+  
+  //- get device mode
+  _kmode = AbstractElectrometerClass::get_ElectroMeterMode();
+
+  //- check range validity
+  if(_kmode.find("CURR") != std::string::npos)
+  {
+    nb_ranges = K6517_AMP_rangeLimit;
+    vrangeslist = K6517_AMP_rangeStr;
+  }
+  else if (_kmode.find("VOLT") != std::string::npos)
+  {
+    nb_ranges = K6517_VOLT_rangeLimit;
+    vrangeslist = K6517_VOLT_rangeStr;
+  }
+  else if (_kmode.find("RES") != std::string::npos)
+  {
+    nb_ranges = K6517_OHM_rangeLimit;
+    vrangeslist = K6517_OHM_rangeStr;
+  }
+  else if (_kmode.find("CHAR") != std::string::npos)
+  {
+    nb_ranges = K6517_COU_rangeLimit;
+    vrangeslist = K6517_COU_rangeStr;
+  }
+  else
+      throw electrometer::ElectrometerException("UNKNOWN_MODE",
+                                              "Unable to find the electrometer mode used.",
+                                              "Keithley_6517::ranges_list( ).");
 
-	//- build and send the command
-	_electrometerProtocol->set_range(cmd_to_send.str());
+  return vrangeslist;
+}
+
+// ============================================================================
+// Keithley_6517::set_ElectroMeterRange
+// ============================================================================
+void Keithley_6517::set_ElectroMeterRange (std::size_t rangeIdx)
+{
+  std::string range_str("");
+  std::size_t range_limit = 0;
+  
+  //- get device mode
+  _kmode = AbstractElectrometerClass::get_ElectroMeterMode();
+
+  //- check range validity
+  if(_kmode.find("CURR") != std::string::npos)
+  {
+    range_limit = K6517_AMP_rangeLimit;
+    range_str = K6517_AMP_rangeStr[rangeIdx];
+  }
+  else if (_kmode.find("VOLT") != std::string::npos)
+  {
+    range_limit = K6517_VOLT_rangeLimit;
+    range_str = K6517_VOLT_rangeStr[rangeIdx];
+  }
+  else if (_kmode.find("RES") != std::string::npos)
+  {
+    range_limit = K6517_OHM_rangeLimit;
+    range_str = K6517_OHM_rangeStr[rangeIdx];
+  }
+  else if (_kmode.find("CHAR") != std::string::npos)
+  {
+    range_limit = K6517_COU_rangeLimit;
+    range_str = K6517_COU_rangeStr[rangeIdx];
+  }
+  
+  if ( rangeIdx >= range_limit )
+  {
+    throw electrometer::ElectrometerException("OUT_OF_RANGE",
+                                              "Range index is above the max range value.",
+                                              "Keithley_6517::set_ElectroMeterRange( ).");
+  }
+  
+  _electrometerProtocol->set_range(range_str);
 }
 
 // ============================================================================
-- 
GitLab