From f7fc2a3c74d4c29193cc92b5ec71f33894e54b1f Mon Sep 17 00:00:00 2001
From: Xavier Elattaoui <xavier.elattaoui@synchrotron-soleil.fr>
Date: Fri, 20 Jun 2008 14:36:49 +0000
Subject: [PATCH] xavier : - DDC status show only errors if any - added command
 to get DDC model configuration

---
 include/AbstractElectrometerClass.h |  26 +++--
 include/ElectrometerProtocol.h      |  54 +++++++----
 include/KeithleyDDCProtocol.h       |   6 ++
 include/Keithley_486.h              |   5 +
 include/Keithley_487.h              |  13 ++-
 include/Keithley_617.h              |  15 ++-
 include/Keithley_6512.h             |   9 +-
 src/AbstractElectrometerClass.cpp   |  22 ++++-
 src/ElectrometerProtocol.cpp        |  10 ++
 src/KeithleyDDCProtocol.cpp         |  24 ++++-
 src/Keithley_486.cpp                | 141 ++++++++++++++++++++++++++-
 src/Keithley_487.cpp                | 142 +++++++++++++++++++++++++++-
 src/Keithley_617.cpp                |  89 ++++++++++++++---
 src/Keithley_6512.cpp               |  80 +++++++++++++++-
 14 files changed, 577 insertions(+), 59 deletions(-)

diff --git a/include/AbstractElectrometerClass.h b/include/AbstractElectrometerClass.h
index 30c50a1..0d82073 100644
--- a/include/AbstractElectrometerClass.h
+++ b/include/AbstractElectrometerClass.h
@@ -9,9 +9,17 @@
 //
 // $Author: xavela $
 //
-// $Revision: 1.12 $
+// $Revision: 1.13 $
 //
 // $Log: not supported by cvs2svn $
+// Revision 1.12  2008/05/14 09:42:37  xavela
+// xavier :
+// - attributes management :
+// -> integrationTime, buffersize and triggerMode now well initialised
+//
+// TODO : after a Start command
+// -> declare all attributes INVALID !?
+//
 // Revision 1.11  2008/04/30 15:57:29  xavela
 // xavier :
 // 6517 model management added and tested :
@@ -162,7 +170,7 @@ public:
 	virtual void set_triggerMode			    (short);
 	virtual void set_integrationTime			(double);
 	virtual short get_buffer_size			    (void);
-  virtual short get_triggerMode			    (void) { return _trigMod;};
+	virtual short get_triggerMode			    (void) { return _trigMod;};
 
 	/**
 	*  \brief Novelec Electrometer methods
@@ -192,6 +200,12 @@ public:
 	*/
 	virtual std::string electrometer_status	(void);
 
+	/**
+	*  \brief Returns the DDC Keithley configuration
+	*			asking its "Machine Status" word (= Using "U0X" cmd) .
+	*/
+	virtual std::string get_configuration	(void);
+
 	/**
 	*  \brief Common getters and setters
 	*/
@@ -208,7 +222,7 @@ protected :
 	{
 		ON		  = 0,
 		FAULT	  = 8,
-    RUNNING = 10,
+		RUNNING = 10,
 		ALARM	  = 11,
 		UNKNOWN	= 13
 	};
@@ -223,9 +237,9 @@ protected :
 	std::string				_device_proxy_name;
 	ElectrometerProtocol*	_electrometerProtocol;
 
-  //- for internal use -> to configure the Integration mode
-  short _size;
-  short _trigMod;
+	//- for internal use -> to configure the Integration mode
+	short _size;
+	short _trigMod;
 private :
 
 public :
diff --git a/include/ElectrometerProtocol.h b/include/ElectrometerProtocol.h
index ca10570..7a005f6 100644
--- a/include/ElectrometerProtocol.h
+++ b/include/ElectrometerProtocol.h
@@ -12,9 +12,15 @@
 //
 // $Author: xavela $
 //
-// $Revision: 1.9 $
+// $Revision: 1.10 $
 //
 // $Log: not supported by cvs2svn $
+// Revision 1.9  2008/04/15 12:52:00  xavela
+// xavier :
+// - SRQ management changed :
+// * ReadStatusByteRegister method added
+// * IsSrqLineUP added
+//
 // Revision 1.8  2008/02/15 10:17:55  xavela
 // xavier :
 // - command abort added for SCPI Keithleys
@@ -116,6 +122,12 @@ public:
 	*/
 	virtual std::string get_raw_status (void) = 0;
 	
+	/**
+	*  \brief Returns the DDC Keithley configuration
+	*			asking its "Machine Status" word (= Using "U0X" cmd) .
+	*/
+	virtual std::string get_DDC_configuration	(void);
+
 	/**
 	*  \brief Electrometer : Keithley protocol dependent commands.
 	*/
