// ============================================================================ // // = CONTEXT // TANGO Project - KeithleyElectrometer Support Library // // = FILENAME // Keithley_6512.cpp // // = AUTHOR // X. Elattaoui // // ============================================================================ static long KEITHLEY_MODEL = 6512; // ============================================================================ // DEPENDENCIES // ============================================================================ #include <iostream> #include <stdexcept> #include <sstream> #include <string> #include <Xstring.h> #include "Keithley_6512.h" #include "KeithleyDDCProtocol.h" /* * 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"}; /* * Range limit */ static short K6512_rangeLimit = 12; /* * Trigger Mode limit */ static short K6512_triggerModeLimit = 7; // ============================================================================ // Keithley_6512::Keithley_6512 // ============================================================================ Keithley_6512::Keithley_6512 (std::string& comLink_device_name) : AbstractElectrometerClass(comLink_device_name) { std::cout << "Keithley_6512::Keithley_6512 <-" << std::endl; //- build the keithley Electrometer obj _electrometerProtocol = new KeithleyDDCProtocol (_device_proxy_name); std::cout << "Keithley_6512::Keithley_6512 ->" << std::endl; } // ============================================================================ // Keithley_6512::~Keithley_6512 // ============================================================================ Keithley_6512::~Keithley_6512 (void) { std::cout << "Keithley_6512::~Keithley_6512 <-" << std::endl; std::cout << "Keithley_6512::~Keithley_6512 ->" << std::endl; } // ============================================================================ // Keithley_6512::autoRange_off // ============================================================================ void Keithley_6512::autoRange_off (void) { KeithleyDDCProtocol* _kddc = dynamic_cast<KeithleyDDCProtocol*>(_electrometerProtocol); if(_kddc) _kddc->autoRange_OFF_forK617_6512(); } // ============================================================================ // Keithley_6512::range_up // ============================================================================ void Keithley_6512::range_up (void) { std::stringstream cmd_to_send; // force read of range on instrument to update _range variable electrometer_status(); _range += 1; if(_range > K6512_rangeLimit) { _range = K6512_rangeLimit; throw electrometer::ElectrometerException("OUT_OF_RANGE", "Range up limit reached.", "Keithley_6512::range_up( )."); } //- build and send the command cmd_to_send << _range << std::endl; _electrometerProtocol->set_range(cmd_to_send.str()); } // ============================================================================ // Keithley_6512::range_down // ============================================================================ void Keithley_6512::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_6512::range_down( )."); } //- build and send the command cmd_to_send << _range << std::endl; _electrometerProtocol->set_range(cmd_to_send.str()); } // ============================================================================ // Keithley_6512::get_ElectroMeterRange // ============================================================================ std::string Keithley_6512::get_ElectroMeterRange (void) { // force read of range on instrument to update _range variable electrometer_status(); return _rangeStr; } // ============================================================================ // Keithley_6512::set_buffer_size() // ============================================================================ void Keithley_6512::set_buffer_size (short ) { //std::string cmd_to_send(""); throw electrometer::ElectrometerException("COMMAND_NOT_SUPPORTED", "The 6512 Keithley device buffer size cannot be set (it stores up to 100 points internally.)", "Keithley_6512::set_triggerMode( )."); } // ============================================================================ // Keithley_6512::set_triggerMode // ============================================================================ void Keithley_6512::set_triggerMode (short trigMod) { if(trigMod<0 || trigMod>K6512_triggerModeLimit) throw electrometer::ElectrometerException("OUT_OF_RANGE", "Trigger mode value invalid. Please enter a value in the range 0 - 7.", "Keithley_6512::set_triggerMode( )."); std::stringstream cmd_to_send; //- just for internal use _trigMod = trigMod; cmd_to_send << "T" << trigMod << "X" << std::endl; _electrometerProtocol->set_triggerMode(cmd_to_send.str()); } // ============================================================================ // Keithley_6512::get_ElectroMeterMode // ============================================================================ std::string Keithley_6512::get_ElectroMeterMode (void) { // force read of mode on instrument to update _mode variable electrometer_status(); return _mode; } // ============================================================================ // Keithley_6512::setAmperMeterMode (617 & 6512 Keithley DDC models // ============================================================================ void Keithley_6512::setAmperMeterMode (void) { _electrometerProtocol->setAmperMeterMode( ); } // ============================================================================ // Keithley_6512::setVoltMeterMode (617 & 6512 Keithley DDC models // ============================================================================ void Keithley_6512::setVoltMeterMode (void) { _electrometerProtocol->setVoltMeterMode( ); } // ============================================================================ // Keithley_6512::setOhmMeterMode (617 & 6512 Keithley DDC models // ============================================================================ void Keithley_6512::setOhmMeterMode (void) { _electrometerProtocol->setOhmMeterMode( ); } // ============================================================================ // Keithley_6512::setCoulombMeterMode (617 & 6512 Keithley DDC models // ============================================================================ void Keithley_6512::setCoulombMeterMode (void) { _electrometerProtocol->setCoulombMeterMode( ); } // ============================================================================ // Keithley_6512::init_keithley : command to perform an integration cycle // ============================================================================ void Keithley_6512::init_keithley (void) { //- set trigger mode this->set_triggerMode(_trigMod); //- default conversion rate _electrometerProtocol->set_conversionRate( ); //- force readings with no prefix _electrometerProtocol->disable_readingWithPrefix(); //- force readings from device buffer _electrometerProtocol->enable_readingsFromBuffer_K617_6512(); //- enable SRQ on buffer full _electrometerProtocol->enable_SRQBufferFull (); } // ============================================================================ // Keithley_6512::electrometer_status // ============================================================================ std::string Keithley_6512::electrometer_status (void) { std::string _kstatus("undefined status"); std::string argout("undefined status"); std::string tmp(""); //- read keithley status from HW _kstatus = _electrometerProtocol->get_raw_status(); //- build status try { //- model number : std::string modelNum = _kstatus.substr(0,4); //- if not expected data (here model number) if(modelNum.find("6512") == std::string::npos) { set_electroState(ALARM); argout = "Invalid status string received"; return argout; } argout = "Keithley Type : " + modelNum + "\n"; //- Functions and associate range : tmp = _kstatus.substr(4,1); short func = XString<short>::convertFromString(tmp); //- Range : tmp = _kstatus.substr(5,2); _range = XString<short>::convertFromString(tmp); if(!func) { _mode = "Function : VOLTS"; argout += _mode + "\n"; _rangeStr = K6512_VoltRangeValue[_range]; } else if(func == 1) { _mode = "Function : AMPS"; argout += _mode + "\n"; _rangeStr = K6512_AmpRangeValue[_range]; argout += _rangeStr + "\n"; } else if(func == 2) { _mode = "Function : OHMS"; argout += _mode + "\n"; _rangeStr = K6512_OhmRangeValue[_range]; } else if(func == 3) { _mode = "Function : COULOMBS"; argout += _mode + "\n"; _rangeStr = K6512_CouRangeValue[_range]; } else if(func == 4) { _mode = "Function : XFDBK"; argout += _mode + "\n"; _rangeStr = K6512_XfdbRangeValue[_range]; } //- Range : argout += "RANGE : " + _rangeStr + "\n"; //- Zero check state tmp = _kstatus.substr(7,1); if(XString<short>::convertFromString(tmp)) argout += "Zero Check : ON\n"; else argout += "Zero Check : OFF\n"; //- Zero correct state tmp = _kstatus.substr(8,1); if(XString<short>::convertFromString(tmp)) argout += "Zero Correct : ON\n"; else argout += "Zero Correct : OFF\n"; //- Suppress tmp = _kstatus.substr(9,1); if(XString<short>::convertFromString(tmp)) argout += "Suppress : ON\n"; else argout += "Suppress : OFF\n"; //- Trigger tmp = _kstatus.substr(10,1); if(!XString<short>::convertFromString(tmp)) argout += "Trigger : Continuous on Talk\n"; else if(XString<short>::convertFromString(tmp) == 1) argout += "Trigger :One-Shot on Talk\n"; else if(XString<short>::convertFromString(tmp) == 2) argout += "Trigger :Continuous on Get\n"; else if(XString<short>::convertFromString(tmp) == 3) argout += "Trigger :One-Shot on Get\n"; else if(XString<short>::convertFromString(tmp) == 4) argout += "Trigger :Continuous on \"X\"\n"; else if(XString<short>::convertFromString(tmp) == 5) argout += "Trigger :One-Shot on \"X\"\n"; else if(XString<short>::convertFromString(tmp) == 6) argout += "Trigger :Continuous on External\n"; else if(XString<short>::convertFromString(tmp) == 7) argout += "Trigger :One-Shot on External\n"; //- Read Mode tmp = _kstatus.substr(12,1); if(!XString<short>::convertFromString(tmp)) argout += "Read Mode : Electrometer\n"; else if(XString<short>::convertFromString(tmp) == 1) argout += "Read Mode : Data Store\n"; else if(XString<short>::convertFromString(tmp) == 2) argout += "Read Mode : Maximum\n"; else if(XString<short>::convertFromString(tmp) == 3) argout += "Read Mode : Minimum\n"; else if(XString<short>::convertFromString(tmp) == 4) argout += "Read Mode :Voltage Source\n"; //- Data Store tmp = _kstatus.substr(15,1); if(!XString<short>::convertFromString(tmp)) argout += "Data Store : Conversion Rate\n"; else if(XString<short>::convertFromString(tmp) == 1) argout += "Data Store : 1 RDG/Sec\n"; else if(XString<short>::convertFromString(tmp) == 2) argout += "Data Store : 1 RDG/10Sec\n"; else if(XString<short>::convertFromString(tmp) == 3) argout += "Data Store : 1 RDG/Min\n"; else if(XString<short>::convertFromString(tmp) == 4) argout += "Data Store : 1 RDG/10Min\n"; else if(XString<short>::convertFromString(tmp) == 5) argout += "Data Store : 1 RDG/1Hr\n"; else if(XString<short>::convertFromString(tmp) == 6) argout += "Data Store : Trig Button\n"; else if(XString<short>::convertFromString(tmp) == 7) argout += "Data Store : Disabled\n"; //- SRQ Mask tmp = _kstatus.substr(16,2); if(!XString<short>::convertFromString(tmp)) argout += "SRQ Data Mask : SRQ Disabled\n"; else if(XString<short>::convertFromString(tmp) == 1) argout += "SRQ Data Mask : Reading Overflow\n"; else if(XString<short>::convertFromString(tmp) == 2) argout += "SRQ Data Mask : Data Store Full\n"; else if(XString<short>::convertFromString(tmp) == 8) argout += "SRQ Data Mask : Reading Done\n"; else if(XString<short>::convertFromString(tmp) == 16) argout += "SRQ Data Mask : Ready\n"; else if(XString<short>::convertFromString(tmp) == 32) argout += "SRQ Data Mask : Error\n"; //- EOI & Bus Hold Off tmp = _kstatus.substr(18,1); if(!XString<short>::convertFromString(tmp)) argout += "EOI & Bus Hold Off : EOI and Hold-Off\n"; else if(XString<short>::convertFromString(tmp) == 1) argout += "EOI & Bus Hold Off : No EOI and Hold-Off\n"; else if(XString<short>::convertFromString(tmp) == 2) argout += "EOI & Bus Hold Off : EOI and no Hold-Off\n"; else if(XString<short>::convertFromString(tmp) == 3) argout += "EOI & Bus Hold Off : No EOI and no Hold-Off\n"; } catch(std::out_of_range) { set_electroState(ALARM); throw electrometer::ElectrometerException("OUT_OF_RANGE", "Cannot extract device status [find or substr failed !].", "Keithley_6512::electrometer_status( )."); } set_electroState(ON); return argout; }