Code owners
Assign users and groups as approvers for specific file changes. Learn more.
Keithley_485.cpp 8.78 KiB
// ============================================================================
//
// = CONTEXT
// TANGO Project - KeithleyElectrometer Support Library
//
// = FILENAME
// Keithley_485.cpp
//
// = AUTHOR
// X. Elattaoui
//
// ============================================================================
// ============================================================================
// DEPENDENCIES
// ============================================================================
#include <iostream>
#include <stdexcept>
#include <sstream>
#include <string>
#include <XString.h>
#include "KeithleyDDCProtocol.h"
#include "Keithley_485.h"
/*
* 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"};
/*
* Range limit
*/
static const short K485_rangeLimit = 7;
/*
* Trigger Moded limit
*/
static const short K485_triggerModeLimit = 5;
// ============================================================================
// Keithley_485::Keithley_485
// ============================================================================
Keithley_485::Keithley_485 (std::string& comLink_device_name):AbstractElectrometerClass(comLink_device_name)
{
std::cout << "Keithley_485::Keithley_485 <-" << std::endl;
std::cout << "Keithley_485::Keithley_485 ->" << std::endl;
}
// ============================================================================
// Keithley_485::~Keithley_485
// ============================================================================
Keithley_485::~Keithley_485 (void)
{
std::cout << "Keithley_485::~Keithley_485 <-" << std::endl;
std::cout << "Keithley_485::~Keithley_485 ->" << std::endl;
}
// ============================================================================
// Keithley_485::init_protocol
// ============================================================================
bool Keithley_485::init_protocol (void)
{
std::string description("");
bool success = false;
try
{
//- build the keithley Electrometer protocol obj
_electrometerProtocol = new KeithleyDDCProtocol (_device_proxy_name);
if(_electrometerProtocol)
success = _electrometerProtocol->build_communicationLink();
}
catch(Tango::DevFailed& df)
{
description = "FAILED to create proxy on : " + _device_proxy_name;
Tango::Except::re_throw_exception (df,
(const char*)"COMMUNICATION_ERROR",
description.c_str(),
(const char*)"Keithley_485::init_protocol");
}
catch(...)
{
description = "FAILED to create proxy on : " + _device_proxy_name + ". Caught [...].";
Tango::Except::throw_exception (
(const char*)"COMMUNICATION_ERROR",
description.c_str(),
(const char*)"Keithley_485::init_protocol");
}
return success;
}
// ============================================================================
// Keithley_485::range_up
// ============================================================================
void Keithley_485::range_up (void)
{
std::stringstream cmd_to_send;
// force read of range on instrument to update _range variable
electrometer_status();
_range += 1;
if(_range > K485_rangeLimit)
{
_range = K485_rangeLimit;
throw electrometer::ElectrometerException("OUT_OF_RANGE",
"Range up limit reached.",
"Keithley_485::range_up( ).");
}
//- build and send the command
cmd_to_send << _range << std::endl;
_electrometerProtocol->set_range(cmd_to_send.str());
}
// ============================================================================
// Keithley_485::range_down
// ============================================================================
void Keithley_485::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)
{
_range=0;
throw electrometer::ElectrometerException("OUT_OF_RANGE",
"Range down limit reached.",
"Keithley_485::range_down( ).");
}
//- build and send the command
cmd_to_send << _range << std::endl;
_electrometerProtocol->set_range(cmd_to_send.str());
}
// ============================================================================
// Keithley_485::get_ElectroMeterRange
// ============================================================================
std::string Keithley_485::get_ElectroMeterRange (void)
{
// force read of range on instrument to update _range variable
electrometer_status();
return _rangeStr;
}
// ============================================================================
// Keithley_485::set_triggerMode
// ============================================================================
void Keithley_485::set_triggerMode (short trigMod)
{
std::stringstream cmd_to_send;
if(trigMod<0 || trigMod>K485_triggerModeLimit)
throw electrometer::ElectrometerException("OUT_OF_RANGE",
"Trigger mode value invalid. Please enter a value in the range 0 - 5.",
"Keithley_485::set_triggerMode( ).");
cmd_to_send << trigMod <<std::endl;
_electrometerProtocol->set_triggerMode(cmd_to_send.str());
}
// ============================================================================
// Keithley_485::electrometer_status
// ============================================================================
std::string Keithley_485::electrometer_status (void)
{
std::string _kstatus("undefined status");
std::string argout("");
std::string tmp("");
//- read keithley status from HW
_kstatus = _electrometerProtocol->get_DDC_configuration();
//- build status
try
{
//- model number :
std::string modelNum = _kstatus.substr(0,3);
//- if not expected data (here model number)
if(modelNum.find("485") == std::string::npos)
{
set_electroState(ALARM);
argout = "Invalid status string received";
return argout;
}
argout = "Keithley Type : " + modelNum + "\n";
//- Zero check state
tmp = _kstatus.substr(3,1);
if(XString<short>::convertFromString(tmp))
argout += "Zero Check : ON\n";
else
argout += "Zero Check : OFF\n";
//- Log state
tmp = _kstatus.substr(4,1);
if(XString<short>::convertFromString(tmp))
argout += "Log : ON\n";
else
argout += "Log : OFF\n";
//- Range
tmp = _kstatus.substr(5,1);
_range = XString<short>::convertFromString(tmp);
_rangeStr = K485_rangeValue[_range];
argout += "Range : " + _rangeStr + "\n";
//- Relative (baseline suppress)
tmp = _kstatus.substr(6,1);
if(XString<short>::convertFromString(tmp))
argout += "Relative ON\n";
else
argout += "Relative OFF\n";
//- Relative (baseline suppress)
tmp = _kstatus.substr(7,1);
if(XString<short>::convertFromString(tmp))
argout += "EOI : Send\n";
else
argout += "EOI : Do Not Send\n";
//- Trigger
tmp = _kstatus.substr(8,1);
short trigg = XString<short>::convertFromString(tmp);
if(!trigg)
argout += "Trigger : Continuous on Talk\n";
else
if(trigg == 1)
argout += "Trigger :One-Shot on Talk\n";
else
if(trigg == 2)
argout += "Trigger :Continuous on Get\n";
else
if(trigg == 3)
argout += "Trigger :One-Shot on Get\n";
else
if(trigg == 4)
argout += "Trigger :Continuous on \"X\"\n";
else
if(trigg == 5)
argout += "Trigger :One-Shot on \"X\"\n";
//- SRQ Data Mask
tmp = _kstatus.substr(6,2);
short srqInfo = XString<short>::convertFromString(tmp);
if(!srqInfo)
argout += "SRQ Data Mask : SRQ Disabled\n";
else
if(srqInfo == 1)
argout += "SRQ Data Mask : Reading Overflow\n";
else
if(srqInfo == 8)
argout += "SRQ Data Mask : Reading Done\n";
else
if(srqInfo == 9)
argout += "SRQ Data Mask : Reading Done or Reading Overflow\n";
else
if(srqInfo == 16)
argout += "SRQ Data Mask : Busy\n";
else
if(srqInfo == 17)
argout += "SRQ Data Mask : Busy or Reading Overflow\n";
else
if(srqInfo == 24)
argout += "SRQ Data Mask : Busy or Reading Done\n";
else
if(srqInfo == 25)
argout += "SRQ Data Mask : Busy, Reading Done or Reading Overflow\n";
else
if(srqInfo == 32)
argout += "SRQ Error Mask : Clear SRQ Errol mask\n";
else
if(srqInfo == 33)
argout += "SRQ Error Mask : IDDCQ\n";
else
if(srqInfo == 34)
argout += "SRQ Error Mask : IDDC\n";
else
if(srqInfo == 35)
argout += "SRQ Error Mask : IDDC or IDDCO\n";
else
if(srqInfo == 36)
argout += "SRQ Error Mask : Not in Remote\n";
else
if(srqInfo == 37)
argout += "SRQ Error Mask : Not in Remote or IDDCO\n";
else
if(srqInfo == 38)
argout += "SRQ Error Mask : Not in Remote or IDDC\n";
else
if(srqInfo == 39)
argout += "SRQ Error Mask : Not in Remote, IDDCO or IDDC\n";
}
catch(std::out_of_range)
{
set_electroState(ALARM);
throw electrometer::ElectrometerException("OUT_OF_RANGE",
"Cannot extract device status [find or substr failed !].",
"Keithley_485::electrometer_status( ).");
}
set_electroState(ON);
return argout;
}