@@ -124,7 +136,7 @@ public:
 	virtual void set_knplc			(std::string nPLC);
 	virtual void set_triggercount	(std::string trigcounts);
 	virtual void set_triggerdelay	(std::string trigdelay);
-  virtual void set_triggerMode (std::string);
+	virtual void set_triggerMode (std::string);
 	virtual void set_triggerdelayAuto (std::string trigdelAuto);
 	virtual void set_averagecount     (std::string avercounts);
 	virtual void set_averagecontrol   (std::string averctrl);
@@ -154,25 +166,25 @@ public:
 	/**
 	*  \brief Electrometer : Integration Mode configuration
 	*/
-  virtual void set_buffer_size		(std::string size);
-  virtual void clear_buffer		    (void);
-  virtual void store_raw_input		(void);
-  virtual void start_storing		  (void);
-  virtual void enable_SRQBufferFull	(void);
-  virtual void disable_SRQBufferFull(void);
-
-  virtual void set_conversionRate                 (void);
-  virtual void enable_readingWithPrefix           (void);
-  virtual void disable_readingWithPrefix          (void);
-  virtual void enable_ReadingsFromElectrometer    (void);
-  virtual void enable_readingsFromBuffer_K617_6512(void);
-  virtual void enable_readingsFromBuffer_K486_487 (void);
-  virtual void read_data_with_no_timestamp        (void);
-
-	virtual std::string get_buffer_size			        (void);
-
-  //- only for K_486 and K_487 devices
-  virtual void enable_integrationPeriod           (void);
+	virtual void set_buffer_size		(std::string size);
+	virtual void clear_buffer		    (void);
+	virtual void store_raw_input		(void);
+	virtual void start_storing			(void);
+	virtual void enable_SRQBufferFull	(void);
+	virtual void disable_SRQBufferFull	(void);
+
+	virtual void set_conversionRate                 (void);
+	virtual void enable_readingWithPrefix           (void);
+	virtual void disable_readingWithPrefix          (void);
+	virtual void enable_ReadingsFromElectrometer    (void);
+	virtual void enable_readingsFromBuffer_K617_6512(void);
+	virtual void enable_readingsFromBuffer_K486_487 (void);
+	virtual void read_data_with_no_timestamp        (void);
+
+	virtual std::string get_buffer_size			    (void);
+
+	//- only for K_486 and K_487 devices
+	virtual void enable_integrationPeriod           (void);
 
 
 	/**
diff --git a/include/KeithleyDDCProtocol.h b/include/KeithleyDDCProtocol.h
index fb36ef7..1e4939c 100644
--- a/include/KeithleyDDCProtocol.h
+++ b/include/KeithleyDDCProtocol.h
@@ -91,6 +91,12 @@ public:
 	*/
 	std::string get_raw_status (void) ;
 
+	/**
+	*  \brief Returns the DDC Keithley configuration
+	*			asking its "Machine Status" word (= Using "U0X" cmd) .
+	*/
+	std::string get_DDC_configuration	(void);
+
 	/**
 	*  \brief Electrometer Mode : getters and setters.
 	*/
diff --git a/include/Keithley_486.h b/include/Keithley_486.h
index 6bdc48f..f141dcb 100644
--- a/include/Keithley_486.h
+++ b/include/Keithley_486.h
@@ -68,6 +68,11 @@ public:
 	*/
 	std::string electrometer_status (void);
 
+	/**
+	*  \brief Returns the DDC Keithley configuration
+	*			asking its "Machine Status" word (= Using "U0X" cmd) .
+	*/
+	std::string get_configuration	(void);
 	//-	TODO :
 	//	DDC_Filters*	_ddcFilters;
 	//	DDC_Triggers*	_ddcTriggers;
diff --git a/include/Keithley_487.h b/include/Keithley_487.h
index 75ec182..ca4bd7d 100644
--- a/include/Keithley_487.h
+++ b/include/Keithley_487.h
@@ -48,10 +48,10 @@ public:
 	void range_up       (void);
 	void range_down     (void);
 	void autoRange_off  (void);
-  void set_buffer_size(short);
-  void set_triggerMode(short);
-	void init_keithley		(void); 
-  short get_buffer_size (void) { return _size; };
+	void set_buffer_size(short);
+	void set_triggerMode(short);
+	void init_keithley	(void); 
+	short get_buffer_size (void) { return _size; };
 
   /**
 	*  \brief Electrometer Function(s).
@@ -74,6 +74,11 @@ public:
 	*/
 	std::string electrometer_status (void);
 
+	/**
+	*  \brief Returns the DDC Keithley configuration
+	*			asking its "Machine Status" word (= Using "U0X" cmd) .
+	*/
+	std::string get_configuration	(void);
 	
 	//-	TODO :
 	//	DDC_Filters*	_ddcFilters;
diff --git a/include/Keithley_617.h b/include/Keithley_617.h
index 6ece226..d4a11f9 100644
--- a/include/Keithley_617.h
+++ b/include/Keithley_617.h
@@ -45,11 +45,11 @@ public:
 	/**
 	*  \brief Device dependent commands.
 	*/
