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__)
56 {
"",
"",
":STAT:QUES:ENAB" },
57 {
"",
"",
":STAT:OPER:ENAB" }
62 {
"*STB?",
"",
"*SRE?" },
63 {
"*ESR?",
"",
"*ESE?" },
64 {
":STAT:QUES:EVEN?",
":STAT:QUES:COND?",
":STAT:QUES:ENAB?" },
65 {
":STAT:OPER:EVEN?",
":STAT:OPER:COND?",
":STAT:OPER:ENAB?" }
70 std::string(
"TFM1186")
86static std::string
l_ToString(
F32 number,
int precision = 7,
const char * locale =
"C")
88 std::locale l_locale = std::locale(locale);
89 std::ostringstream l_oss;
91 l_oss.imbue(l_locale);
92 l_oss << std::scientific << std::setprecision(precision);
98static std::string
l_ToString(
F64 number,
int precision = 15,
const char * locale =
"C")
100 std::locale l_locale = std::locale(locale);
101 std::ostringstream l_oss;
103 l_oss.imbue(l_locale);
104 l_oss << std::scientific << std::setprecision(precision);
116 size_t l_Comma = rErrStr.find_first_of(
',');
117 rError.
Code = std::stoi(rErrStr.substr(0, l_Comma));
119 size_t l_OpenQuote = rErrStr.find_first_of(
'"', l_Comma + 1);
120 size_t l_CloseQuote = rErrStr.find_last_of(
'"');
121 rError.
Description = rErrStr.substr(l_OpenQuote + 1, l_CloseQuote - (l_OpenQuote + 1));
127 std::vector<std::string> lErrorList;
128 if (rE.code() & std::regex_constants::error_badrepeat)
129 lErrorList.push_back (
"error_badrepeat");
130 if (rE.code() & std::regex_constants::error_ctype)
131 lErrorList.push_back (
"error_ctype");
132 if (rE.code() & std::regex_constants::error_escape)
133 lErrorList.push_back (
"error_escape");
134 if (rE.code() & std::regex_constants::error_backref)
135 lErrorList.push_back (
"error_backref");
136 if (rE.code() & std::regex_constants::error_brack)
137 lErrorList.push_back (
"error_brack");
138 if (rE.code() & std::regex_constants::error_paren)
139 lErrorList.push_back (
"error_paren");
140 if (rE.code() & std::regex_constants::error_brace)
141 lErrorList.push_back (
"error_brace");
142 if (rE.code() & std::regex_constants::error_badbrace)
143 lErrorList.push_back (
"error_badbrace");
144 if (rE.code() & std::regex_constants::error_range)
145 lErrorList.push_back (
"error_range");
146 if (rE.code() & std::regex_constants::error_space)
147 lErrorList.push_back (
"error_space");
148 if (rE.code() & std::regex_constants::error_badrepeat)
149 lErrorList.push_back (
"error_badrepeat");
150 if (rE.code() & std::regex_constants::error_complexity)
151 lErrorList.push_back (
"error_complexity");
152 if (rE.code() & std::regex_constants::error_stack)
153 lErrorList.push_back (
"error_stack");
155 std::string lErrors = lErrorList.front();
156 for (
auto lpError = lErrorList.begin() + 1; lpError < lErrorList.end(); lpError++)
157 lErrors +=
" | " + *lpError;
164template <
class InstrType,
class RsrcMgrType>
165bool CTHM1176Instrument<InstrType, RsrcMgrType>::ReadIdentification(std::string & rIdentification)
175 rIdentification = std::string(m_ReadBuffer.begin(), m_ReadBuffer.end());
181 rIdentification.clear();
187template <
class InstrType,
class RsrcMgrType>
188bool CTHM1176Instrument<InstrType, RsrcMgrType>::ParseIdentification(
struct sIdentifier & rIdentification)
194 std::regex l_Regex(
"([^,]+),([^,]+),([^,]+),([^,]+)");
196 if (!std::regex_match(m_Identification, l_Match, l_Regex))
200 rIdentification.
Model = l_Match[2].str();
201 rIdentification.
SerialNumber =
static_cast<U32>(stoul(l_Match[3].str()));
203 std::string l_Versions = l_Match[4].str();
204 l_Regex =
"el(([A-Z])([0-9]+))-pr(([A-Z]?)([0-9]+))-fw(([0-9]+)\\.([0-9]+))\\n";
205 if (!std::regex_match(l_Versions, l_Match, l_Regex))
222 std::map<std::string, eInstrModel> l_InstModel =
230 auto l_pInstrModel = l_InstModel.find(rIdentification.
Model);
231 if (l_pInstrModel == l_InstModel.cend())
238 rIdentification.
InstrModel = l_pInstrModel->second;
247 catch (std::regex_error& rE)
256template <
class InstrType,
class RsrcMgrType>
257bool CTHM1176Instrument<InstrType, RsrcMgrType>::GetErrorList(
CErrorList & rList,
const std::string & rContext)
266 if (!InstrType::ReadSTB(l_STB.
RawSTB))
274 enum eRetry { kRetryErrorRetrieving };
277 if (!InstrType::Write(
":SYST:ERR?"))
278 throw kRetryErrorRetrieving;
279 if (!InstrType::Read(l_Error))
280 throw kRetryErrorRetrieving;
282 catch (eRetry & rRetry)
284 if (rRetry == kRetryErrorRetrieving)
287 if (!InstrType::Clear())
290 if (!InstrType::Write(
":SYST:ERR?"))
292 if (!InstrType::Read(l_Error))
297 std::string l_ErrStr = std::string(l_Error.data(), l_Error.size());
300 rList.push_back(l_Err);
302 if (!InstrType::ReadSTB(l_STB.
RawSTB))
314 for (
auto it = rList.begin(); it != rList.end(); it++)
316 CERR(
"THM1176Error " << it->Code <<
" : " << it->Description <<
" in " << it->Context << std::endl);
322template <
class InstrType,
class RsrcMgrType>
328 bool l_InitialLockState = InstrType::LockedExclusive();
335 if (!l_InitialLockState && !InstrType::LockExclusive(m_Timeout))
340 bool l_OPCAppended = !std::regex_match(rWriteStr, std::regex(
"\\*IDN\\?"));
343 l_Query = rWriteStr +
";*OPC?";
348 if (!InstrType::Write(l_Query))
353 if (!InstrType::ReadSTB(l_STB.
RawSTB))
360 bool l_Timeout =
false;
367 if (InstrType::Read(rReadBuffer,
true))
373 l_Timeout = InstrType::Timeout();
378 if (!InstrType::ReadSTB(l_STB.
RawSTB))
389 std::size_t l_MaxSizeToMatch = std::strlen(
";1\n");
390 std::match_results<std::vector<char>::iterator> m;
392 if (std::regex_match((rReadBuffer.
size() <= l_MaxSizeToMatch) ? rReadBuffer.
begin() : rReadBuffer.
end() - l_MaxSizeToMatch, rReadBuffer.
end(), m, std::regex(
";?1\\n?$")))
393 rReadBuffer.
resize(rReadBuffer.
size() - m.length());
397 if (!l_InitialLockState && !InstrType::Unlock())
408 InstrType::Write(
":ABOR");
415 InstrType::Read(rReadBuffer,
true);
418 GetErrorList(m_ErrorList, rWriteStr);
421 if (!l_InitialLockState) InstrType::Unlock();
428 catch (std::regex_error& rE)
437template <
class InstrType,
class RsrcMgrType>
438bool CTHM1176Instrument<InstrType, RsrcMgrType>::ReadBootTime(
CAbsoluteTimestamp & rBootTime)
446 if (!
WriteAndRead(
"*RST;:INIT;:FETC:TIM?", m_ReadBuffer))
448 std::string l_TimestampString(m_ReadBuffer.begin(), m_ReadBuffer.end());
449 U64 l_Timestamp = std::stoull(l_TimestampString,
nullptr, 0);
453 std::time_t l_CurrentTime = std::time(
nullptr);
468template <
class InstrType,
class RsrcMgrType>
469bool CTHM1176Instrument<InstrType, RsrcMgrType>::ReadAllRanges(
CFluxList & rRanges)
481 if (l_Tokens.size() < 1)
486 for (
auto it = l_Tokens.begin(); it != l_Tokens.end(); it++)
488 std::string l_StrRange(it->begin, it->end - 2);
491 rRanges.push_back(std::stof(l_StrRange));
493 catch (
const std::invalid_argument& ia)
509template <
class InstrType,
class RsrcMgrType>
510bool CTHM1176Instrument<InstrType, RsrcMgrType>::ReadAllUnits(std::map<eUnits,U32> & rAllUnits)
517 if (!WriteAndRead(
":UNIT:ALL?", m_ReadBuffer))
522 if (l_Tokens.size() < 2 || (l_Tokens.size() % 2) == 1)
527 for (
auto it = l_Tokens.begin(); it != l_Tokens.end(); it++)
529 std::string l_StrUnit(it->begin, it->end);
531 std::string l_StrDivisor(it->begin, it->end);
535 U32 l_Divisor =
static_cast<U32>(std::stoul(l_StrDivisor));
536 rAllUnits.insert(std::pair<eUnits, U32>(l_Units, l_Divisor));
549template <
class InstrType,
class RsrcMgrType>
550bool CTHM1176Instrument<InstrType, RsrcMgrType>::ReadUseCalibration(
bool & rUseCal)
557 if (!WriteAndRead(
":CAL:STAT?", m_ReadBuffer))
560 std::string l_Answer(m_ReadBuffer.begin(), m_ReadBuffer.end());
561 if (l_Answer ==
"ON")
563 else if (l_Answer ==
"OFF")
577template <
class InstrType,
class RsrcMgrType>
578bool CTHM1176Instrument<InstrType, RsrcMgrType>::ReadManufacturingDate(std::string & rDate)
582 std::string l_CalFileContent;
589 rDate = std::string(l_CalFileContent, 100, 10);
602template <
class InstrType,
class RsrcMgrType>
603bool CTHM1176Instrument<InstrType, RsrcMgrType>::ReadRotationMatrix(Matrix3f & rMatrix, std::string & rCalibrationDate)
607 std::string l_CalFileContent;
614 rCalibrationDate = std::string(l_CalFileContent, 64, 10);
617 char * l_pMatrix =
const_cast<char *
>(l_CalFileContent.c_str());
628 I32 l_IntMatrix[3][3];
629 for (
int i = 0; i < 3; i++)
630 for (
int j = 0; j < 3; j++)
633 l_pMatrix +=
sizeof (
I32);
637 const F32 l_C =
static_cast<F32>(0x7FFFFFFF);
638 rMatrix << l_IntMatrix[0][0]/l_C, l_IntMatrix[0][1]/l_C, l_IntMatrix[0][2]/l_C,
639 l_IntMatrix[1][0]/l_C, l_IntMatrix[1][1]/l_C, l_IntMatrix[1][2]/l_C,
640 l_IntMatrix[2][0]/l_C, l_IntMatrix[2][1]/l_C, l_IntMatrix[2][2]/l_C;
646 rCalibrationDate =
"";
652template <
class InstrType,
class RsrcMgrType>
653bool CTHM1176Instrument<InstrType, RsrcMgrType>::ApplyRotationMatrix(
tFlux & rBx,
tFlux & rBy,
tFlux & rBz)
658 if (!m_UseCalibration)
662 Vector3f l_B(rBx, rBy, rBz);
663 l_B = m_RotationMatrix * l_B;
678template <
class InstrType,
class RsrcMgrType>
684 if (!m_UseCalibration)
688 if (rBx.size() != rBy.size() || rBx.size() != rBz.size())
694 for (
auto l_pBx = rBx.begin(), l_pBy = rBy.begin(), l_pBz = rBz.begin();
696 l_pBx++, l_pBy++, l_pBz++)
698 Vector3f l_B(*l_pBx, *l_pBy, *l_pBz);
699 l_B = m_RotationMatrix * l_B;
714template <
class InstrType,
class RsrcMgrType>
721 std::vector<char>::const_iterator l_tokenbeg, l_tokenend;
722 if (!rBP.
GetNext(l_tokenbeg, l_tokenend,
';'))
733 tFlux l_DivisorReal = 1.;
734 if (m_UseCalibration)
735 l_DivisorReal =
static_cast<tFlux>(m_Units.at(Units));
738 if (l_tokenbeg[1] ==
'6')
741 l_len >= 4 && rMeas.size() < NoMeasurements;
742 l_len -= 4, l_off += 4)
745 rMeas.push_back(
static_cast<tFlux>(l_MeasI32) / l_DivisorReal);
750 else if (l_tokenbeg[1] ==
'5')
753 size_t l_Pack = (l_tokenbeg[l_off] ==
'1') ? 1 :
754 (l_tokenbeg[l_off] ==
'2') ? 2 : 0;
761 rMeas.push_back(
static_cast<tFlux>(l_MeasI32) / l_DivisorReal);
764 for (l_len -= 4, l_off += 4;
765 l_len >= l_Pack && rMeas.size() < NoMeasurements;
766 l_len -= l_Pack, l_off += l_Pack)
769 l_MeasI32 +=
static_cast<I8>(*(&*l_tokenbeg + l_off));
772 rMeas.push_back(
static_cast<tFlux>(l_MeasI32) / l_DivisorReal);
783 std::vector<char>::const_iterator l_measbeg, l_measend;
785 for (l_GetNextRet = l_FluxParser.GetNext(l_measbeg, l_measend,
',');
786 l_GetNextRet && rMeas.size() < NoMeasurements;
787 l_GetNextRet = l_FluxParser.GetNext(l_measbeg, l_measend,
','))
789 std::string l_Measurement(l_measbeg, l_measend);
790 rMeas.push_back(std::stof(l_Measurement));
795 if (rMeas.size() != NoMeasurements)
811template <
class InstrType,
class RsrcMgrType>
813: InstrType(rResourceManager, ResourceName),
814 m_Timeout(0), m_ReadBuffer(65535), m_Sleep(false), m_UseCalibration(true), m_AbortRead(false)
818template <
class InstrType,
class RsrcMgrType>
821 if (InstrType::IsOpen())
831template <
class InstrType,
class RsrcMgrType>
837template <
class InstrType,
class RsrcMgrType>
849template <
class InstrType,
class RsrcMgrType>
864 m_Timeout = InitialTimeout;
865 if (!InstrType::Open())
867 if (Exclusive && !InstrType::LockExclusive(m_Timeout))
869 if (!InstrType::Clear())
873 if (!ReadIdentification(m_Identification))
875 if (!ParseIdentification(m_IdentificationStruct))
877 if ((m_IdentificationStruct.Model ==
"THM1176-A") && (m_IdentificationStruct.FirmwareVersion.Major < l_MinMajor || m_IdentificationStruct.FirmwareVersion.Minor < l_MinMinor))
879 if (!ReadBootTime(m_BootTime))
881 if (!ReadAllUnits(m_Units))
883 if (!ReadAllRanges(m_Ranges))
885 if (!ReadManufacturingDate(m_ManufacturingDate))
887 if (!ReadRotationMatrix(m_RotationMatrix, m_CalibrationDate))
889 if (!ReadUseCalibration(m_UseCalibration))
907 if (pErrMsg !=
nullptr)
908 *pErrMsg = rE.
what();
909 if (InstrType::IsOpen())
916template <
class InstrType,
class RsrcMgrType>
922 if (InstrType::IsOpen())
929template <
class InstrType,
class RsrcMgrType>
935 std::string l_Command =
":AVER:COUN " + std::to_string(rAvg.
NoPoints);
937 if (l_Success) m_AveragingParms = rAvg;
941template <
class InstrType,
class RsrcMgrType>
952 rAvg.
NoPoints =
static_cast<U16>(std::stoi(std::string(m_ReadBuffer.begin(), m_ReadBuffer.end())));
963template <
class InstrType,
class RsrcMgrType>
971 if (!
WriteAndRead(
":AVER:COUN?;:AVER:COUN? MIN;:AVER:COUN? MAX;:AVER:COUN? DEF", m_ReadBuffer))
976 if (l_Tokens.size() != 4)
979 rAvg.
NoPoints.Val =
static_cast<U16>(std::stoi(std::string(l_Tokens[0].begin, l_Tokens[0].end)));
980 rAvg.
NoPoints.Min =
static_cast<U16>(std::stoi(std::string(l_Tokens[1].begin, l_Tokens[1].end)));
981 rAvg.
NoPoints.Max =
static_cast<U16>(std::stoi(std::string(l_Tokens[2].begin, l_Tokens[2].end)));
982 rAvg.
NoPoints.Def =
static_cast<U16>(std::stoi(std::string(l_Tokens[3].begin, l_Tokens[3].end)));
993template <
class InstrType,
class RsrcMgrType>
1003template <
class InstrType,
class RsrcMgrType>
1013template <
class InstrType,
class RsrcMgrType>
1019 std::string l_Command =
":TRIG:SOUR ";
1020 switch (rInputTrig.
Source)
1024 l_Command +=
";COUN " + std::to_string(rInputTrig.
Count);
1028 l_Command +=
";COUN " + std::to_string(rInputTrig.
Count);
1033 l_Command +=
";COUN " + std::to_string(rInputTrig.
Count);
1039 m_TriggerParms = rInputTrig;
1046 m_ErrorList = l_ErrorList;
1051template <
class InstrType,
class RsrcMgrType>
1067 if (l_Tokens.size() != 3)
1071 std::string l_Source(l_Tokens[0].begin, l_Tokens[0].end);
1072 if (l_Source ==
"IMMEDIATE")
1074 else if (l_Source ==
"TIMER")
1076 else if (l_Source ==
"BUS")
1082 rInputTrig.
Period_s = std::stod(std::string(l_Tokens[1].begin, l_Tokens[1].end));
1085 rInputTrig.
Count =
static_cast<U16>(std::stoi(std::string(l_Tokens[2].begin, l_Tokens[2].end)));
1096template <
class InstrType,
class RsrcMgrType>
1105 ";TIM?;TIM? MIN;TIM? MAX;TIM? DEF"
1106 ";COUN?;COUN? MIN;COUN? MAX;COUN? DEF",
1112 if (l_Tokens.size() != 9)
1116 std::string l_Source(l_Tokens[0].begin, l_Tokens[0].end);
1117 if (l_Source ==
"IMMEDIATE")
1119 else if (l_Source ==
"TIMER")
1121 else if (l_Source ==
"BUS")
1127 rInputTrig.
Period_s.Val = std::stod(std::string(l_Tokens[1].begin, l_Tokens[1].end));
1128 rInputTrig.
Period_s.Min = std::stod(std::string(l_Tokens[2].begin, l_Tokens[2].end));
1129 rInputTrig.
Period_s.Max = std::stod(std::string(l_Tokens[3].begin, l_Tokens[3].end));
1130 rInputTrig.
Period_s.Def = std::stod(std::string(l_Tokens[4].begin, l_Tokens[4].end));
1133 rInputTrig.
Count.Val =
static_cast<U16>(std::stoi(std::string(l_Tokens[5].begin, l_Tokens[5].end)));
1134 rInputTrig.
Count.Min =
static_cast<U16>(std::stoi(std::string(l_Tokens[6].begin, l_Tokens[6].end)));
1135 rInputTrig.
Count.Max =
static_cast<U16>(std::stoi(std::string(l_Tokens[7].begin, l_Tokens[7].end)));
1136 rInputTrig.
Count.Def =
static_cast<U16>(std::stoi(std::string(l_Tokens[8].begin, l_Tokens[8].end)));
1147template <
class InstrType,
class RsrcMgrType>
1157 m_UnitsParms = Units;
1164 m_ErrorList = l_ErrorList;
1169template <
class InstrType,
class RsrcMgrType>
1180 std::string l_Answer(m_ReadBuffer.begin(), m_ReadBuffer.end());
1193template <
class InstrType,
class RsrcMgrType>
1199 std::string l_Command = std::string(
":CAL:STAT ") + (UseCal ?
"ON" :
"OFF");
1203 m_UseCalibration = UseCal;
1210template <
class InstrType,
class RsrcMgrType>
1216 rUseCal = m_UseCalibration;
1220template <
class InstrType,
class RsrcMgrType>
1226 std::string l_Command;
1228 l_Command =
":SENS:AUTO ON";
1230 l_Command =
":SENS:AUTO OFF;:SENS " +
l_ToString(rRange.
Range, 1) +
" T";
1234 m_RangeParms = rRange;
1241 m_ErrorList = l_ErrorList;
1246template <
class InstrType,
class RsrcMgrType>
1259 if (l_Tokens.size() != 2)
1263 std::string l_Auto(l_Tokens[0].begin, l_Tokens[0].end);
1266 else if (l_Auto ==
"OFF")
1267 rRange.
Auto =
false;
1272 std::string l_Range(l_Tokens[1].begin, l_Tokens[1].end - 2);
1273 rRange.
Range = std::stof(l_Range);
1284template <
class InstrType,
class RsrcMgrType>
1292 if (!
WriteAndRead(
":SENS:AUTO?;:SENS?;:SENS? MIN;:SENS? MAX;:SENS? DEF", m_ReadBuffer))
1297 if (l_Tokens.size() != 5)
1301 std::string l_Auto(l_Tokens[0].begin, l_Tokens[0].end);
1304 else if (l_Auto ==
"OFF")
1305 rRange.
Auto =
false;
1310 std::string l_Val(l_Tokens[1].begin, l_Tokens[1].end - 2);
1311 rRange.
Range.Val = std::stof(l_Val);
1314 std::string l_Min(l_Tokens[2].begin, l_Tokens[2].end - 2);
1315 rRange.
Range.Min = std::stof(l_Min);
1318 std::string l_Max(l_Tokens[3].begin, l_Tokens[3].end - 2);
1319 rRange.
Range.Max = std::stof(l_Max);
1322 std::string l_Def(l_Tokens[4].begin, l_Tokens[4].end - 2);
1323 rRange.
Range.Def = std::stof(l_Def);
1337template <
class InstrType,
class RsrcMgrType>
1344 m_ErrorList.clear();
1358 std::vector<char>::const_iterator l_tokenbeg, l_tokenend;
1361 if (!l_BP.
GetNext(l_tokenbeg, l_tokenend,
','))
1363 rUsedBytes =
static_cast<U32>(std::stoul(std::string(l_tokenbeg, l_tokenend)));
1366 if (!l_BP.
GetNext(l_tokenbeg, l_tokenend,
','))
1368 rAvailableBytes =
static_cast<U32>(std::stoul(std::string(l_tokenbeg, l_tokenend)));
1371 while (l_BP.
GetNext(l_tokenbeg, l_tokenend,
','))
1375 l_File.
Path = std::string(l_tokenbeg, l_tokenend);
1377 if (!l_BP.
GetNext(l_tokenbeg, l_tokenend,
','))
1379 l_File.
Size = std::stoul(std::string(l_tokenbeg, l_tokenend));
1381 if (!l_BP.
GetNext(l_tokenbeg, l_tokenend,
','))
1383 l_File.
Type = std::string(l_tokenbeg, l_tokenend);
1385 rFileList.push_back(l_File);
1389 if (!InstrType::SetTimeout(m_Timeout))
1396 InstrType::SetTimeout(m_Timeout);
1402template <
class InstrType,
class RsrcMgrType>
1408 m_ErrorList.clear();
1412 std::string l_Command;
1413 l_Command =
":MMEM:DATA? " "\"" + Path +
"\"";
1424 size_t l_off, l_len;
1425 if (!
IsArbitraryBlock(m_ReadBuffer.begin(), m_ReadBuffer.end(), l_off, l_len))
1427 rContent = std::string(m_ReadBuffer.begin() + l_off, m_ReadBuffer.begin() + l_off + l_len);
1430 if (!InstrType::SetTimeout(m_Timeout))
1437 InstrType::SetTimeout(m_Timeout);
1446template <
class InstrType,
class RsrcMgrType>
1453 m_AveragingParmsAtInit = m_AveragingParms;
1454 m_TriggerParmsAtInit = m_TriggerParms;
1455 m_TriggerTimes.clear();
1458 std::string l_Command = Continuous ?
":INIT:CONT 1;:INIT" :
":INIT:CONT 0;:INIT";
1462template <
class InstrType,
class RsrcMgrType>
1471template <
class InstrType,
class RsrcMgrType>
1477 m_ErrorList.clear();
1480 std::chrono::high_resolution_clock::time_point l_T = std::chrono::high_resolution_clock::now();
1481 m_TriggerTimes.push_back(l_T);
1484 return InstrType::AssertTrigger();
1490template <
class InstrType,
class RsrcMgrType>
1500 l_ArbSelect.
Bx =
true;
1501 l_ArbSelect.
By =
true;
1502 l_ArbSelect.
Bz =
true;
1507 return MeasurementsGet(l_ArbSelect, rBx, rBy, rBz, rUnits, rTemp, rTimestampList, pMeasurementConditions);
1510template <
class InstrType,
class RsrcMgrType>
1522 std::string l_Command =
":UNIT?;:SENS?";
1523 if (ArbSelect.
Bx) l_Command +=
";:FETC:ARR:X? " + std::to_string(ArbSelect.
NoMeasurements);
1524 if (ArbSelect.
By) l_Command +=
";:FETC:ARR:Y? " + std::to_string(ArbSelect.
NoMeasurements);
1525 if (ArbSelect.
Bz) l_Command +=
";:FETC:ARR:Z? " + std::to_string(ArbSelect.
NoMeasurements);
1526 if (ArbSelect.
Temperature) l_Command +=
";:FETC:TEMP?";
1527 if (ArbSelect.
Timestamp) l_Command +=
";:FETC:TIM?";
1528 if (m_Sleep) l_Command +=
";:SYST:SLEE";
1534 auto l_pError = m_ErrorList.begin();
1535 for (; l_pError < m_ErrorList.end(); l_pError++)
1537 if (l_pError < m_ErrorList.end())
1543 std::vector<char>::const_iterator l_tokenbeg, l_tokenend;
1544 if (!l_BP.
GetNext(l_tokenbeg, l_tokenend,
';'))
1546 if (!
StringToUnits(std::string(l_tokenbeg, l_tokenend), rUnits))
1550 if (!l_BP.
GetNext(l_tokenbeg, l_tokenend,
';'))
1552 std::string l_RangeString(l_tokenbeg, l_tokenend);
1553 tFlux l_Range = stof(l_RangeString);
1559 if (!ParseMeasurements(l_BP, rUnits, rBx, ArbSelect.
NoMeasurements))
1567 if (!ParseMeasurements(l_BP, rUnits, rBy, ArbSelect.
NoMeasurements))
1575 if (!ParseMeasurements(l_BP, rUnits, rBz, ArbSelect.
NoMeasurements))
1580 if (!ApplyRotationMatrix(rBx, rBy, rBz))
1583 m_ErrorList.push_back(l_Error);
1590 if (!l_BP.
GetNext(l_tokenbeg, l_tokenend,
';'))
1592 std::string l_TemperatureString(l_tokenbeg, l_tokenend);
1593 rTemp =
static_cast<U16>(stoul(l_TemperatureString));
1597 rTimestampList.clear();
1601 if (!l_BP.
GetNext(l_tokenbeg, l_tokenend,
';'))
1603 std::string l_TimestampString(l_tokenbeg, l_tokenend);
1604 U64 l_LastTimestamp = std::stoull(l_TimestampString,
nullptr, 0);
1608 switch (m_TriggerParmsAtInit.Source)
1617 U64 l_TimeOffset =
static_cast<U64> (i * l_Period * 1E9 + 0.5);
1618 rTimestampList.push_back(l_LastTimestamp - l_TimeOffset);
1626 U64 l_TimeOffset =
static_cast<U64> (i * m_TriggerParmsAtInit.Period_s * 1E9 + 0.5);
1627 rTimestampList.push_back(l_LastTimestamp - l_TimeOffset);
1634 auto l_LastTriggerTime = m_TriggerTimes.back();
1635 for (
auto l_pTime = m_TriggerTimes.begin(); l_pTime < m_TriggerTimes.begin() + ArbSelect.
NoMeasurements; l_pTime++)
1637 std::chrono::nanoseconds l_TimeOffset = l_LastTriggerTime - *l_pTime;
1638 rTimestampList.push_back(l_LastTimestamp - l_TimeOffset.count());
1646 if (pMeasurementConditions)
1649 switch (m_TriggerParmsAtInit.Source)
1658 m_TriggerParmsAtInit.Period_s *= 1E-9;
1663 pMeasurementConditions->
TriggerParms = m_TriggerParmsAtInit;
1666 pMeasurementConditions->
Range = l_Range;
1679template <
class InstrType,
class RsrcMgrType>
1685 std::string l_Command;
1690 l_Command +=
":FORM ASC";
1693 l_Command +=
":FORM INT";
1696 l_Command +=
":FORM PACK,2";
1699 l_Command +=
":FORM PACK,1";
1711 m_ErrorList = l_ErrorList;
1716template <
class InstrType,
class RsrcMgrType>
1725 std::string l_Command =
":FORM?";
1730 std::string l_Format = std::string(m_ReadBuffer.begin(), m_ReadBuffer.end());
1731 if (std::string(
"ASCII") == l_Format)
1733 else if (std::string(
"INTEGER") == l_Format)
1735 else if (std::string(
"PACKED,2") == l_Format)
1737 else if (std::string(
"PACKED,1") == l_Format)
1753template <
class InstrType,
class RsrcMgrType>
1755 bool DefaultParms,
eUnits Units,
tFlux ExpectedField,
unsigned int NoDigits)
1757 MTL_INSTRUMENT_THM1176_DEBUG_COUT(MTL__FUNCTION_NAME__ <<
" default=" << DefaultParms <<
" units=" << Units <<
" expect=" << ExpectedField <<
" ndigits=" << NoDigits << std::endl);
1764 l_Command += DefaultParms ?
";:MEAS:X?" :
";:READ:X?";
1765 if (ExpectedField > 0.f || NoDigits != 0) l_Command +=
" ";
1766 if (ExpectedField > 0.f) l_Command +=
l_ToString(ExpectedField);
1767 if (NoDigits != 0) l_Command +=
"," + std::to_string(NoDigits);
1768 l_Command +=
";:FETC:Y?";
1769 if (NoDigits != 0) l_Command +=
" " + std::to_string(NoDigits);
1771 if (NoDigits != 0) l_Command +=
" " + std::to_string(NoDigits);
1772 if (m_Sleep) l_Command +=
";:SYST:SLEE";
1781 if (!ParseMeasurements(l_BP, Units, l_Meas, 1))
1786 if (!ParseMeasurements(l_BP, Units, l_Meas, 1))
1791 if (!ParseMeasurements(l_BP, Units, l_Meas, 1))
1796 if (!ApplyRotationMatrix(rBx, rBy, rBz))
1799 m_ErrorList.push_back(l_Error);
1811template <
class InstrType,
class RsrcMgrType>
1813 bool DefaultParms,
eUnits Units,
tFlux ExpectedField,
unsigned int NoDigits)
1815 MTL_INSTRUMENT_THM1176_DEBUG_COUT(MTL__FUNCTION_NAME__ <<
" nmeas=" << NoMeasurements <<
" default=" << DefaultParms <<
" units=" << Units <<
" expect=" << ExpectedField <<
" ndigits=" << NoDigits << std::endl);
1822 l_Command += (DefaultParms ?
";:MEAS:ARR:X? " :
";:READ:ARR:X? ") +
1823 std::to_string(NoMeasurements);
1824 if (ExpectedField > 0.f || NoDigits != 0) l_Command +=
",";
1825 if (ExpectedField > 0.f) l_Command +=
l_ToString(ExpectedField);
1826 if (NoDigits != 0) l_Command +=
"," + std::to_string(NoDigits);
1827 l_Command +=
";:FETC:ARR:Y? " + std::to_string(NoMeasurements);
1828 if (NoDigits != 0) l_Command +=
"," + std::to_string(NoDigits);
1829 l_Command +=
";Z? " + std::to_string(NoMeasurements);
1830 if (NoDigits != 0) l_Command +=
"," + std::to_string(NoDigits);
1831 if (m_Sleep) l_Command +=
";:SYST:SLEE";
1840 if (!ParseMeasurements(l_BP, Units, rBx, NoMeasurements))
1844 if (!ParseMeasurements(l_BP, Units, rBy, NoMeasurements))
1848 if (!ParseMeasurements(l_BP, Units, rBz, NoMeasurements))
1852 if (!ApplyRotationMatrix(rBx, rBy, rBz))
1855 m_ErrorList.push_back(l_Error);
1870template <
class InstrType,
class RsrcMgrType>
1879template <
class InstrType,
class RsrcMgrType>
1885 m_ErrorList.clear();
1889 if (0 == l_Command.size())
1892 if (!InstrType::Write(l_Command) ||
1893 !InstrType::Read(m_ReadBuffer) ||
1894 !GetErrorList(m_ErrorList, l_Command))
1897 rStatus =
static_cast<U16>(std::stoi(std::string(m_ReadBuffer.begin(), m_ReadBuffer.end())));
1909template <
class InstrType,
class RsrcMgrType>
1915 m_ErrorList.clear();
1918 std::string l_CompleteCommand;
1919 for (
auto l_Reg : Regs)
1922 if (0 == l_Command.size())
1924 if (l_CompleteCommand.size() > 0) l_CompleteCommand +=
";";
1925 l_CompleteCommand += l_Command;
1928 if (!InstrType::Write(l_CompleteCommand) ||
1929 !InstrType::Read(m_ReadBuffer) ||
1930 !GetErrorList(m_ErrorList, l_CompleteCommand))
1936 std::vector<char>::const_iterator l_tokenbeg, l_tokenend;
1938 for (
size_t i = Regs.size(); i > 0; i--)
1940 if (!l_BP.
GetNext(l_tokenbeg, l_tokenend,
';'))
1942 rStatus.push_back(
static_cast<U16>(std::stoi(std::string(l_tokenbeg, l_tokenend))));
1954template <
class InstrType,
class RsrcMgrType>
1967 U16 l_StatusEnab =
static_cast<U16>(std::stoi(std::string(m_ReadBuffer.begin(), m_ReadBuffer.end())));
1970 l_StatusEnab &= ~DisableMask;
1971 l_StatusEnab |= EnableMask;
1990template <
class InstrType,
class RsrcMgrType>
1996 rIdentification = m_Identification;
2000template <
class InstrType,
class RsrcMgrType>
2006 rIdentification = m_IdentificationStruct;
2010template <
class InstrType,
class RsrcMgrType>
2017 for (
auto l_Range : m_Ranges)
2018 rRanges.push_back(l_Range);
2022template <
class InstrType,
class RsrcMgrType>
2029 for (
auto l_Unit : m_Units)
2030 rUnits.push_back(l_Unit.first);
2034template <
class InstrType,
class RsrcMgrType>
2042 rDivisor = m_Units.at(Units);
2044 catch (
const std::out_of_range& oor)
2054template <
class InstrType,
class RsrcMgrType>
2057 Matrix = m_RotationMatrix;
2061template <
class InstrType,
class RsrcMgrType>
2087template <
class InstrType,
class RsrcMgrType>
2094 if (!ForceCalibration &&
2098 m_ErrorList.clear();
2122 if (!InstrType::SetTimeout(m_Timeout))
2139 m_ErrorList = l_ErrorList;
2141 InstrType::SetTimeout(m_Timeout);
2147template <
class InstrType,
class RsrcMgrType>
2153 m_ErrorList.clear();
2165 if (!InstrType::SetTimeout(m_Timeout))
2172 InstrType::SetTimeout(m_Timeout);
2178template <
class InstrType,
class RsrcMgrType>
2185 m_TriggerTimes.clear();
2186 m_ErrorList.clear();
2188 m_UseCalibration =
true;
2189 m_AbortRead =
false;
2194 if (!InstrType::Write(
"*RST;*CLS"))
2198 if (!ReadUseCalibration(m_UseCalibration))
2218 ReadUseCalibration(m_UseCalibration);
2224 m_ErrorList = l_ErrorList;
2231template <
class InstrType,
class RsrcMgrType>
2237 m_ErrorList.clear();
2238 return InstrType::Write(
":DIAG:UPGR");
2241template <
class InstrType,
class RsrcMgrType>
2250 rSManufacturingDate = m_ManufacturingDate;
2253 std::match_results<std::string::const_iterator> l_Mm;
2254 if (!std::regex_match(rSManufacturingDate, l_Mm, std::regex(
"^([0-9]{4})-([0-9]{2})-([0-9]{2})")))
2256 struct std::tm l_ManDateStruct = { };
2257 l_ManDateStruct.tm_year = std::stoi(l_Mm[1]) - 1900;
2258 l_ManDateStruct.tm_mon = std::stoi(l_Mm[2]) - 1;
2259 l_ManDateStruct.tm_mday = std::stoi(l_Mm[3]);
2260 if ((rManufacturingDate = mktime(&l_ManDateStruct)) < 0)
2264 rSCalibrationDate = m_CalibrationDate;
2267 std::match_results<std::string::const_iterator> l_Cm;
2268 if (!std::regex_match(rSCalibrationDate, l_Cm, std::regex(
"^([0-9]{4})-([0-9]{2})-([0-9]{2})")))
2270 struct tm l_CalDateStruct = { };
2271 l_CalDateStruct.tm_year = std::stoi(l_Cm[1]) - 1900;
2272 l_CalDateStruct.tm_mon = std::stoi(l_Cm[2]) - 1;
2273 l_CalDateStruct.tm_mday = std::stoi(l_Cm[3]);
2274 if ((rCalibrationDate = mktime(&l_CalDateStruct)) < 0)
2281 rSManufacturingDate.clear();
2282 rManufacturingDate = -1;
2283 rSCalibrationDate.clear();
2284 rCalibrationDate = -1;
2287 catch (std::regex_error& rE)
2296template <
class InstrType,
class RsrcMgrType>
2310 U32 l_CurrentTimeout = InstrType::GetTimeout();
2311 std::this_thread::sleep_for(std::chrono::milliseconds(2 * l_CurrentTimeout));
2321 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 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.