26#define DEBUG_MTL_INSTRUMENT_THM1176 1
27#define DEBUG_MTL_INSTRUMENT_THM1176_ERRORS_ONLY 0
28#if (defined(_DEBUG) && defined(DEBUG_MTL_INSTRUMENT_THM1176) && DEBUG_MTL_INSTRUMENT_THM1176)
29 #if (defined(DEBUG_MTL_INSTRUMENT_THM1176_ERRORS_ONLY) && DEBUG_MTL_INSTRUMENT_THM1176_ERRORS_ONLY)
30 #define MTL_INSTRUMENT_THM1176_DEBUG_COUT(__X__)
32 #define MTL_INSTRUMENT_THM1176_DEBUG_COUT(__X__) std::cout << __X__
34#define MTL_INSTRUMENT_THM1176_DEBUG_CERR(__X__) std::cerr << __X__
36 #define MTL_INSTRUMENT_THM1176_DEBUG_COUT(__X__)
37 #define MTL_INSTRUMENT_THM1176_DEBUG_CERR(__X__)
57 {
"",
"",
":STAT:QUES:ENAB" },
58 {
"",
"",
":STAT:OPER:ENAB" }
63 {
"*STB?",
"",
"*SRE?" },
64 {
"*ESR?",
"",
"*ESE?" },
65 {
":STAT:QUES:EVEN?",
":STAT:QUES:COND?",
":STAT:QUES:ENAB?" },
66 {
":STAT:OPER:EVEN?",
":STAT:OPER:COND?",
":STAT:OPER:ENAB?" }
71 std::string(
"TFM1186")
87static std::string
l_ToString(
F32 number,
int precision = 7,
const char * locale =
"C")
89 std::locale l_locale = std::locale(locale);
90 std::ostringstream l_oss;
92 l_oss.imbue(l_locale);
93 l_oss << std::scientific << std::setprecision(precision);
99static std::string
l_ToString(
F64 number,
int precision = 15,
const char * locale =
"C")
101 std::locale l_locale = std::locale(locale);
102 std::ostringstream l_oss;
104 l_oss.imbue(l_locale);
105 l_oss << std::scientific << std::setprecision(precision);
117 size_t l_Comma = rErrStr.find_first_of(
',');
118 rError.
Code = std::stoi(rErrStr.substr(0, l_Comma));
120 size_t l_OpenQuote = rErrStr.find_first_of(
'"', l_Comma + 1);
121 size_t l_CloseQuote = rErrStr.find_last_of(
'"');
122 rError.
Description = rErrStr.substr(l_OpenQuote + 1, l_CloseQuote - (l_OpenQuote + 1));
128 std::vector<std::string> lErrorList;
129 if (rE.code() & std::regex_constants::error_badrepeat)
130 lErrorList.push_back (
"error_badrepeat");
131 if (rE.code() & std::regex_constants::error_ctype)
132 lErrorList.push_back (
"error_ctype");
133 if (rE.code() & std::regex_constants::error_escape)
134 lErrorList.push_back (
"error_escape");
135 if (rE.code() & std::regex_constants::error_backref)
136 lErrorList.push_back (
"error_backref");
137 if (rE.code() & std::regex_constants::error_brack)
138 lErrorList.push_back (
"error_brack");
139 if (rE.code() & std::regex_constants::error_paren)
140 lErrorList.push_back (
"error_paren");
141 if (rE.code() & std::regex_constants::error_brace)
142 lErrorList.push_back (
"error_brace");
143 if (rE.code() & std::regex_constants::error_badbrace)
144 lErrorList.push_back (
"error_badbrace");
145 if (rE.code() & std::regex_constants::error_range)
146 lErrorList.push_back (
"error_range");
147 if (rE.code() & std::regex_constants::error_space)
148 lErrorList.push_back (
"error_space");
149 if (rE.code() & std::regex_constants::error_badrepeat)
150 lErrorList.push_back (
"error_badrepeat");
151 if (rE.code() & std::regex_constants::error_complexity)
152 lErrorList.push_back (
"error_complexity");
153 if (rE.code() & std::regex_constants::error_stack)
154 lErrorList.push_back (
"error_stack");
156 std::string lErrors = lErrorList.front();
157 for (
auto lpError = lErrorList.begin() + 1; lpError < lErrorList.end(); lpError++)
158 lErrors +=
" | " + *lpError;
165template <
class InstrType,
class RsrcMgrType>
166bool CTHM1176Instrument<InstrType, RsrcMgrType>::ReadIdentification(std::string & rIdentification)
176 rIdentification = std::string(m_ReadBuffer.begin(), m_ReadBuffer.end());
182 rIdentification.clear();
188template <
class InstrType,
class RsrcMgrType>
189bool CTHM1176Instrument<InstrType, RsrcMgrType>::ParseIdentification(
struct sIdentifier & rIdentification)
195 std::regex l_Regex(
"([^,]+),([^,]+),([^,]+),([^,]+)");
197 if (!std::regex_match(m_Identification, l_Match, l_Regex))
201 rIdentification.
Model = l_Match[2].str();
204 std::string l_Versions = l_Match[4].str();
205 l_Regex =
"el(([A-Z])([0-9]+))-pr(([A-Z]?)([0-9]+))-fw(([0-9]+)\\.([0-9]+))\\n";
206 if (!std::regex_match(l_Versions, l_Match, l_Regex))
223 std::map<std::string, eInstrModel> l_InstModel =
231 auto l_pInstrModel = l_InstModel.find(rIdentification.
Model);
232 if (l_pInstrModel == l_InstModel.cend())
239 rIdentification.
InstrModel = l_pInstrModel->second;
248 catch (std::regex_error& rE)
257template <
class InstrType,
class RsrcMgrType>
258bool CTHM1176Instrument<InstrType, RsrcMgrType>::GetErrorList(
CErrorList & rList,
const std::string & rContext)
267 if (!InstrType::ReadSTB(l_STB.
RawSTB))
275 enum eRetry { kRetryErrorRetrieving };
278 if (!InstrType::Write(
":SYST:ERR?"))
279 throw kRetryErrorRetrieving;
280 if (!InstrType::Read(l_Error))
281 throw kRetryErrorRetrieving;
283 catch (eRetry & rRetry)
285 if (rRetry == kRetryErrorRetrieving)
288 if (!InstrType::Clear())
291 if (!InstrType::Write(
":SYST:ERR?"))
293 if (!InstrType::Read(l_Error))
298 std::string l_ErrStr = std::string(l_Error.data(), l_Error.size());
301 rList.push_back(l_Err);
303 if (!InstrType::ReadSTB(l_STB.
RawSTB))
315 for (
auto it = rList.begin(); it != rList.end(); it++)
317 CERR(
"THM1176Error " << it->Code <<
" : " << it->Description <<
" in " << it->Context << std::endl);
323template <
class InstrType,
class RsrcMgrType>
329 bool l_InitialLockState = InstrType::LockedExclusive();
336 if (!l_InitialLockState && !InstrType::LockExclusive(m_Timeout))
341 bool l_OPCAppended = !std::regex_match(rWriteStr, std::regex(
"\\*IDN\\?"));
344 l_Query = rWriteStr +
";*OPC?";
349 if (!InstrType::Write(l_Query))
361 bool l_Timeout =
false;
368 if (InstrType::Read(rReadBuffer,
true))
374 l_Timeout = InstrType::Timeout();
379 if (!InstrType::ReadSTB(l_STB.
RawSTB))
390 std::size_t l_MaxSizeToMatch = std::strlen(
";1\n");
391 std::match_results<std::vector<char>::iterator> m;
393 if (std::regex_match((rReadBuffer.
size() <= l_MaxSizeToMatch) ? rReadBuffer.
begin() : rReadBuffer.
end() - l_MaxSizeToMatch, rReadBuffer.
end(), m, std::regex(
";?1\\n?$")))
394 rReadBuffer.
resize(rReadBuffer.
size() - m.length());
398 if (!l_InitialLockState && !InstrType::Unlock())
409 InstrType::Write(
":ABOR");
416 InstrType::Read(rReadBuffer,
true);
419 GetErrorList(m_ErrorList, rWriteStr);
422 if (!l_InitialLockState) InstrType::Unlock();
429 catch (std::regex_error& rE)
438template <
class InstrType,
class RsrcMgrType>
439bool CTHM1176Instrument<InstrType, RsrcMgrType>::ReadBootTime(
CAbsoluteTimestamp & rBootTime)
451 if(!m_ErrorList.empty())
453 auto l_pError = m_ErrorList.begin();
454 for (; l_pError < m_ErrorList.end(); l_pError++)
462 if (!WriteAndRead(
":FETC:TIM?", m_ReadBuffer))
464 std::string l_TimestampString(m_ReadBuffer.begin(), m_ReadBuffer.end());
465 U64 l_Timestamp = std::stoull(l_TimestampString,
nullptr, 0);
469 std::time_t l_CurrentTime = std::time(
nullptr);
484template <
class InstrType,
class RsrcMgrType>
485bool CTHM1176Instrument<InstrType, RsrcMgrType>::ReadAllRanges(
CFluxList & rRanges)
497 if (l_Tokens.size() < 1)
502 for (
auto it = l_Tokens.begin(); it != l_Tokens.end(); it++)
504 std::string l_StrRange(it->begin, it->end - 2);
507 rRanges.push_back(std::stof(l_StrRange));
509 catch (
const std::invalid_argument& ia)
525template <
class InstrType,
class RsrcMgrType>
526bool CTHM1176Instrument<InstrType, RsrcMgrType>::ReadAllUnits(std::map<eUnits,U32> & rAllUnits)
533 if (!WriteAndRead(
":UNIT:ALL?", m_ReadBuffer))
538 if (l_Tokens.size() < 2 || (l_Tokens.size() % 2) == 1)
543 for (
auto it = l_Tokens.begin(); it != l_Tokens.end(); it++)
545 std::string l_StrUnit(it->begin, it->end);
547 std::string l_StrDivisor(it->begin, it->end);
551 U32 l_Divisor =
static_cast<U32>(std::stoul(l_StrDivisor));
552 rAllUnits.insert(std::pair<eUnits, U32>(l_Units, l_Divisor));
565template <
class InstrType,
class RsrcMgrType>
566bool CTHM1176Instrument<InstrType, RsrcMgrType>::ReadUseCalibration(
bool & rUseCal)
573 if (!WriteAndRead(
":CAL:STAT?", m_ReadBuffer))
576 std::string l_Answer(m_ReadBuffer.begin(), m_ReadBuffer.end());
577 if (l_Answer ==
"ON")
579 else if (l_Answer ==
"OFF")
593template <
class InstrType,
class RsrcMgrType>
594bool CTHM1176Instrument<InstrType, RsrcMgrType>::ReadManufacturingDate(std::string & rDate)
598 std::string l_CalFileContent;
605 rDate = std::string(l_CalFileContent, 100, 10);
618template <
class InstrType,
class RsrcMgrType>
619bool CTHM1176Instrument<InstrType, RsrcMgrType>::ReadRotationMatrix(Matrix3f & rMatrix, std::string & rCalibrationDate)
623 std::string l_CalFileContent;
630 rCalibrationDate = std::string(l_CalFileContent, 64, 10);
633 char * l_pMatrix =
const_cast<char *
>(l_CalFileContent.c_str());
644 I32 l_IntMatrix[3][3];
645 for (
int i = 0; i < 3; i++)
646 for (
int j = 0; j < 3; j++)
649 l_pMatrix +=
sizeof (
I32);
653 const F32 l_C =
static_cast<F32>(0x7FFFFFFF);
654 rMatrix << l_IntMatrix[0][0]/l_C, l_IntMatrix[0][1]/l_C, l_IntMatrix[0][2]/l_C,
655 l_IntMatrix[1][0]/l_C, l_IntMatrix[1][1]/l_C, l_IntMatrix[1][2]/l_C,
656 l_IntMatrix[2][0]/l_C, l_IntMatrix[2][1]/l_C, l_IntMatrix[2][2]/l_C;
662 rCalibrationDate =
"";
668template <
class InstrType,
class RsrcMgrType>
669bool CTHM1176Instrument<InstrType, RsrcMgrType>::ApplyRotationMatrix(
tFlux & rBx,
tFlux & rBy,
tFlux & rBz)
674 if (!m_UseCalibration)
678 Vector3f l_B(rBx, rBy, rBz);
679 l_B = m_RotationMatrix * l_B;
694template <
class InstrType,
class RsrcMgrType>
700 if (!m_UseCalibration)
704 if (rBx.size() != rBy.size() || rBx.size() != rBz.size())
710 for (
auto l_pBx = rBx.begin(), l_pBy = rBy.begin(), l_pBz = rBz.begin();
712 l_pBx++, l_pBy++, l_pBz++)
714 Vector3f l_B(*l_pBx, *l_pBy, *l_pBz);
715 l_B = m_RotationMatrix * l_B;
730template <
class InstrType,
class RsrcMgrType>
737 std::vector<char>::const_iterator l_tokenbeg, l_tokenend;
738 if (!rBP.
GetNext(l_tokenbeg, l_tokenend,
';'))
749 tFlux l_DivisorReal = 1.;
750 if (m_UseCalibration)
751 l_DivisorReal =
static_cast<tFlux>(m_Units.at(Units));
754 if (l_tokenbeg[1] ==
'6')
757 l_len >= 4 && rMeas.size() < NoMeasurements;
758 l_len -= 4, l_off += 4)
761 rMeas.push_back(
static_cast<tFlux>(l_MeasI32) / l_DivisorReal);
766 else if (l_tokenbeg[1] ==
'5')
769 size_t l_Pack = (l_tokenbeg[l_off] ==
'1') ? 1 :
770 (l_tokenbeg[l_off] ==
'2') ? 2 : 0;
777 rMeas.push_back(
static_cast<tFlux>(l_MeasI32) / l_DivisorReal);
780 for (l_len -= 4, l_off += 4;
781 l_len >= l_Pack && rMeas.size() < NoMeasurements;
782 l_len -= l_Pack, l_off += l_Pack)
785 l_MeasI32 +=
static_cast<I8>(*(&*l_tokenbeg + l_off));
788 rMeas.push_back(
static_cast<tFlux>(l_MeasI32) / l_DivisorReal);
799 std::vector<char>::const_iterator l_measbeg, l_measend;
801 for (l_GetNextRet = l_FluxParser.GetNext(l_measbeg, l_measend,
',');
802 l_GetNextRet && rMeas.size() < NoMeasurements;
803 l_GetNextRet = l_FluxParser.GetNext(l_measbeg, l_measend,
','))
805 std::string l_Measurement(l_measbeg, l_measend);
806 rMeas.push_back(std::stof(l_Measurement));
811 if (rMeas.size() != NoMeasurements)
827template <
class InstrType,
class RsrcMgrType>
829: InstrType(rResourceManager, ResourceName),
830 m_Timeout(0), m_ReadBuffer(65535), m_Sleep(false), m_UseCalibration(true), m_AbortRead(false)
834template <
class InstrType,
class RsrcMgrType>
837 if (InstrType::IsOpen())
847template <
class InstrType,
class RsrcMgrType>
853template <
class InstrType,
class RsrcMgrType>
865template <
class InstrType,
class RsrcMgrType>
880 m_Timeout = InitialTimeout;
881 if (!InstrType::Open())
883 if (Exclusive && !InstrType::LockExclusive(m_Timeout))
885 if (!InstrType::Clear())
889 if (!ReadIdentification(m_Identification))
891 if (!ParseIdentification(m_IdentificationStruct))
893 if ((m_IdentificationStruct.Model ==
"THM1176-A") && (m_IdentificationStruct.FirmwareVersion.Major < l_MinMajor || m_IdentificationStruct.FirmwareVersion.Minor < l_MinMinor))
895 if (!ReadBootTime(m_BootTime))
897 if (!ReadAllUnits(m_Units))
899 if (!ReadAllRanges(m_Ranges))
901 if (!ReadManufacturingDate(m_ManufacturingDate))
903 if (!ReadRotationMatrix(m_RotationMatrix, m_CalibrationDate))
905 if (!ReadUseCalibration(m_UseCalibration))
923 if (pErrMsg !=
nullptr)
924 *pErrMsg = rE.
what();
925 if (InstrType::IsOpen())
932template <
class InstrType,
class RsrcMgrType>
938 if (InstrType::IsOpen())
945template <
class InstrType,
class RsrcMgrType>
951 std::string l_Command =
":AVER:COUN " + std::to_string(rAvg.
NoPoints);
953 if (l_Success) m_AveragingParms = rAvg;
957template <
class InstrType,
class RsrcMgrType>
968 rAvg.
NoPoints =
static_cast<U16>(std::stoi(std::string(m_ReadBuffer.begin(), m_ReadBuffer.end())));
979template <
class InstrType,
class RsrcMgrType>
987 if (!
WriteAndRead(
":AVER:COUN?;:AVER:COUN? MIN;:AVER:COUN? MAX;:AVER:COUN? DEF", m_ReadBuffer))
992 if (l_Tokens.size() != 4)
995 rAvg.
NoPoints.Val =
static_cast<U16>(std::stoi(std::string(l_Tokens[0].begin, l_Tokens[0].end)));
996 rAvg.
NoPoints.Min =
static_cast<U16>(std::stoi(std::string(l_Tokens[1].begin, l_Tokens[1].end)));
997 rAvg.
NoPoints.Max =
static_cast<U16>(std::stoi(std::string(l_Tokens[2].begin, l_Tokens[2].end)));
998 rAvg.
NoPoints.Def =
static_cast<U16>(std::stoi(std::string(l_Tokens[3].begin, l_Tokens[3].end)));
1009template <
class InstrType,
class RsrcMgrType>
1019template <
class InstrType,
class RsrcMgrType>
1029template <
class InstrType,
class RsrcMgrType>
1035 std::string l_Command =
":TRIG:SOUR ";
1036 switch (rInputTrig.
Source)
1040 l_Command +=
";COUN " + std::to_string(rInputTrig.
Count);
1044 l_Command +=
";COUN " + std::to_string(rInputTrig.
Count);
1049 l_Command +=
";COUN " + std::to_string(rInputTrig.
Count);
1055 m_TriggerParms = rInputTrig;
1062 m_ErrorList = l_ErrorList;
1067template <
class InstrType,
class RsrcMgrType>
1083 if (l_Tokens.size() != 3)
1087 std::string l_Source(l_Tokens[0].begin, l_Tokens[0].end);
1088 if (l_Source ==
"IMMEDIATE")
1090 else if (l_Source ==
"TIMER")
1092 else if (l_Source ==
"BUS")
1098 rInputTrig.
Period_s = std::stod(std::string(l_Tokens[1].begin, l_Tokens[1].end));
1101 rInputTrig.
Count =
static_cast<U16>(std::stoi(std::string(l_Tokens[2].begin, l_Tokens[2].end)));
1112template <
class InstrType,
class RsrcMgrType>
1121 ";TIM?;TIM? MIN;TIM? MAX;TIM? DEF"
1122 ";COUN?;COUN? MIN;COUN? MAX;COUN? DEF",
1128 if (l_Tokens.size() != 9)
1132 std::string l_Source(l_Tokens[0].begin, l_Tokens[0].end);
1133 if (l_Source ==
"IMMEDIATE")
1135 else if (l_Source ==
"TIMER")
1137 else if (l_Source ==
"BUS")
1143 rInputTrig.
Period_s.Val = std::stod(std::string(l_Tokens[1].begin, l_Tokens[1].end));
1144 rInputTrig.
Period_s.Min = std::stod(std::string(l_Tokens[2].begin, l_Tokens[2].end));
1145 rInputTrig.
Period_s.Max = std::stod(std::string(l_Tokens[3].begin, l_Tokens[3].end));
1146 rInputTrig.
Period_s.Def = std::stod(std::string(l_Tokens[4].begin, l_Tokens[4].end));
1149 rInputTrig.
Count.Val =
static_cast<U16>(std::stoi(std::string(l_Tokens[5].begin, l_Tokens[5].end)));
1150 rInputTrig.
Count.Min =
static_cast<U16>(std::stoi(std::string(l_Tokens[6].begin, l_Tokens[6].end)));
1151 rInputTrig.
Count.Max =
static_cast<U16>(std::stoi(std::string(l_Tokens[7].begin, l_Tokens[7].end)));
1152 rInputTrig.
Count.Def =
static_cast<U16>(std::stoi(std::string(l_Tokens[8].begin, l_Tokens[8].end)));
1163template <
class InstrType,
class RsrcMgrType>
1173 m_UnitsParms = Units;
1180 m_ErrorList = l_ErrorList;
1185template <
class InstrType,
class RsrcMgrType>
1196 std::string l_Answer(m_ReadBuffer.begin(), m_ReadBuffer.end());
1209template <
class InstrType,
class RsrcMgrType>
1215 std::string l_Command = std::string(
":CAL:STAT ") + (UseCal ?
"ON" :
"OFF");
1219 m_UseCalibration = UseCal;
1226template <
class InstrType,
class RsrcMgrType>
1232 rUseCal = m_UseCalibration;
1236template <
class InstrType,
class RsrcMgrType>
1242 std::string l_Command;
1244 l_Command =
":SENS:AUTO ON";
1246 l_Command =
":SENS:AUTO OFF;:SENS " +
l_ToString(rRange.
Range, 1) +
" T";
1250 m_RangeParms = rRange;
1257 m_ErrorList = l_ErrorList;
1262template <
class InstrType,
class RsrcMgrType>
1275 if (l_Tokens.size() != 2)
1279 std::string l_Auto(l_Tokens[0].begin, l_Tokens[0].end);
1282 else if (l_Auto ==
"OFF")
1283 rRange.
Auto =
false;
1288 std::string l_Range(l_Tokens[1].begin, l_Tokens[1].end - 2);
1289 rRange.
Range = std::stof(l_Range);
1300template <
class InstrType,
class RsrcMgrType>
1308 if (!
WriteAndRead(
":SENS:AUTO?;:SENS?;:SENS? MIN;:SENS? MAX;:SENS? DEF", m_ReadBuffer))
1313 if (l_Tokens.size() != 5)
1317 std::string l_Auto(l_Tokens[0].begin, l_Tokens[0].end);
1320 else if (l_Auto ==
"OFF")
1321 rRange.
Auto =
false;
1326 std::string l_Val(l_Tokens[1].begin, l_Tokens[1].end - 2);
1327 rRange.
Range.Val = std::stof(l_Val);
1330 std::string l_Min(l_Tokens[2].begin, l_Tokens[2].end - 2);
1331 rRange.
Range.Min = std::stof(l_Min);
1334 std::string l_Max(l_Tokens[3].begin, l_Tokens[3].end - 2);
1335 rRange.
Range.Max = std::stof(l_Max);
1338 std::string l_Def(l_Tokens[4].begin, l_Tokens[4].end - 2);
1339 rRange.
Range.Def = std::stof(l_Def);
1353template <
class InstrType,
class RsrcMgrType>
1360 m_ErrorList.clear();
1374 std::vector<char>::const_iterator l_tokenbeg, l_tokenend;
1377 if (!l_BP.
GetNext(l_tokenbeg, l_tokenend,
','))
1379 rUsedBytes =
static_cast<U32>(std::stoul(std::string(l_tokenbeg, l_tokenend)));
1382 if (!l_BP.
GetNext(l_tokenbeg, l_tokenend,
','))
1384 rAvailableBytes =
static_cast<U32>(std::stoul(std::string(l_tokenbeg, l_tokenend)));
1387 while (l_BP.
GetNext(l_tokenbeg, l_tokenend,
','))
1391 l_File.
Path = std::string(l_tokenbeg, l_tokenend);
1393 if (!l_BP.
GetNext(l_tokenbeg, l_tokenend,
','))
1395 l_File.
Size = std::stoul(std::string(l_tokenbeg, l_tokenend));
1397 if (!l_BP.
GetNext(l_tokenbeg, l_tokenend,
','))
1399 l_File.
Type = std::string(l_tokenbeg, l_tokenend);
1401 rFileList.push_back(l_File);
1405 if (!InstrType::SetTimeout(m_Timeout))
1412 InstrType::SetTimeout(m_Timeout);
1418template <
class InstrType,
class RsrcMgrType>
1424 m_ErrorList.clear();
1428 std::string l_Command;
1429 l_Command =
":MMEM:DATA? " "\"" + Path +
"\"";
1440 size_t l_off, l_len;
1441 if (!
IsArbitraryBlock(m_ReadBuffer.begin(), m_ReadBuffer.end(), l_off, l_len))
1443 rContent = std::string(m_ReadBuffer.begin() + l_off, m_ReadBuffer.begin() + l_off + l_len);
1446 if (!InstrType::SetTimeout(m_Timeout))
1453 InstrType::SetTimeout(m_Timeout);
1462template <
class InstrType,
class RsrcMgrType>
1469 m_AveragingParmsAtInit = m_AveragingParms;
1470 m_TriggerParmsAtInit = m_TriggerParms;
1471 m_TriggerTimes.clear();
1474 std::string l_Command = Continuous ?
":INIT:CONT 1;:INIT" :
":INIT:CONT 0;:INIT";
1478template <
class InstrType,
class RsrcMgrType>
1487template <
class InstrType,
class RsrcMgrType>
1493 m_ErrorList.clear();
1496 std::chrono::high_resolution_clock::time_point l_T = std::chrono::high_resolution_clock::now();
1497 m_TriggerTimes.push_back(l_T);
1500 return InstrType::AssertTrigger();
1506template <
class InstrType,
class RsrcMgrType>
1516 l_ArbSelect.
Bx =
true;
1517 l_ArbSelect.
By =
true;
1518 l_ArbSelect.
Bz =
true;
1523 return MeasurementsGet(l_ArbSelect, rBx, rBy, rBz, rUnits, rTemp, rTimestampList, pMeasurementConditions);
1526template <
class InstrType,
class RsrcMgrType>
1538 std::string l_Command =
":UNIT?;:SENS?";
1539 if (ArbSelect.
Bx) l_Command +=
";:FETC:ARR:X? " + std::to_string(ArbSelect.
NoMeasurements);
1540 if (ArbSelect.
By) l_Command +=
";:FETC:ARR:Y? " + std::to_string(ArbSelect.
NoMeasurements);
1541 if (ArbSelect.
Bz) l_Command +=
";:FETC:ARR:Z? " + std::to_string(ArbSelect.
NoMeasurements);
1542 if (ArbSelect.
Temperature) l_Command +=
";:FETC:TEMP?";
1543 if (ArbSelect.
Timestamp) l_Command +=
";:FETC:TIM?";
1544 if (m_Sleep) l_Command +=
";:SYST:SLEE";
1550 if(!m_ErrorList.empty())
1552 auto l_pError = m_ErrorList.begin();
1553 for (; l_pError < m_ErrorList.end(); l_pError++)
1555 if (l_pError < m_ErrorList.end())
1562 std::vector<char>::const_iterator l_tokenbeg, l_tokenend;
1563 if (!l_BP.
GetNext(l_tokenbeg, l_tokenend,
';'))
1565 if (!
StringToUnits(std::string(l_tokenbeg, l_tokenend), rUnits))
1569 if (!l_BP.
GetNext(l_tokenbeg, l_tokenend,
';'))
1571 std::string l_RangeString(l_tokenbeg, l_tokenend);
1572 tFlux l_Range = stof(l_RangeString);
1578 if (!ParseMeasurements(l_BP, rUnits, rBx, ArbSelect.
NoMeasurements))
1586 if (!ParseMeasurements(l_BP, rUnits, rBy, ArbSelect.
NoMeasurements))
1594 if (!ParseMeasurements(l_BP, rUnits, rBz, ArbSelect.
NoMeasurements))
1599 if (!ApplyRotationMatrix(rBx, rBy, rBz))
1602 m_ErrorList.push_back(l_Error);
1609 if (!l_BP.
GetNext(l_tokenbeg, l_tokenend,
';'))
1611 std::string l_TemperatureString(l_tokenbeg, l_tokenend);
1612 rTemp =
static_cast<U16>(stoul(l_TemperatureString));
1616 rTimestampList.clear();
1620 if (!l_BP.
GetNext(l_tokenbeg, l_tokenend,
';'))
1622 std::string l_TimestampString(l_tokenbeg, l_tokenend);
1623 U64 l_LastTimestamp = std::stoull(l_TimestampString,
nullptr, 0);
1627 switch (m_TriggerParmsAtInit.Source)
1636 U64 l_TimeOffset =
static_cast<U64> (i * l_Period * 1E9 + 0.5);
1637 rTimestampList.push_back(l_LastTimestamp - l_TimeOffset);
1645 U64 l_TimeOffset =
static_cast<U64> (i * m_TriggerParmsAtInit.Period_s * 1E9 + 0.5);
1646 rTimestampList.push_back(l_LastTimestamp - l_TimeOffset);
1653 auto l_LastTriggerTime = m_TriggerTimes.back();
1654 for (
auto l_pTime = m_TriggerTimes.begin(); l_pTime < m_TriggerTimes.begin() + ArbSelect.
NoMeasurements; l_pTime++)
1656 std::chrono::nanoseconds l_TimeOffset = l_LastTriggerTime - *l_pTime;
1657 rTimestampList.push_back(l_LastTimestamp - l_TimeOffset.count());
1665 if (pMeasurementConditions)
1668 switch (m_TriggerParmsAtInit.Source)
1677 m_TriggerParmsAtInit.Period_s *= 1E-9;
1682 pMeasurementConditions->
TriggerParms = m_TriggerParmsAtInit;
1685 pMeasurementConditions->
Range = l_Range;
1698template <
class InstrType,
class RsrcMgrType>
1704 std::string l_Command;
1709 l_Command +=
":FORM ASC";
1712 l_Command +=
":FORM INT";
1715 l_Command +=
":FORM PACK,2";
1718 l_Command +=
":FORM PACK,1";
1730 m_ErrorList = l_ErrorList;
1735template <
class InstrType,
class RsrcMgrType>
1744 std::string l_Command =
":FORM?";
1749 std::string l_Format = std::string(m_ReadBuffer.begin(), m_ReadBuffer.end());
1750 if (std::string(
"ASCII") == l_Format)
1752 else if (std::string(
"INTEGER") == l_Format)
1754 else if (std::string(
"PACKED,2") == l_Format)
1756 else if (std::string(
"PACKED,1") == l_Format)
1772template <
class InstrType,
class RsrcMgrType>
1774 bool DefaultParms,
eUnits Units,
tFlux ExpectedField,
unsigned int NoDigits)
1776 MTL_INSTRUMENT_THM1176_DEBUG_COUT(MTL__FUNCTION_NAME__ <<
" default=" << DefaultParms <<
" units=" << Units <<
" expect=" << ExpectedField <<
" ndigits=" << NoDigits << std::endl);
1783 l_Command += DefaultParms ?
";:MEAS:X?" :
";:READ:X?";
1784 if (ExpectedField > 0.f || NoDigits != 0) l_Command +=
" ";
1785 if (ExpectedField > 0.f) l_Command +=
l_ToString(ExpectedField);
1786 if (NoDigits != 0) l_Command +=
"," + std::to_string(NoDigits);
1787 l_Command +=
";:FETC:Y?";
1788 if (NoDigits != 0) l_Command +=
" " + std::to_string(NoDigits);
1790 if (NoDigits != 0) l_Command +=
" " + std::to_string(NoDigits);
1791 if (m_Sleep) l_Command +=
";:SYST:SLEE";
1800 if (!ParseMeasurements(l_BP, Units, l_Meas, 1))
1805 if (!ParseMeasurements(l_BP, Units, l_Meas, 1))
1810 if (!ParseMeasurements(l_BP, Units, l_Meas, 1))
1815 if (!ApplyRotationMatrix(rBx, rBy, rBz))
1818 m_ErrorList.push_back(l_Error);
1830template <
class InstrType,
class RsrcMgrType>
1832 bool DefaultParms,
eUnits Units,
tFlux ExpectedField,
unsigned int NoDigits)
1834 MTL_INSTRUMENT_THM1176_DEBUG_COUT(MTL__FUNCTION_NAME__ <<
" nmeas=" << NoMeasurements <<
" default=" << DefaultParms <<
" units=" << Units <<
" expect=" << ExpectedField <<
" ndigits=" << NoDigits << std::endl);
1841 l_Command += (DefaultParms ?
";:MEAS:ARR:X? " :
";:READ:ARR:X? ") +
1842 std::to_string(NoMeasurements);
1843 if (ExpectedField > 0.f || NoDigits != 0) l_Command +=
",";
1844 if (ExpectedField > 0.f) l_Command +=
l_ToString(ExpectedField);
1845 if (NoDigits != 0) l_Command +=
"," + std::to_string(NoDigits);
1846 l_Command +=
";:FETC:ARR:Y? " + std::to_string(NoMeasurements);
1847 if (NoDigits != 0) l_Command +=
"," + std::to_string(NoDigits);
1848 l_Command +=
";Z? " + std::to_string(NoMeasurements);
1849 if (NoDigits != 0) l_Command +=
"," + std::to_string(NoDigits);
1850 if (m_Sleep) l_Command +=
";:SYST:SLEE";
1859 if (!ParseMeasurements(l_BP, Units, rBx, NoMeasurements))
1863 if (!ParseMeasurements(l_BP, Units, rBy, NoMeasurements))
1867 if (!ParseMeasurements(l_BP, Units, rBz, NoMeasurements))
1871 if (!ApplyRotationMatrix(rBx, rBy, rBz))
1874 m_ErrorList.push_back(l_Error);
1889template <
class InstrType,
class RsrcMgrType>
1898template <
class InstrType,
class RsrcMgrType>
1904 m_ErrorList.clear();
1908 if (0 == l_Command.size())
1911 if (!InstrType::Write(l_Command) ||
1912 !InstrType::Read(m_ReadBuffer) ||
1913 !GetErrorList(m_ErrorList, l_Command))
1916 rStatus =
static_cast<U16>(std::stoi(std::string(m_ReadBuffer.begin(), m_ReadBuffer.end())));
1928template <
class InstrType,
class RsrcMgrType>
1934 m_ErrorList.clear();
1937 std::string l_CompleteCommand;
1938 for (
auto l_Reg : Regs)
1941 if (0 == l_Command.size())
1943 if (l_CompleteCommand.size() > 0) l_CompleteCommand +=
";";
1944 l_CompleteCommand += l_Command;
1947 if (!InstrType::Write(l_CompleteCommand) ||
1948 !InstrType::Read(m_ReadBuffer) ||
1949 !GetErrorList(m_ErrorList, l_CompleteCommand))
1955 std::vector<char>::const_iterator l_tokenbeg, l_tokenend;
1957 for (
size_t i = Regs.size(); i > 0; i--)
1959 if (!l_BP.
GetNext(l_tokenbeg, l_tokenend,
';'))
1961 rStatus.push_back(
static_cast<U16>(std::stoi(std::string(l_tokenbeg, l_tokenend))));
1973template <
class InstrType,
class RsrcMgrType>
1986 U16 l_StatusEnab =
static_cast<U16>(std::stoi(std::string(m_ReadBuffer.begin(), m_ReadBuffer.end())));
1989 l_StatusEnab &= ~DisableMask;
1990 l_StatusEnab |= EnableMask;
2009template <
class InstrType,
class RsrcMgrType>
2015 rIdentification = m_Identification;
2019template <
class InstrType,
class RsrcMgrType>
2025 rIdentification = m_IdentificationStruct;
2029template <
class InstrType,
class RsrcMgrType>
2036 for (
auto l_Range : m_Ranges)
2037 rRanges.push_back(l_Range);
2041template <
class InstrType,
class RsrcMgrType>
2048 for (
auto l_Unit : m_Units)
2049 rUnits.push_back(l_Unit.first);
2053template <
class InstrType,
class RsrcMgrType>
2061 rDivisor = m_Units.at(Units);
2063 catch (
const std::out_of_range& oor)
2073template <
class InstrType,
class RsrcMgrType>
2076 Matrix = m_RotationMatrix;
2080template <
class InstrType,
class RsrcMgrType>
2106template <
class InstrType,
class RsrcMgrType>
2113 if (!ForceCalibration &&
2117 m_ErrorList.clear();
2141 if (!InstrType::SetTimeout(m_Timeout))
2158 m_ErrorList = l_ErrorList;
2160 InstrType::SetTimeout(m_Timeout);
2166template <
class InstrType,
class RsrcMgrType>
2172 m_ErrorList.clear();
2184 if (!InstrType::SetTimeout(m_Timeout))
2191 InstrType::SetTimeout(m_Timeout);
2197template <
class InstrType,
class RsrcMgrType>
2204 m_TriggerTimes.clear();
2205 m_ErrorList.clear();
2207 m_UseCalibration =
true;
2208 m_AbortRead =
false;
2213 if (!InstrType::Write(
"*RST;*CLS"))
2217 if (!ReadUseCalibration(m_UseCalibration))
2237 ReadUseCalibration(m_UseCalibration);
2243 m_ErrorList = l_ErrorList;
2250template <
class InstrType,
class RsrcMgrType>
2256 m_ErrorList.clear();
2257 return InstrType::Write(
":DIAG:UPGR");
2260template <
class InstrType,
class RsrcMgrType>
2269 rSManufacturingDate = m_ManufacturingDate;
2272 std::match_results<std::string::const_iterator> l_Mm;
2273 if (!std::regex_match(rSManufacturingDate, l_Mm, std::regex(
"^([0-9]{4})-([0-9]{2})-([0-9]{2})")))
2275 struct std::tm l_ManDateStruct = { };
2276 l_ManDateStruct.tm_year = std::stoi(l_Mm[1]) - 1900;
2277 l_ManDateStruct.tm_mon = std::stoi(l_Mm[2]) - 1;
2278 l_ManDateStruct.tm_mday = std::stoi(l_Mm[3]);
2279 if ((rManufacturingDate = mktime(&l_ManDateStruct)) < 0)
2283 rSCalibrationDate = m_CalibrationDate;
2286 std::match_results<std::string::const_iterator> l_Cm;
2287 if (!std::regex_match(rSCalibrationDate, l_Cm, std::regex(
"^([0-9]{4})-([0-9]{2})-([0-9]{2})")))
2289 struct tm l_CalDateStruct = { };
2290 l_CalDateStruct.tm_year = std::stoi(l_Cm[1]) - 1900;
2291 l_CalDateStruct.tm_mon = std::stoi(l_Cm[2]) - 1;
2292 l_CalDateStruct.tm_mday = std::stoi(l_Cm[3]);
2293 if ((rCalibrationDate = mktime(&l_CalDateStruct)) < 0)
2300 rSManufacturingDate.clear();
2301 rManufacturingDate = -1;
2302 rSCalibrationDate.clear();
2303 rCalibrationDate = -1;
2306 catch (std::regex_error& rE)
2315template <
class InstrType,
class RsrcMgrType>
2329 U32 l_CurrentTimeout = InstrType::GetTimeout();
2330 std::this_thread::sleep_for(std::chrono::milliseconds(2 * l_CurrentTimeout));
2340 m_AbortRead =
false;
Exception handling utilities.
Collection of utility macros for error messages.
Platform Dependent Definitions.
unsigned long long U64
64-bit unsigned integer.
unsigned char U8
Unsigned byte.
float F32
32-bit floating-point number.
int I32
32-bit signed integer.
unsigned int U32
32-bit unsigned integer.
double F64
64-bit floating-point number.
unsigned short U16
16-bit unsigned integer.
Utilities to aid in sending SCPI commands and parsing of SCPI reponses.
static const F64 THM1176_IMMEDIATE_TIME_PER_ACQ_A(1.0281823091218700E-04)
static const U32 THM1176_CALIBRATION_TIMEOUT(30000)
static const std::string THM1176_INFO_FILE_NAME("info.dat")
static std::string l_ParseRegexError(std::regex_error &rE)
static const F64 THM1176_IMMEDIATE_TIME_PER_MEAS_B(0.0000285930870825438)
#define MTL_INSTRUMENT_THM1176_DEBUG_COUT(__X__)
static std::string l_ToString(F32 number, int precision=7, const char *locale="C")
#define MTL_INSTRUMENT_THM1176_DEBUG_CERR(__X__)
static const U32 THM1176_FILE_ACCESS_TIMEOUT(20000)
static const std::set< std::string > MODELS_NOT_TO_CALIBRATE
static const F64 THM1176_IMMEDIATE_TIME_PER_ACQ_B(0.0000116103073008506)
static const char * STATUS_SET_CMDS[4][3]
static const I32 THM1176_ERROR_CODE_MEAS_OVERRANGE(205)
static const U32 THM1176_CAL_FILE_OFFSET_VERSION(32)
static const std::string THM1176_CALIBRATION_FILE_NAME("cal.dat")
static const U32 THM1176_CAL_FILE_OFFSET_MATRIX_V2(116)
static const I32 THM1176_FATAL_ERROR_CODE_LIMIT(200)
static void l_ParseErrorString(std::string &rErrStr, const std::string &rContext, sError &rError)
static const F64 THM1176_IMMEDIATE_TIME_PER_MEAS_A(4.4532792007542600E-05)
static const char * STATUS_GET_CMDS[4][3]
Interface definition for C++ API for Metrolab THM1176/TFM1186.
#define THM1176_SUPPORTED_VERSION_MIN_MAJOR
#define THM1176_SUPPORTED_VERSION_MIN_MINOR
Type conversion routines for C++ API for Metrolab THM1176/TFM1186.
virtual const char * what() const noexcept
Return string describing what happened.
void resize(size_t size)
Resize the buffer.
std::vector< MTL_INSTRUMENT_BUFFER_TYPE >::iterator end()
Return an iterator to the end of the buffer.
void clear()
Clear by setting the buffer size to zero.
std::vector< MTL_INSTRUMENT_BUFFER_TYPE >::iterator begin()
Return an iterator to the beginning of the buffer.
size_t size() const
Return the buffer size.
bool GetNext(std::vector< char >::const_iterator &rNextBegin, std::vector< char >::const_iterator &rNextEnd, const char Separator=';')
Find the next token.
const tTokens Tokenize(const char Separator=';', size_t Offset=0)
Split the buffer into tokens.
std::vector< sToken > tTokens
List of tokens.
std::vector< char >::const_iterator end()
Return the end of the data to be parsed.
void SetNextOffset(std::vector< char >::const_iterator Offset)
Manually set the offset to the next token.
bool StatusPreset()
Reset OPERation and QUEStionable enable registers.
bool ParmAveragingGet(sAveraging< uParm > &rAvg)
Fetch the currently selected averaging parameter.
bool GetIdentification(std::string &rIdentification)
Fetch the intrument's identification string.
bool ReadFileDirectory(U32 &rUsedBytes, U32 &rAvailableBytes, tFileList &rFileList)
Read the instrument's file directory information.
bool StatusGet(sStatusRegister Reg, U16 &rStatus)
Fetch current value of a single status register.
virtual ~CTHM1176Instrument()
Destructor.
bool ParmUseCalibrationGet(bool &rUseCal)
Fetch parameter whether to return calibrated results.
bool Initiate(bool Continuous=false)
Initiate measurements.
bool GetAllRanges(CFluxList &rRanges)
Fetch all the intrument's ranges.
bool ParmUnitsGet(eUnits &rUnits)
Fetch currently selected measurement units.
bool SetFormat(eCommunicationFormat Format)
Select whether data is returned as text or binary.
bool ParmSleepGet(bool &rSleep)
Fetch parameter whether to sleep after each acquisition.
bool ParmRangeSet(const sRange< uParm > &rRange)
Set measurement range.
bool Abort(void)
Abort a measurement in progress.
bool ReadInformationDates(std::string &rSManufacturingDate, std::time_t &rManufacturingDate, std::string &rSCalibrationDate, std::time_t &rCalibrationDate)
Fetch the intrument's date information.
bool Connect(U32 InitialTimeout, bool Exclusive=true, std::string *pErrMsg=nullptr)
Open the connection to the instrument.
bool Measure(tFlux &rBx, tFlux &rBy, tFlux &rBz, bool DefaultParms=true, eUnits Units=kT, tFlux ExpectedField=0., unsigned int NoDigits=0)
High-level measurement: single measurement.
void Disconnect()
Close the connection to the instrument.
CTHM1176Instrument(RsrcMgrType &rResourceManager, tResourceName ResourceName)
Constructor.
bool ParmTriggerInputSet(const sInputTrigger< uParm > &rInputTrig)
Set trigger input parameters.
bool GetDivisor(eUnits Units, U32 &rDivisor)
Fetch divisor to convert instrument's base units to given units.
bool ParmRangeGet(sRange< uParm > &rRange)
Fetch currently selected measurement range.
bool AbortRead()
Abort a read operation.
bool StatusSetEnableRegister(eStatusRegisterSet Set, U16 DisableMask, U16 EnableMask)
Disable and enable bits in the given enable register.
bool WriteAndRead(const std::string &rWriteStr, CSCPIBuffer &rReadBuffer)
bool ParmUnitsSet(eUnits Units)
Set measurement units.
bool GetImmediateMeasurementPeriod(const sAveraging< uParm > &rAvg, eModelRevision modelRev, F64 &rPeriod)
Compute measurement interval for Immediate Trigger, for a given averaging parameter.
bool ReadFile(std::string Path, std::string &rContent)
Read a file from the instrument's file system.
bool ParmAveragingSet(const sAveraging< uParm > &rAvg)
Set the averaging parameter.
bool Reset()
Reset the instrument to power-on configuration.
bool SendBusTrigger()
Send a USB bus trigger.
bool CalibrateZeroOffset(bool ForceCalibration=false)
Perform the Zero Offset calibration procedure.
bool ParmSleepSet(bool Sleep)
Set parameter whether to sleep after each acquisition.
bool ParmTriggerInputGet(sInputTrigger< uParm > &rInputTrig)
Fetch current trigger input parameters.
bool SwitchToDFUMode()
Enter the Device Firmware Upgrade mode.
bool GetAllUnits(CUnitsList &rUnits)
Fetch all units supported by instrument.
bool ParmUseCalibrationSet(bool UseCal)
Set whether to return calibrated results.
bool GetRotationMatrix(Matrix3f &Matrix)
Fetch the intrument's rotation matrix, to correct angular error.
bool RestoreZeroOffset()
Restore the factory values for the Zero Offset.
bool GetFormat(eCommunicationFormat &Format)
Retrieve whether data is returned as text or binary.
const CErrorList & CurrentErrorList()
Fetch current error list.
bool MeasurementsGet(U32 NoMeasurements, CFluxList &rBx, CFluxList &rBy, CFluxList &rBz, eUnits &rUnits, U16 &rTemp, CTimestampList &rTimestampList, sMeasurementConditions *pMeasurementConditions=NULL)
Retrieve measurements: short form.
void ClearErrorList()
Clear the error list.
Timestamp for a measurement.
void clear(void)
Clear to default values (zeroes).
List of errors returned by the instrument.
List of flux density values.
bool GetEstimatedPeriod(F64 &Period)
Estimate the measurement period from this timestamp list, by means of a least-squares fit.
List of measurement units.
List of SCPI status registers.
List of values returned for several SCPI status registers.
I32 BinaryToI32(const char pBinary[4])
Convert binary to I32, taking into account endedness.
@ kStatusEnable
Enable register.
std::string UnitsToString(eUnits Units)
Convert measurement units from enumeration to string.
F32 tFlux
Flux density value, as 32-bit floating-point number.
I16 BinaryToI16(const char pBinary[2])
Convert binary to I16, taking into account endedness.
eCommunicationFormat
Enumeration of possible formats for returned data.
@ kComFormatInteger
Binary (32-bit integers).
@ kComFormatPacked2Byte
Binary packed: first field value as I32, remainder deltas as I16.
@ kComFormatPacked1Byte
Binary packed: first field value as I32, remainder deltas as I8.
@ kComFormatAscii
Human-legible text.
std::vector< sFile > tFileList
List of directory entries.
eModelRevision
THM1176 type A or B.
@ kInputTrigSrcTimer
Timed trigger: start measurement at regular intervals.
@ kInputTrigSrcImmediate
Immediate trigger: start measurement immediately after previous one completes.
@ kInputTrigSrcBus
Bus trigger: start measurement upon USB trigger message.
bool StringToUnits(std::string SUnits, eUnits &rUnits)
Convert measurement units from string to enumeration.
eUnits
Enumeration of possible measurement units.
eStatusRegisterSet
Enumeration of SCPI status register sets.
std::string tResourceName
IEEE488 resource name.
static const I32 THM1176_NO_ANGLE_CORRECTION_CODE
Warning that angle correction was not applied.
bool IsArbitraryBlock(const iterator_type first, const iterator_type last, size_t &rStartOffset, size_t &rLength)
Find arbitrary-block data within a buffer.
Specify the measurement data to be returned.
bool Bx
Return the flux density X-component.
bool Temperature
Return the sensor temperature.
bool By
Return the flux density Y-component.
bool Bz
Return the flux density Z-component.
bool Timestamp
Return the timestamp.
U32 NoMeasurements
Return this number of measurements.
ParmType< U16 > NoPoints
Number of points in block average.
Error returned by the instrument.
std::string Context
SCPI commands being executed at time of error.
std::string Description
Error description.
Directory entry in the instrument's file system.
std::string Path
File path.
std::string Type
File type ("ASCII" or "BINARY").
size_t Size
File size, in bytes.
Instrument's identification string - parsed version.
struct sVersion FirmwareVersion
Version numbers of firmware.
std::string Manufacturer
Manufacturer name ("Metrolab Technology SA").
struct sVersion ElectronicsVersion
Version numbers of electronics.
U32 SerialNumber
Serial number.
struct sVersion ProbeVersion
Version numbers of probe.
std::string Model
Model name (e.g. "THM1176-MF").
enum eInstrModel InstrModel
Enumerator of instrument model.
enum eModelRevision ModelRevision
Revision of Model.
Summary of the parameters used to make a measurement.
bool UseCalibration
Use calibration data.
tFlux Range
Current range setting.
sAveraging< uParm > AveragingParms
Averaging parameters.
sInputTrigger< uParm > TriggerParms
Trigger parameters.
Measurement range parameter.
bool Auto
Auto-ranging enabled.
ParmType< tFlux > Range
Measurement range, if auto-ranging is not enabled.
Complete identification of a SCPI status register.
eStatusRegisterSet Set
SCPI register set.
eStatusRegisterType Type
SCPI register type.
std::string Name
Version name.
U8 Minor
Minor version number.
U8 Major
Major version number.
U8 EAV
Error Available in Error / Event Queue.
Union to access the Status Byte as integer or bit fields.
struct MTL::Instrument::THM1176Types::uStatusByte::sStatusByte StatusByte
Access the Status Byte as bit fields.
U16 RawSTB
Access the Status Byte as unsigned integer.