-	void autoRange_off    (void);
-	void range_up         (void);
-	void range_down       (void);
-  void set_buffer_size  (short not_used);
-  void set_triggerMode  (short);
+	void autoRange_off		(void);
+	void range_up			(void);
+	void range_down			(void);
+	void set_buffer_size	(short not_used);
+	void set_triggerMode	(short);
 	void init_keithley		(void); 
 	
 	/**
@@ -71,6 +71,11 @@ public:
 	*/
 	std::string electrometer_status (void);
 
+	/**
+	*  \brief Returns the DDC Keithley configuration
+	*			asking its "Machine Status" word (= Using "U0X" cmd) .
+	*/
+	std::string get_configuration	(void);
 	
 	//-	TODO :
 	//	DDC_Filters*	_ddcFilters;
diff --git a/include/Keithley_6512.h b/include/Keithley_6512.h
index b4e0a9f..11b7749 100644
--- a/include/Keithley_6512.h
+++ b/include/Keithley_6512.h
@@ -48,8 +48,8 @@ public:
 	void autoRange_off  (void);
 	void range_up       (void);
 	void range_down     (void);
-  void set_buffer_size (short not_used);
-  void set_triggerMode (short);
+	void set_buffer_size (short not_used);
+	void set_triggerMode (short);
 	void init_keithley		(void); 
 	
 	/**
@@ -71,6 +71,11 @@ public:
 	*/
 	std::string electrometer_status (void);
 
+	/**
+	*  \brief Returns the DDC Keithley configuration
+	*			asking its "Machine Status" word (= Using "U0X" cmd) .
+	*/
+	std::string get_configuration	(void);
 	
 	//-	TODO :
 	//	DDC_Filters*	_ddcFilters;
diff --git a/src/AbstractElectrometerClass.cpp b/src/AbstractElectrometerClass.cpp
index c17921d..34723b8 100644
--- a/src/AbstractElectrometerClass.cpp
+++ b/src/AbstractElectrometerClass.cpp
@@ -11,9 +11,17 @@
 //
 // $Author: xavela $
 //
-// $Revision: 1.13 $
+// $Revision: 1.14 $
 //
 // $Log: not supported by cvs2svn $
+// Revision 1.13  2008/05/14 09:42:37  xavela
+// xavier :
+// - attributes management :
+// -> integrationTime, buffersize and triggerMode now well initialised
+//
+// TODO : after a Start command
+// -> declare all attributes INVALID !?
+//
 // Revision 1.12  2008/04/30 15:57:31  xavela
 // xavier :
 // 6517 model management added and tested :
@@ -417,6 +425,14 @@ bool AbstractElectrometerClass::get_overloadRangeState (void)
 	return _electrometerProtocol->get_overloadRangeState( );	
 }
 
+// ============================================================================
+// AbstractElectrometerClass::get_configuration
+// ============================================================================
+std::string AbstractElectrometerClass::get_configuration (void)
+{ 
+	return _electrometerProtocol->get_DDC_configuration( );	
+}
+
 // ============================================================================
 // AbstractElectrometerClass::electrometer_status
 // ============================================================================
@@ -433,8 +449,8 @@ std::string AbstractElectrometerClass::electrometer_status (void)
 		//- if no error the error code is 0
 		if( XString<short>::convertFromString(&argout[0]) != ON)
 			set_electroState(ALARM);
-    else
-      set_electroState(ON);
+		else
+			set_electroState(ON);
 	}
 	catch(...)
 	{
diff --git a/src/ElectrometerProtocol.cpp b/src/ElectrometerProtocol.cpp
index bc80d45..8609e4d 100644
--- a/src/ElectrometerProtocol.cpp
+++ b/src/ElectrometerProtocol.cpp
@@ -709,3 +709,13 @@ void ElectrometerProtocol::read_data_with_no_timestamp (void)
 											"This Electrometer does not support this command.",
 											"ElectrometerProtocol::read_data_with_no_timestamp( ).");
 }
+
+// ============================================================================
+// ElectrometerProtocol::get_DDC_configuration
+// ============================================================================
+std::string ElectrometerProtocol::get_DDC_configuration (void) 
+{
+	throw electrometer::ElectrometerException("COMMAND_NOT_SUPPORTED", 
+											"This Electrometer does not support this command.",
+											"ElectrometerProtocol::get_configuration( ).");
+}
diff --git a/src/KeithleyDDCProtocol.cpp b/src/KeithleyDDCProtocol.cpp
index d379bb8..f5ba092 100644
--- a/src/KeithleyDDCProtocol.cpp
+++ b/src/KeithleyDDCProtocol.cpp
@@ -403,7 +403,7 @@ std::string argout("no data");
 
 	cmd_to_send.str("");
 	//- get status word
