// ============================================================================ // // = 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 defaultStatus("0000000000"); 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"; if ( _kstatus.size() < defaultStatus.size() ) { argout = _kstatus; set_electroState(ALARM); return argout; } //- Zero check state tmp = _kstatus.substr(0,1); if(XString<short>::convertFromString(tmp)) argout += "Zero Check : ON\n"; else argout += "Zero Check : OFF\n"; //- Log state tmp = _kstatus.substr(1,1); if(XString<short>::convertFromString(tmp)) argout += "Log : ON\n"; else argout += "Log : OFF\n"; //- Range tmp = _kstatus.substr(2,1); _range = XString<short>::convertFromString(tmp); _rangeStr = K485_rangeValue[_range]; argout += _rangeStr + "\n"; //- Relative (baseline suppress) tmp = _kstatus.substr(3,1); if(XString<short>::convertFromString(tmp)) argout += "Relative ON\n"; else argout += "Relative OFF\n"; //- Relative (baseline suppress) tmp = _kstatus.substr(4,1); if(XString<short>::convertFromString(tmp)) argout += "EOI : Send\n"; else argout += "EOI : Do Not Send\n"; //- Trigger tmp = _kstatus.substr(5,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"; //- SRQ Error Mask tmp = _kstatus.substr(6,2); short srqMaskErr = XString<short>::convertFromString(tmp); if(!srqMaskErr) argout += "SRQ Error Mask : SRQ Disabled\n"; else if(srqMaskErr == 1) argout += "SRQ Error Mask : IDDCO\n"; else if(srqMaskErr == 2) argout += "SRQ Error Mask : IDDC\n"; else if(srqMaskErr == 3) argout += "SRQ Error Mask : IDDCO or IDDC\n"; else if(srqMaskErr == 4) argout += "SRQ Error Mask : Not in Remote\n"; else if(srqMaskErr == 5) argout += "SRQ Error Mask : Not in Remote or IDDCO\n"; else if(srqMaskErr == 6) argout += "SRQ Error Mask : Not in Remote or IDDC\n"; else if(srqMaskErr == 7) 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; }