-	cmd_to_send << "U0X" << std::endl;
+	cmd_to_send << "U1X" << std::endl;
 	argout = _communication_link->write_read(cmd_to_send.str());
 
 //	std::cout << "\n\nKeithleyDDCProtocol::get_raw_status returns *" << argout << "*" << std::ends;
@@ -411,6 +411,28 @@ std::string argout("no data");
 	return argout;
 }
 
+// ============================================================================
+// KeithleyDDCProtocol::get_DDC_configuration
+// ============================================================================
+std::string KeithleyDDCProtocol::get_DDC_configuration (void) 
+{
+std::stringstream cmd_to_send;
+std::string argout("no data");
+
+	//- send command : G0X -> show prefix ( = keithley type )
+	cmd_to_send << "G0X" << std::endl;
+	_communication_link->write(cmd_to_send.str());
+
+	cmd_to_send.str("");
+	//- get status word
+	cmd_to_send << "U0X" << std::endl;
+	argout = _communication_link->write_read(cmd_to_send.str());
+
+	std::cout << "\n\nKeithleyDDCProtocol::get_DDC_configuration returns *" << argout << "*" << std::ends;
+
+	return argout;
+}
+
 // ============================================================================
 // KeithleyDDCProtocol::clear_registers
 // ============================================================================
diff --git a/src/Keithley_486.cpp b/src/Keithley_486.cpp
index d8c6d11..da5dea6 100644
--- a/src/Keithley_486.cpp
+++ b/src/Keithley_486.cpp
@@ -219,13 +219,150 @@ void Keithley_486::init_keithley (void)
 // Keithley_486::electrometer_status
 // ============================================================================
 std::string Keithley_486::electrometer_status (void)
+{
+	std::string kconfig("undefined configuration");
+	std::string argout("");
+	std::string tmp("");
+
+	try
+	{
+		kconfig = _electrometerProtocol->get_raw_status();
+		std::string modelNum = kconfig.substr(0,3);
+		if(modelNum.find("486") == std::string::npos)
+		{
+			set_electroState(ALARM);
+			argout = "Invalid error status string received";
+			return argout;
+		}
+
+
+		//- IDDC Error : Set when an illegal device dependent command (IDDC) such as HlX is received ("H" is illegal).
+		tmp = kconfig.substr(3,1);
+		short iddc = XString<short>::convertFromString(tmp);
+		if(iddc)
+		{
+			argout += "IDDC error : illegal device dependent command received.\n";
+		}
+		//- IDDCO Error : Set when an illegal device-dependent command option (IDDCO) such as T9X is received ("9" is illegal).
+		tmp = kconfig.substr(4,1);
+		short iddco = XString<short>::convertFromString(tmp);
+		if(iddco)
+		{
+			argout += "IDDCO error : an illegal device-dependent command option received.\n";
+		}
+		//- Remote Error : Set when a programming command is received when REN is false.
+		tmp = kconfig.substr(5,1);
+		short remote = XString<short>::convertFromString(tmp);
+		if(remote)
+		{
+			argout += "REMOTE error : programming command is received when REN is false.\n";
+		}
+		//- Self-Test Error : Set when a self-test failure (RAM and/or ROM) occurs.
+		tmp = kconfig.substr(6,1);
+		short selfT = XString<short>::convertFromString(tmp);
+		if(selfT)
+		{
+			argout += "SELF-TEST error : Set when a self-test failure (RAM and/or ROM) occurs.\n";
+		}
+		//- Trigger Overrun Error : Set when a trigger is received when the instrument is still processing a reading from a previous trigger.
+		tmp = kconfig.substr(7,1);
+		short trigg = XString<short>::convertFromString(tmp);
+		if(trigg)
+		{
+			argout += "Trigger error : Trigger received while instrument is still processing a reading from a previous trigger.\n";
+		}
+		//- Conflict Error : Set when trying to send a calibration value with the instrument on a measurement 
+		//-		range that is too small to accommodate the value..
+		tmp = kconfig.substr(8,1);
+		short conflict = XString<short>::convertFromString(tmp);
+		if(conflict)
+		{
+			argout += "CONFLICT error : Calibration value with the instrument on a measurement range that is too small.\n";
+		}
+		//- CAL LOCKED Error : Set when calibrating the instrument with the calibration switch in the locked (disabled) position.
+		tmp = kconfig.substr(9,1);
+		short calL = XString<short>::convertFromString(tmp);
+		if(calL)
+		{
+			argout += "CAL LOCKED error : Set when calibrating the instrument with the calibration switch in the locked (disabled) position..\n";
+		}
+		//- Zero Check Error : Set when trying to calibrate the instrument with zero check enabled.
+		tmp = kconfig.substr(10,1);
+		short zchk = XString<short>::convertFromString(tmp);
+		if(zchk)
+		{
+			argout += "ZERO CHECK error : Set when trying to calibrate the instrument with zero check enabled.\n";
+		}
+		//- Calibration Error : CALIBRATION - Set when calibration results in a cal constant value that is not within allowable
+		//-		limits. Repeated failure may indicate that the Model 486/487 is defective. See service information
+		//-		in this manual.
+		tmp = kconfig.substr(11,1);
+		short calib = XString<short>::convertFromString(tmp);
+		if(calib)
+		{
+			argout += "CALIBRATION error : Set when calibration results in a cal constant value that is not within allowable limits.\n";
+		}
+		//- E2PROM DEFAULTS Error : Set when power-up checksum test on defaults fail.
+		tmp = kconfig.substr(12,1);
+		short e2prom = XString<short>::convertFromString(tmp);
+		if(e2prom)
+		{
+			argout += "E2PROM DEFAULTS error : Set when power-up checksum test on defaults fail.\n";
+		}
+		//- E2pROM CAL CONSTANTS Error : Set when power-up checksum test on cal constants fail.
+		tmp = kconfig.substr(13,1);
+		short e2prcalL = XString<short>::convertFromString(tmp);
+		if(e2prcalL)
+		{
+			argout += "E2pROM CAL CONSTANTS error : Set when power-up checksum test on cal constants fail.\n";
+		}
+		//- V-SOURCE CONFLICT Error : Set when trying to send a voltage source value to the Mode1 487 that
+		//-		exceeds the maxim um limit of the currently selected voltage sauce range. On the Model 486,
+		//-		this bit is always reset to "0".
+		tmp = kconfig.substr(14,1);
+		short vsconf = XString<short>::convertFromString(tmp);
+		if(vsconf)
+		{
+			argout += "V-SOURCE CONFLICT error : On the Model 486 this bit is always reset to \"0\".\n";
+		}
+		//- V-SOURCE Error : On the Model 486, this bit is always reset to "0".
+		tmp = kconfig.substr(15,1);
+		short vsrc = XString<short>::convertFromString(tmp);
+		if(vsrc)
+		{
+			argout += "V-SOURCE error : On the Model 486, this bit is always reset to \"0\".\n";
+		}
+
+		if( argout.empty() )
+			argout = "No error.";
+
+		argout = "Keithley Type " + modelNum + " Error Status :\n" + argout;
+
+	}
+	catch(...)
+	{
+		set_electroState(ALARM);
+	
+		throw electrometer::ElectrometerException("UNKNOWN_ERROR", 
+												"Cannot extract device error status.",
+												"Keithley_486::electrometer_status( ).");
+	}
+
+	set_electroState(ON);
+	return argout;
+}
+
+// ============================================================================
+// Keithley_486::get_configuration
+// ============================================================================
+std::string Keithley_486::get_configuration (void)
 { 
 	std::string _kstatus("undefined status");
 	std::string argout("undefined status");
 	std::string tmp("");
 
 	//- read keithley status from HW	
-	_kstatus = _electrometerProtocol->get_raw_status();
+	_kstatus = _electrometerProtocol->get_DDC_configuration();
 
 	//- build status
 	try
@@ -436,7 +573,7 @@ std::string Keithley_486::electrometer_status (void)
 
 		throw electrometer::ElectrometerException("OUT_OF_RANGE", 
 												"Cannot extract device status [find or substr failed !].",
-												"Keithley_486::electrometer_status( ).");
+												"Keithley_486::get_configuration( ).");
 	}
 
 	set_electroState(ON);
diff --git a/src/Keithley_487.cpp b/src/Keithley_487.cpp
index df3e23e..483d2fe 100644
--- a/src/Keithley_487.cpp
+++ b/src/Keithley_487.cpp
@@ -253,13 +253,151 @@ void Keithley_487::init_keithley (void)
 // Keithley_487::electrometer_status
 // ============================================================================
 std::string Keithley_487::electrometer_status (void)
+{
+	std::string kconfig("undefined configuration");
+	std::string argout("");
+	std::string tmp("");
+
+	try
+	{
+		kconfig = _electrometerProtocol->get_raw_status();
+		std::string modelNum = kconfig.substr(0,3);
+		if(modelNum.find("487") == std::string::npos)
+		{
+			set_electroState(ALARM);
+			argout = "Invalid error status string received";
+			return argout;
+		}
+
+
+		//- IDDC Error : Set when an illegal device dependent command (IDDC) such as HlX is received ("H" is illegal).
+		tmp = kconfig.substr(3,1);
+		short iddc = XString<short>::convertFromString(tmp);
+		if(iddc)
+		{
+			argout += "IDDC error : illegal device dependent command received.\n";
+		}
+		//- IDDCO Error : Set when an illegal device-dependent command option (IDDCO) such as T9X is received ("9" is illegal).
+		tmp = kconfig.substr(4,1);
+		short iddco = XString<short>::convertFromString(tmp);
+		if(iddco)
+		{
+			argout += "IDDCO error : an illegal device-dependent command option received.\n";
+		}
+		//- Remote Error : Set when a programming command is received when REN is false.
+		tmp = kconfig.substr(5,1);
+		short remote = XString<short>::convertFromString(tmp);
+		if(remote)
+		{
+			argout += "REMOTE error : programming command is received when REN is false.\n";
+		}
+		//- Self-Test Error : Set when a self-test failure (RAM and/or ROM) occurs.
+		tmp = kconfig.substr(6,1);
+		short selfT = XString<short>::convertFromString(tmp);
+		if(selfT)
+		{
+			argout += "SELF-TEST error : Set when a self-test failure (RAM and/or ROM) occurs.\n";
+		}
+		//- Trigger Overrun Error : Set when a trigger is received when the instrument is still processing a reading from a previous trigger.
+		tmp = kconfig.substr(7,1);
+		short trigg = XString<short>::convertFromString(tmp);
+		if(trigg)
+		{
+			argout += "Trigger error : Trigger received while instrument is still processing a reading from a previous trigger.\n";
+		}
+		//- Conflict Error : Set when trying to send a calibration value with the instrument on a measurement 
+		//-		range that is too small to accommodate the value..
+		tmp = kconfig.substr(8,1);
+		short conflict = XString<short>::convertFromString(tmp);
+		if(conflict)
+		{
+			argout += "CONFLICT error : Calibration value with the instrument on a measurement range that is too small.\n";
+		}
+		//- CAL LOCKED Error : Set when calibrating the instrument with the calibration switch in the locked (disabled) position.
+		tmp = kconfig.substr(9,1);
+		short calL = XString<short>::convertFromString(tmp);
+		if(calL)
+		{
+			argout += "CAL LOCKED error : Set when calibrating the instrument with the calibration switch in the locked (disabled) position..\n";
+		}
+		//- Zero Check Error : Set when trying to calibrate the instrument with zero check enabled.
+		tmp = kconfig.substr(10,1);
+		short zchk = XString<short>::convertFromString(tmp);
+		if(zchk)
+		{
+			argout += "ZERO CHECK error : Set when trying to calibrate the instrument with zero check enabled.\n";
+		}
+		//- Calibration Error : CALIBRATION - Set when calibration results in a cal constant value that is not within allowable
+		//-		limits. Repeated failure may indicate that the Model 486/487 is defective. See service information
+		//-		in this manual.
+		tmp = kconfig.substr(11,1);
+		short calib = XString<short>::convertFromString(tmp);
+		if(calib)
+		{
+			argout += "CALIBRATION error : Set when calibration results in a cal constant value that is not within allowable limits.\n";
+		}
+		//- E2PROM DEFAULTS Error : Set when power-up checksum test on defaults fail.
+		tmp = kconfig.substr(12,1);
+		short e2prom = XString<short>::convertFromString(tmp);
+		if(e2prom)
+		{
+			argout += "E2PROM DEFAULTS error : Set when power-up checksum test on defaults fail.\n";
+		}
+		//- E2pROM CAL CONSTANTS Error : Set when power-up checksum test on cal constants fail.
+		tmp = kconfig.substr(13,1);
+		short e2prcalL = XString<short>::convertFromString(tmp);
+		if(e2prcalL)
+		{
+			argout += "E2pROM CAL CONSTANTS error : Set when power-up checksum test on cal constants fail.\n";
+		}
+		//- V-SOURCE CONFLICT Error : Set when trying to send a voltage source value to the Mode1 487 that
+		//-		exceeds the maxim um limit of the currently selected voltage sauce range. On the Model 486,
+		//-		this bit is always reset to "0".
+		tmp = kconfig.substr(14,1);
+		short vsconf = XString<short>::convertFromString(tmp);
+		if(vsconf)
+		{
+			argout += "V-SOURCE CONFLICT error : Voltage source value exceeds the maxim um limit of the currently selected voltage sauce range.\n";
+		}
+		//- V-SOURCE Error : The Model 487, this bit is set when trying to place the voltage source in operate
+		//-		while the enabled interlock is open.
+		tmp = kconfig.substr(15,1);
+		short vsrc = XString<short>::convertFromString(tmp);
+		if(vsrc)
+		{
+			argout += "V-SOURCE error : Trying to place the voltage source in operate while the enabled interlock is open.\n";
+		}
+
+		if( argout.empty() )
+			argout = "No error.";
+
+		argout = "Keithley Type " + modelNum + " Error Status :\n" + argout;
+
+	}
+	catch(...)
+	{
+		set_electroState(ALARM);
+	
+		throw electrometer::ElectrometerException("UNKNOWN_ERROR", 
+												"Cannot extract device error status.",
+												"Keithley_487::electrometer_status( ).");
+	}
+
+	set_electroState(ON);
+	return argout;
+}
+
+// ============================================================================
+// Keithley_487::get_configuration
+// ============================================================================
+std::string Keithley_487::get_configuration (void)
 { 
 	std::string _kstatus("undefined status");
 	std::string argout("undefined status");
 	std::string tmp("");
 
 	//- read keithley status from HW	
-	_kstatus = _electrometerProtocol->get_raw_status();
+	_kstatus = _electrometerProtocol->get_DDC_configuration();
 
 	//- build status
 	try
@@ -482,7 +620,7 @@ std::string Keithley_487::electrometer_status (void)
 
 		throw electrometer::ElectrometerException("OUT_OF_RANGE", 
 												"Cannot extract device status [find or substr failed !].",
-												"Keithley_487::electrometer_status( ).");
+												"Keithley_487::get_configuration( ).");
 	}
 
 	set_electroState(ON);
diff --git a/src/Keithley_617.cpp b/src/Keithley_617.cpp
index 41172a4..2d91a26 100644
--- a/src/Keithley_617.cpp
+++ b/src/Keithley_617.cpp
@@ -85,8 +85,6 @@ void Keithley_617::range_up (void)
 std::stringstream cmd_to_send;
 
 	// force read of range on instrument to update _range variable 
-//	electrometer_status();
-
 	_range += 1;
 
 	if(_range > K617_rangeLimit)
@@ -111,8 +109,6 @@ void Keithley_617::range_down (void)
 std::stringstream cmd_to_send;
 
 	// force read of range on instrument to update _range variable 
-//	electrometer_status();
-
 	_range -= 1;
 
 	if(_range < 0)
@@ -134,8 +130,6 @@ std::stringstream cmd_to_send;
 std::string Keithley_617::get_ElectroMeterRange (void) 
 {
 	// force read of range on instrument to update _range variable
-//	electrometer_status();
-
 	return _rangeStr;
 }
 
@@ -144,7 +138,6 @@ std::string Keithley_617::get_ElectroMeterRange (void)
 // ============================================================================
 void Keithley_617::set_buffer_size (short cmd) 
 {
-//std::string cmd_to_send("");
 
 		throw electrometer::ElectrometerException("COMMAND_NOT_SUPPORTED", 
 												"The 617 Keithley device buffer size cannot be set (it stores up to 100 points internally.)",
@@ -178,8 +171,6 @@ void Keithley_617::set_triggerMode (short trigMod)
 std::string Keithley_617::get_ElectroMeterMode (void) 
 {
 	// force read of mode on instrument to update _mode variable
-//	electrometer_status();
-
 	return _mode;
 }
 
@@ -236,13 +227,89 @@ void Keithley_617::init_keithley (void)
 // Keithley_617::electrometer_status
 // ============================================================================
 std::string Keithley_617::electrometer_status (void)
+{
+	std::string kconfig("undefined configuration");
+	std::string argout("");
+	std::string tmp("");
+
+	try
+	{
+		kconfig = _electrometerProtocol->get_raw_status();
+		std::string modelNum = kconfig.substr(0,3);
+		if(modelNum.find("617") == std::string::npos)
+		{
+			set_electroState(ALARM);
+			argout = "Invalid error status string received";
+			return argout;
+		}
+
+
+		//- IDDC Error : Set when an illegal device dependent command (IDDC) such as HlX is received ("H" is illegal).
+		tmp = kconfig.substr(3,1);
+		short iddc = XString<short>::convertFromString(tmp);
+		if(iddc)
+		{
+			argout += "IDDC error : illegal device dependent command received.\n";
+		}
+		//- IDDCO Error : Set when an illegal device-dependent command option (IDDCO) such as T9X is received ("9" is illegal).
+		tmp = kconfig.substr(4,1);
+		short iddco = XString<short>::convertFromString(tmp);
+		if(iddco)
+		{
+			argout += "IDDCO error : an illegal device-dependent command option received.\n";
+		}
+		//- Remote Error : Set when a programming command is received when REN is false.
+		tmp = kconfig.substr(5,1);
+		short remote = XString<short>::convertFromString(tmp);
+		if(remote)
+		{
+			argout += "REMOTE error : programming command is received when REN is false\n";
+		}
+		//- Trigger Overrun Error : Set when a trigger is received when the instrument is still processing a reading from a previous trigger.
+		tmp = kconfig.substr(7,1);
+		short trigg = XString<short>::convertFromString(tmp);
+		if(trigg)
+		{
+			argout += "Trigger error : Trigger received while instrument is still processing a reading from a previous trigger.\n";
+		}
+		//- Number Error : Set when an Out of range calibration or voltage source value is received.
+		tmp = kconfig.substr(8,1);
+		short numErr = XString<short>::convertFromString(tmp);
+		if(numErr)
+		{
+			argout += "Number error : Out of range calibration or voltage source value is received.\n";
+		}
+
+		if( argout.empty() )
+			argout = "No error.";
+
+		argout = "Keithley Type " + modelNum + " Error Status :\n" + argout;
+
+	}
+	catch(...)
+	{
+		set_electroState(ALARM);
+	
+		throw electrometer::ElectrometerException("UNKNOWN_ERROR", 
+												"Cannot extract device error status.",
+												"Keithley_617::electrometer_status( ).");
+	}
+
+	set_electroState(ON);
+	return argout;
+}
+
+// ============================================================================
+// Keithley_617::get_configuration
+// ============================================================================
+std::string Keithley_617::get_configuration (void)
 { 
 	std::string _kstatus("undefined status");
 	std::string argout("undefined status");
 	std::string tmp("");
 
 	//- read keithley status from HW	
-	_kstatus = _electrometerProtocol->get_raw_status();
+	_kstatus = _electrometerProtocol->get_DDC_configuration();
 
 	//- build status
 	try
@@ -444,7 +511,7 @@ std::string Keithley_617::electrometer_status (void)
 	
 		throw electrometer::ElectrometerException("OUT_OF_RANGE", 
 												"Cannot extract device status [find or substr failed !].",
-												"Keithley_617::electrometer_status( ).");
+												"Keithley_617::get_configuration( ).");
 	}
 
 	set_electroState(ON);
diff --git a/src/Keithley_6512.cpp b/src/Keithley_6512.cpp
index 5e1fcd7..8ae2737 100644
--- a/src/Keithley_6512.cpp
+++ b/src/Keithley_6512.cpp
@@ -236,13 +236,89 @@ void Keithley_6512::init_keithley (void)
 // Keithley_6512::electrometer_status
 // ============================================================================
 std::string Keithley_6512::electrometer_status (void)
+{
+	std::string kconfig("undefined configuration");
+	std::string argout("");
+	std::string tmp("");
+
+	try
+	{
+		kconfig = _electrometerProtocol->get_raw_status();
+		std::string modelNum = kconfig.substr(0,4);
+		if(modelNum.find("6512") == std::string::npos)
+		{
+			set_electroState(ALARM);
+			argout = "Invalid error status string received";
+			return argout;
+		}
+
+
+		//- IDDC Error : Set when an illegal device dependent command (IDDC) such as HlX is received ("H" is illegal).
+		tmp = kconfig.substr(4,1);
+		short iddc = XString<short>::convertFromString(tmp);
+		if(iddc)
+		{
+			argout += "IDDC error : illegal device dependent command received.\n";
+		}
+		//- IDDCO Error : Set when an illegal device-dependent command option (IDDCO) such as T9X is received ("9" is illegal).
+		tmp = kconfig.substr(5,1);
+		short iddco = XString<short>::convertFromString(tmp);
+		if(iddco)
+		{
+			argout += "IDDCO error : an illegal device-dependent command option received.\n";
+		}
+		//- Remote Error : Set when a programming command is received when REN is false.
+		tmp = kconfig.substr(6,1);
+		short remote = XString<short>::convertFromString(tmp);
+		if(remote)
+		{
+			argout += "REMOTE error : programming command is received when REN is false\n";
+		}
+		//- Trigger Overrun Error : Set when a trigger is received when the instrument is still processing a reading from a previous trigger.
+		tmp = kconfig.substr(8,1);
+		short trigg = XString<short>::convertFromString(tmp);
+		if(trigg)
+		{
+			argout += "Trigger error : Trigger received while instrument is still processing a reading from a previous trigger.\n";
+		}
+		//- Number Error : Set when an Out of range calibration or voltage source value is received.
+		tmp = kconfig.substr(9,1);
+		short numErr = XString<short>::convertFromString(tmp);
+		if(numErr)
+		{
+			argout += "Number error : Out of range calibration or voltage source value is received.\n";
+		}
+
+		if( argout.empty() )
+			argout = "No error.";
+
+		argout = "Keithley Type " + modelNum + " Error Status :\n" + argout;
+
+	}
+	catch(...)
+	{
+		set_electroState(ALARM);
+	
+		throw electrometer::ElectrometerException("UNKNOWN_ERROR", 
+												"Cannot extract device error status.",
+												"Keithley_6512::electrometer_status( ).");
+	}
+
+	set_electroState(ON);
+	return argout;
+}
+
+// ============================================================================
+// Keithley_6512::get_configuration
+// ============================================================================
+std::string Keithley_6512::get_configuration (void)
 { 
 	std::string _kstatus("undefined status");
 	std::string argout("undefined status");
 	std::string tmp("");
 
 	//- read keithley status from HW	
-	_kstatus = _electrometerProtocol->get_raw_status();
+	_kstatus = _electrometerProtocol->get_DDC_configuration();
 
 	//- build status
 	try
@@ -428,7 +504,7 @@ std::string Keithley_6512::electrometer_status (void)
 
 		throw electrometer::ElectrometerException("OUT_OF_RANGE", 
 												"Cannot extract device status [find or substr failed !].",
-												"Keithley_6512::electrometer_status( ).");
+												"Keithley_6512::get_configuration( ).");
 	}
 
 
-- 
GitLab