THM1176InstrumentManager 1.1
Qt Object abstraction for Metrolab THM1176
Loading...
Searching...
No Matches
CTHM1176InstrumentManager.cpp
Go to the documentation of this file.
1// Copyright (c) 2025 Metrolab Technology S.A., Geneva, Switzerland (www.metrolab.com)
2// See the included file LICENSE.txt for the licensing conditions.
3
7
9#include "OSDefines.h"
10#include "Helpers.h"
11#include "Exception.h"
12
13using namespace MTL;
14using namespace MTL::Instrument;
15using namespace MTL::Instrument::THM1176Types;
16
17
18
20//----------------------------------------------------------------------//
21// THM1176 Instrument Scanner //
22//----------------------------------------------------------------------//
23void CTHM1176InstrumentScanner::HandleError (QString Description,
24 QString Context)
25{
26 // Create the error structure.
27 sError l_Error;
29 l_Error.Description = Description.toStdString();
30 l_Error.Context = Context.toStdString();
31
32 // Emit the update.
33 CErrorList l_ErrorList;
34 l_ErrorList.push_back(l_Error);
35 emit UpdateErrorList(l_ErrorList);
36
37} // CTHM1176InstrumentScanner::HandleError
38
39void CTHM1176InstrumentScanner::Start (THM1176_RSRC_MGR_CLS * pResourceManager)
40{
41 m_pResourceManager = pResourceManager;
42 m_TimerID = startTimer(THM1176_SCAN_INTERVAL);
43
44} // CTHM1176InstrumentScanner::Start
45
47{
48 killTimer(m_TimerID);
49 m_pResourceManager = nullptr;
50
51 // Quit the event loop.
52 QThread::currentThread()->quit();
53
54} // CTHM1176InstrumentScanner::Stop
55
56void CTHM1176InstrumentScanner::timerEvent (QTimerEvent * Event)
57{
58 MTL_Unused(Event)
59
60 // Get the current list, and if it has changed, emit the signal.
61 if (nullptr != m_pResourceManager)
62 {
63 CResourceList l_InstrumentList;
64 m_pResourceManager->FindResources(l_InstrumentList, THM1176_RSRC_FILTER);
65
66 if (m_InstrumentList != l_InstrumentList)
67 {
68 m_InstrumentList = l_InstrumentList;
69 emit UpdateInstrumentList(m_InstrumentList);
70 }
71 }
72
73 // Gripe if the Resource Manager is not up.
74 else
75 HandleError("Resource Manager not running", __func__);
76
77} // CTHM1176InstrumentScanner::timerEvent
78
79
80
82//----------------------------------------------------------------------//
83// THM1176 Instrument Controller: Error reporting //
84//----------------------------------------------------------------------//
85void CTHM1176InstrumentController::HandleError (QString Description,
86 QString Context)
87{
88 // Get the THM1176 error list, if the THM1176 is connected.
89 CErrorList l_ErrorList;
90 if (nullptr != m_pTHM1176)
91 {
92 l_ErrorList = m_pTHM1176->CurrentErrorList();
93 m_pTHM1176->ClearErrorList();
94 }
95
96 // Create the error structure for the header message.
97 sError l_Error;
99 l_Error.Description = Description.toStdString();
100 l_Error.Context = Context.toStdString();
101
102 // Insert the header message at the front of the list.
103 l_ErrorList.insert(l_ErrorList.begin(), l_Error);
104
105 // Emit the error list update.
106 emit UpdateErrorList(l_ErrorList);
107
108} // CTHM1176InstrumentController::HandleError
109
110//----------------------------------------------------------------------//
111// THM1176 Instrument Controller: Initialize / Shutdown //
112//----------------------------------------------------------------------//
113void CTHM1176InstrumentController::Start (THM1176_RSRC_MGR_CLS * pResourceManager)
114{
115 m_pResourceManager = pResourceManager;
116
117} // CTHM1176InstrumentController::Start
118
120{
121 // Disconnect the THM1176 and deallocate the object, if it exists.
122 if (nullptr != m_pTHM1176)
123 {
124 m_pTHM1176->Disconnect();
125 delete m_pTHM1176;
126 }
127
128 // Reset the object pointers to NULL, just to be sure.
129 m_pResourceManager = nullptr;
130 m_pTHM1176 = nullptr;
131
132 // Quit the event loop.
133 QThread::currentThread()->quit();
134
135} // CTHM1176InstrumentController::Stop
136
137//----------------------------------------------------------------------//
138// THM1176 Instrument Controller slots: Connection //
139//----------------------------------------------------------------------//
140void CTHM1176InstrumentController::ClearInstrumentInfo (void)
141{
142 m_CurrentInstrument.clear();
143
144 m_Identification.clear();
145 m_RangeList.clear();
146 m_UnitsList.clear();
147 m_DivisorList.clear();
148 m_AveragingParmBounds.clear();
149 m_TriggerParmBounds.clear();
150 m_RangeParmBounds.clear();
151
152 m_AveragingParms.clear();
153 m_TriggerParms.clear();
154 m_OutputSelect.clear();
155 m_SleepParm = false;
156 m_Units = kT;
157 m_RangeParms.clear();
158 m_CommFormat = kComFormatAscii;
159
160} // CTHM1176InstrumentController::ClearInstrumentInfo
161
162void CTHM1176InstrumentController::GetInstrumentInfo (std::string Context)
163{
164 // Get the parsed identification string.
165 if (!m_pTHM1176->GetIdentification(m_Identification))
166 throw CException<CTHM1176InstrumentManager>("Cannot get identification string", Context);
167
168 // Get the range list.
169 if (!m_pTHM1176->GetAllRanges(m_RangeList))
170 throw CException<CTHM1176InstrumentManager>("Cannot get range list", Context);
171
172 // Get the list of units supported by this instrument, and associated divisors.
173 MakeUnitsList(Context);
174
175 // Get the Averaging parameter bounds.
176 if (!m_pTHM1176->ParmAveragingGet(m_AveragingParmBounds))
177 throw CException<CTHM1176InstrumentManager>("Cannot get Averaging parameter bounds", Context);
178
179 // Get the Trigger parameter bounds.
180 if (!m_pTHM1176->ParmTriggerInputGet(m_TriggerParmBounds))
181 throw CException<CTHM1176InstrumentManager>("Cannot get Trigger parameter bounds", Context);
182
183 // Get the Range parameter bounds.
184 if (!m_pTHM1176->ParmRangeGet(m_RangeParmBounds))
185 throw CException<CTHM1176InstrumentManager>("Cannot get Range parameter bounds", Context);
186
187 // Get the Averaging parameters.
188 m_AveragingParms.NoPoints = m_AveragingParmBounds.NoPoints.Val;
189
190 // Get the Trigger parameters.
191 m_TriggerParms.Source = m_TriggerParmBounds.Source;
192 m_TriggerParms.Period_s = m_TriggerParmBounds.Period_s.Val;
193 m_TriggerParms.Count = m_TriggerParmBounds.Count.Val;
194
195 // Reset the output selection.
196 m_OutputSelect.clear();
197 m_OutputSelect.NoMeasurements = m_TriggerParmBounds.Count.Val;
198
199 // Get the sleep parameter.
200 if (!m_pTHM1176->ParmSleepGet(m_SleepParm))
201 throw CException<CTHM1176InstrumentManager>("Cannot get Sleep parameter", Context);
202
203 // Get the units.
204 GetCurrentUnits(Context);
205
206 // Get the Range parameters.
207 m_RangeParms.Auto = m_RangeParmBounds.Auto;
208 m_RangeParms.Range = m_RangeParmBounds.Range.Val;
209
210 // Get the Communication Format.
211 if (!m_pTHM1176->GetFormat(m_CommFormat))
212 throw CException<CTHM1176InstrumentManager>("Cannot get Communication Format", Context);
213
214} // CTHM1176InstrumentController::GetInstrumentInfo
215
216void CTHM1176InstrumentController::GetInstrumentParameters (std::string Context)
217{
218 // Get the Averaging parameters.
219 if (!m_pTHM1176->ParmAveragingGet(m_AveragingParms))
220 throw CException<CTHM1176InstrumentManager>("Cannot get Averaging parameters", Context);
221
222 // Get the Trigger parameters.
223 if (!m_pTHM1176->ParmTriggerInputGet(m_TriggerParms))
224 throw CException<CTHM1176InstrumentManager>("Cannot get Trigger parameters", Context);
225
226 // Reset the output selection.
227 m_OutputSelect.clear();
228 m_OutputSelect.NoMeasurements = m_TriggerParmBounds.Count.Val;
229
230 // Get the sleep parameter.
231 if (!m_pTHM1176->ParmSleepGet(m_SleepParm))
232 throw CException<CTHM1176InstrumentManager>("Cannot get Sleep parameter", Context);
233
234 // Get the units.
235 GetCurrentUnits(Context);
236
237 // Get the Range parameters.
238 if (!m_pTHM1176->ParmRangeGet(m_RangeParms))
239 throw CException<CTHM1176InstrumentManager>("Cannot get Range parameters", Context);
240
241 // Get the Communication Format.
242 if (!m_pTHM1176->GetFormat(m_CommFormat))
243 throw CException<CTHM1176InstrumentManager>("Cannot get Communication Format", Context);
244
245} // CTHM1176InstrumentController::GetInstrumentParameters
246
247void CTHM1176InstrumentController::PublishInstrumentInfo (void)
248{
249 emit UpdateCurrentInstrument(m_CurrentInstrument);
250
251 emit UpdateIdentification(m_Identification);
252 emit UpdateRangeList(m_RangeList);
253 emit UpdateUnitsList(m_UnitsList);
254 emit UpdateDivisorList(m_DivisorList);
255 emit UpdateAveragingParmBounds(m_AveragingParmBounds);
256 emit UpdateTriggerParmBounds(m_TriggerParmBounds);
257 emit UpdateRangeParmBounds(m_RangeParmBounds);
258
259 emit UpdateOutputSelect(m_OutputSelect);
260 emit UpdateSleepParm(m_SleepParm);
261 emit UpdateUnits(m_Units);
262 emit UpdateCommFormat(m_CommFormat);
263
264} // CTHM1176InstrumentController::PublishInstrumentInfo
265
266void CTHM1176InstrumentController::PublishInstrumentParameters (void)
267{
268 emit UpdateAveragingParms(m_AveragingParms);
269 emit UpdateTriggerParms(m_TriggerParms);
270 emit UpdateOutputSelect(m_OutputSelect);
271 emit UpdateSleepParm(m_SleepParm);
272 emit UpdateUnits(m_Units);
273 emit UpdateRangeParms(m_RangeParms);
274 emit UpdateCommFormat(m_CommFormat);
275
276} // CTHM1176InstrumentController::PublishInstrumentParameters
277
279{
280 // Save the instrument list.
281 m_InstrumentList = InstrumentList;
282
283 // All is well if we have no active instrument, or if the active instrument is still in the list.
284 if (m_CurrentInstrument.empty() && m_pTHM1176 == nullptr) return;
285
286 for (auto l_pTHM1176ResourceID = InstrumentList.begin(); l_pTHM1176ResourceID < InstrumentList.end(); l_pTHM1176ResourceID++)
287 if (m_CurrentInstrument == *l_pTHM1176ResourceID) return;
288
289 // If the active instrument is no longer in the list, stop the continuous-measurement timer.
290 if (m_TimerID)
291 killTimer(m_TimerID);
292 m_TimerID = 0;
293
294 // Disconnect the instrument.
295 if (m_pTHM1176 != nullptr)
296 m_pTHM1176->Disconnect();
297 m_pTHM1176 = nullptr;
298 emit UpdateInstrumentPointer(m_pTHM1176);
299
300 // Flag that we are not connected.
301 m_OperatingMode = kTHM1176NotConnected;
302 emit UpdateOperatingMode(m_OperatingMode);
303
304 // Clear the information on the current instrument.
305 // Note: instrument in Reset mode forces Instrument Manager to emit all parameter-value notifications.
306 ClearInstrumentInfo();
307 PublishInstrumentInfo();
308
309} // CTHM1176InstrumentController::UpdateInstrumentList
310
312{
313 // Prepare to catch general administrative inconsistencies.
314 try
315 {
316 // Make sure the resource name is in the current resource list.
317 auto l_pResource = m_InstrumentList.begin();
318 for (; l_pResource < m_InstrumentList.end(); l_pResource++)
319 if (*l_pResource == CurrentInstrument) break;
320 if (l_pResource >= m_InstrumentList.end())
321 throw CException<CTHM1176InstrumentManager>("Resource name not in resource list", __func__);
322
323 // If the resource name is the currently selected one, there is nothing to do.
324 if (CurrentInstrument == m_CurrentInstrument)
325 return;
326
327 // Disconnect the current instrument, if it exists.
328 if (nullptr != m_pTHM1176)
329 {
330 m_pTHM1176->Disconnect();
331 delete m_pTHM1176;
332 m_pTHM1176 = nullptr;
333 emit UpdateInstrumentPointer(m_pTHM1176);
334
335 // Flag that we are not connected.
336 m_OperatingMode = kTHM1176NotConnected;
337 emit UpdateOperatingMode(m_OperatingMode);
338
339 // Clear the information on the current instrument.
340 // Note: instrument in Reset mode forces Instrument Manager to emit all parameter-value notifications.
341 ClearInstrumentInfo();
342 PublishInstrumentInfo();
343 }
344
345 // Make sure we have the pointer to the Resource Manager.
346 if (nullptr == m_pResourceManager)
347 throw CException<CTHM1176InstrumentManager>("Resource Manager not running", __func__);
348
349 // Create the new THM1176 object.
350 m_pTHM1176 = new CTHM1176Instrument<THM1176_INSTR_CLS, THM1176_RSRC_MGR_CLS>(*m_pResourceManager, CurrentInstrument);
351 if (nullptr == m_pTHM1176)
352 throw CException<CTHM1176InstrumentManager>("Cannot create THM1176 object", __func__);
353 emit UpdateInstrumentPointer(m_pTHM1176);
354 }
356 {
357 // Notify Instrument Manager that SetCurrentInstrument failed.
358 emit UpdateCurrentInstrument(m_CurrentInstrument);
359
360 // Emit the error message(s).
361 HandleError(rE.message(), rE.context());
362 return;
363 }
364
365 // Prepare to catch errors that involve actual instrument I/O.
366 try
367 {
368 // Connect to the THM1176.
369 std::string ErrorMessage;
370 if (!m_pTHM1176->Connect(THM1176_CONNECT_TIMEOUT, true, &ErrorMessage))
371 throw CException<CTHM1176InstrumentManager>("Cannot connect to THM1176: " + ErrorMessage, __func__);
372
373 // Retrieve the instrument information from the instrument.
374 GetInstrumentInfo(__func__);
375 m_CurrentInstrument = CurrentInstrument;
376
377 // Now we have all the information, we can publish it.
378 // Note: instrument in Reset mode forces Instrument Manager to emit all parameter-value notifications.
379 PublishInstrumentInfo();
380
381 // Set the operating mode to Idle.
382 m_OperatingMode = kTHM1176Idle;
383 emit UpdateOperatingMode(m_OperatingMode);
384 }
386 {
387 delete m_pTHM1176;
388 m_pTHM1176 = nullptr;
389
390 // Notify Instrument Manager that SetCurrentInstrument failed.
391 ClearInstrumentInfo();
392 emit UpdateCurrentInstrument(m_CurrentInstrument);
393
394 // Emit the error message(s).
395 HandleError(rE.message(), rE.context());
396 return;
397 } catch (const std::exception& ex) {
398 // Handle standard exceptions.
399 HandleError(ex.what(), __func__);
400 } catch (...) {
401 // Handle unknown exceptions.
402 HandleError("Unknown error occurred during THM1176 connection", __func__);
403 }
404
405} // CTHM1176InstrumentController::SetCurrentInstrument
406
407//----------------------------------------------------------------------//
408// THM1176 Instrument Controller slots: Instrument control //
409//----------------------------------------------------------------------//
411{
412 try
413 {
414 // Make sure we're connected, and not in the requested operating mode already.
415 if (m_pTHM1176 == nullptr)
416 throw CException<CTHM1176InstrumentManager>("Cannot change operating mode", __func__);
417 else if (m_OperatingMode == OperatingMode)
418 return;
419
420 // If we were in continuous measurement mode, stop the timer and abort the measurements.
421 if (kTHM1176MeasureContinuously == m_OperatingMode)
422 {
423 if (0 != m_TimerID)
424 {
425 killTimer(m_TimerID);
426 m_TimerID = 0;
427 }
428
429 if (!m_pTHM1176->Abort())
430 throw CException<CTHM1176InstrumentManager>("Cannot abort ", __func__);
431 }
432
433 // Handle the different cases.
434 m_OperatingMode = OperatingMode;
435 switch (m_OperatingMode)
436 {
438 if (nullptr != m_pTHM1176)
439 {
440 // Abort any ongoing measurements.
441 if (!m_pTHM1176->Abort())
442 throw CException<CTHM1176InstrumentManager>("Cannot abort measurement", __func__);
443
444 // Disconnect the instrument.
445 m_pTHM1176->Disconnect();
446 delete m_pTHM1176;
447 m_pTHM1176 = nullptr;
448 emit UpdateInstrumentPointer(m_pTHM1176);
449
450 // Flag that we are not connected.
451 m_OperatingMode = kTHM1176NotConnected;
452 emit UpdateOperatingMode(m_OperatingMode);
453
454 // Clear the information on the current instrument.
455 // Note: instrument in Reset mode forces Instrument Manager to emit all parameter-value notifications.
456 ClearInstrumentInfo();
457 PublishInstrumentInfo();
458 }
459 break;
460
461 case kTHM1176Reset:
462 // Abort any ongoing measurements.
463 if (!m_pTHM1176->Abort())
464 throw CException<CTHM1176InstrumentManager>("Cannot abort measurement", __func__);
465
466 // Set the operating mode to Reset.
467 m_OperatingMode = kTHM1176Reset;
468 emit UpdateOperatingMode(m_OperatingMode);
469
470 // Reset the instrument.
471 if (!m_pTHM1176->Reset())
472 throw CException<CTHM1176InstrumentManager>("Cannot reset", __func__);
473
474 // Retrieve and publish the instrument parameters.
475 GetInstrumentParameters(__func__);
476 PublishInstrumentParameters();
477
478 // Set the operating mode back to Idle.
479 m_OperatingMode = kTHM1176Idle;
480 emit UpdateOperatingMode(m_OperatingMode);
481 break;
482
483 case kTHM1176Idle:
484 // Abort any ongoing measurements.
485 if (!m_pTHM1176->Abort())
486 throw CException<CTHM1176InstrumentManager>("Cannot abort measurement", __func__);
487
488 // Flag that we're idle.
489 m_OperatingMode = kTHM1176Idle;
490 emit UpdateOperatingMode(m_OperatingMode);
491 break;
492
493 case kTHM1176Measure:
494 // Abort any ongoing measurements.
495 if (!m_pTHM1176->Abort())
496 throw CException<CTHM1176InstrumentManager>("Cannot abort measurement", __func__);
497
498 // Flag that we're Measuring.
499 m_OperatingMode = kTHM1176Measure;
500 emit UpdateOperatingMode(m_OperatingMode);
501
502 // Initiate the measurement.
503 if (!m_pTHM1176->Initiate(false))
504 throw CException<CTHM1176InstrumentManager>("Cannot initiate measurement", __func__);
505
506 // What we do next depends on the trigger mode.
507 switch (m_TriggerParms.Source)
508 {
509 case kInputTrigSrcBus:
510 // We will fetch the measurements after the appropriate number of triggers.
511 m_TriggerCount = 0;
512 break;
513
514 default:
515 {
516 // Transmit the measurements.
517 CMeasurement l_Measurement;
518 eUnits l_Units;
519 sMeasurementConditions l_MeasurementConditions;
520 if (!m_pTHM1176->MeasurementsGet(m_OutputSelect,
521 l_Measurement.Bx, l_Measurement.By, l_Measurement.Bz,
522 l_Units, l_Measurement.Temp, l_Measurement.TimestampList,
523 &l_MeasurementConditions))
524 throw CException<CTHM1176InstrumentManager>("Cannot fetch measurement", __func__);
525
526 TranslateUnits(l_Measurement, l_Units);
527
528 l_Measurement.AveragingParms = l_MeasurementConditions.AveragingParms;
529 l_Measurement.TriggerParms = l_MeasurementConditions.TriggerParms;
530 l_Measurement.OutputSelect = m_OutputSelect;
531 l_Measurement.SleepParm = m_SleepParm;
532 l_Measurement.RangeParms = m_RangeParms;
533 l_Measurement.RangeParms.Range = l_MeasurementConditions.Range;
534 l_Measurement.CommFormat = m_CommFormat;
535
536 l_Measurement.Warnings = m_pTHM1176->CurrentErrorList();
537
538 emit UpdateMeasurement(l_Measurement);
539
540 // Flag that we're idle again.
541 m_OperatingMode = kTHM1176Idle;
542 emit UpdateOperatingMode(m_OperatingMode);
543 break;
544 }
545 }
546 break;
547
549 // Abort any ongoing measurements.
550 if (!m_pTHM1176->Abort())
551 throw CException<CTHM1176InstrumentManager>("Cannot abort measurement", __func__);
552
553 // Flag that we're Measuring Continuously.
554 m_OperatingMode = kTHM1176MeasureContinuously;
555 emit UpdateOperatingMode(m_OperatingMode);
556
557 // What we do next depends on the trigger mode.
558 switch (m_TriggerParms.Source)
559 {
560 // For Immediate trigger, start a timer to initiate and read the results.
562 m_TimerID = startTimer(0);
563 break;
564
565 // For Timed trigger, initiate the measurement continuously, and start
566 // a timer to read the results.
568 if (!m_pTHM1176->Initiate(true))
569 throw CException<CTHM1176InstrumentManager>("Cannot initiate measurement", __func__);
570 m_TimerID = startTimer(0);
571 break;
572
573 // For Bus triggered, initiate the first measurement.
574 case kInputTrigSrcBus:
575 m_TriggerCount = 0;
576 if (!m_pTHM1176->Initiate(false))
577 throw CException<CTHM1176InstrumentManager>("Cannot initiate measurement", __func__);
578 break;
579 }
580 break;
581
583 // Abort any ongoing measurements.
584 if (!m_pTHM1176->Abort())
585 throw CException<CTHM1176InstrumentManager>("Cannot abort measurement", __func__);
586
587 // Flag that we're calibrating the zero offset.
588 m_OperatingMode = kTHM1176CalibrateZeroOffset;
589 emit UpdateOperatingMode(m_OperatingMode);
590
591 // Perform the calibration.
592 if (!m_pTHM1176->CalibrateZeroOffset(m_CalibrationOverride))
593 throw CException<CTHM1176InstrumentManager>("Cannot calibrate zero offset", __func__);
594
595 // Flag that we're idle again.
596 m_OperatingMode = kTHM1176Idle;
597 emit UpdateOperatingMode(m_OperatingMode);
598 break;
599
601 // Abort any ongoing measurements.
602 if (!m_pTHM1176->Abort())
603 throw CException<CTHM1176InstrumentManager>("Cannot abort measurement", __func__);
604
605 // Flag that we're restoring the zero offset.
606 m_OperatingMode = kTHM1176RestoreZeroOffset;
607 emit UpdateOperatingMode(m_OperatingMode);
608
609 // Perform the restoration.
610 if (!m_pTHM1176->RestoreZeroOffset())
611 throw CException<CTHM1176InstrumentManager>("Cannot restore zero offset", __func__);
612
613 // Flag that we're idle again.
614 m_OperatingMode = kTHM1176Idle;
615 emit UpdateOperatingMode(m_OperatingMode);
616 break;
617 } // switch
618 } // try
619
620 // If anything goes wrong, we abort the measurement, emit an error and return to idle.
622 {
623 if (kTHM1176MeasureContinuously == m_OperatingMode && 0 != m_TimerID)
624 {
625 killTimer(m_TimerID);
626 m_TimerID = 0;
627 }
628 m_pTHM1176->Abort();
629 HandleError(rE.message(), rE.context());
630 m_OperatingMode = kTHM1176Idle;
631 emit UpdateOperatingMode(m_OperatingMode);
632 }
633
634} // CTHM1176InstrumentController::SetOperatingMode
635
637{
638 try
639 {
640 // Make sure we're good to go.
641 if (m_pTHM1176 == nullptr ||
642 (kTHM1176Measure != m_OperatingMode && kTHM1176MeasureContinuously != m_OperatingMode) ||
643 kInputTrigSrcBus != m_TriggerParms.Source ||
644 m_TriggerCount >= m_TriggerParms.Count)
645 throw CException<CTHM1176InstrumentManager>("Cannot send trigger in current mode", __func__);
646
647 // Send the trigger.
648 if (!m_pTHM1176->SendBusTrigger())
649 throw CException<CTHM1176InstrumentManager>("Cannot send trigger", __func__);
650
651 // If the trigger count has reached the limit, read the result.
652 if (++m_TriggerCount >= m_TriggerParms.Count)
653 {
654 // Transmit the measurements.
655 CMeasurement l_Measurement;
656 eUnits l_Units;
657 sMeasurementConditions l_MeasurementConditions;
658 if (!m_pTHM1176->MeasurementsGet(m_OutputSelect,
659 l_Measurement.Bx, l_Measurement.By, l_Measurement.Bz,
660 l_Units, l_Measurement.Temp, l_Measurement.TimestampList,
661 &l_MeasurementConditions))
662 throw CException<CTHM1176InstrumentManager>("Cannot fetch measurement", __func__);
663
664 TranslateUnits(l_Measurement, l_Units);
665
666 l_Measurement.AveragingParms = l_MeasurementConditions.AveragingParms;
667 l_Measurement.TriggerParms = l_MeasurementConditions.TriggerParms;
668 l_Measurement.OutputSelect = m_OutputSelect;
669 l_Measurement.SleepParm = m_SleepParm;
670 l_Measurement.RangeParms = m_RangeParms;
671 l_Measurement.RangeParms.Range = l_MeasurementConditions.Range;
672 l_Measurement.CommFormat = m_CommFormat;
673
674 l_Measurement.Warnings = m_pTHM1176->CurrentErrorList();
675
676 emit UpdateMeasurement(l_Measurement);
677
678 // For Continuous Measurement, initiate next measurement.
679 if (kTHM1176MeasureContinuously == m_OperatingMode)
680 {
681 m_TriggerCount = 0;
682 if (!m_pTHM1176->Initiate(false))
683 throw CException<CTHM1176InstrumentManager>("Cannot initiate measurement", __func__);
684 }
685 // Else go back to Idle.
686 else
687 {
688 m_OperatingMode = kTHM1176Idle;
689 emit UpdateOperatingMode(m_OperatingMode);
690 }
691 }
692 }
693
694 // If anything goes wrong, just flag the error.
696 {
697 HandleError(rE.message(), rE.context());
698 }
699
700} // CTHM1176InstrumentController::SendTrigger
701
702void CTHM1176InstrumentController::timerEvent (QTimerEvent * Event)
703{
704 MTL_Unused(Event)
705
706 // This timer handler is only used for continuous measurements.
707 try
708 {
709 // For immediate trigger, we have to initiate the measurement each time.
710 if (kInputTrigSrcImmediate == m_TriggerParms.Source &&
711 !m_pTHM1176->Initiate(false))
712 throw CException<CTHM1176InstrumentManager>("Cannot initiate measurement", __func__);
713
714 // Transmit the measurements.
715 CMeasurement l_Measurement;
716 eUnits l_Units;
717 sMeasurementConditions l_MeasurementConditions;
718 if (!m_pTHM1176->MeasurementsGet(m_OutputSelect,
719 l_Measurement.Bx, l_Measurement.By, l_Measurement.Bz,
720 l_Units, l_Measurement.Temp, l_Measurement.TimestampList,
721 &l_MeasurementConditions))
722 throw CException<CTHM1176InstrumentManager>("Cannot fetch measurement", __func__);
723
724 TranslateUnits(l_Measurement, l_Units);
725
726 l_Measurement.AveragingParms = l_MeasurementConditions.AveragingParms;
727 l_Measurement.TriggerParms = l_MeasurementConditions.TriggerParms;
728 l_Measurement.OutputSelect = m_OutputSelect;
729 l_Measurement.SleepParm = m_SleepParm;
730 l_Measurement.RangeParms = m_RangeParms;
731 l_Measurement.RangeParms.Range = l_MeasurementConditions.Range;
732 l_Measurement.CommFormat = m_CommFormat;
733
734 l_Measurement.Warnings = m_pTHM1176->CurrentErrorList();
735
736 emit UpdateMeasurement(l_Measurement);
737 }
738
739 // If anything goes wrong, just flag the error.
741 {
742 HandleError(rE.message(), rE.context());
743 }
744
745} // CTHM1176InstrumentController::timerEvent
746
747void CTHM1176InstrumentController::MakeUnitsList (std::string Context)
748{
749 m_UnitsList.clear();
750 CUnitsList l_UnitsList;
751 if (!m_pTHM1176->GetAllUnits(l_UnitsList))
752 throw CException<CTHM1176InstrumentManager>("Cannot get units list", Context);
753
754 // Add all units supported by the instrument. First unit is always T.
755 for (auto l_pUnits = l_UnitsList.begin(); l_pUnits < l_UnitsList.end(); l_pUnits++)
756 {
757 m_UnitsList.push_back(static_cast<eTHM1176Units>(*l_pUnits));
758
759 U32 l_Divisor;
760 if (!m_pTHM1176->GetDivisor(*l_pUnits, l_Divisor))
761 throw CException<CTHM1176InstrumentManager>("Cannot get units list", Context);
762 m_DivisorList.push_back(l_Divisor);
763 }
764
765 // Add the fake "A/m", "kA/m" and "mA/m" units if they fall in the instrument's range.
766 F32 l_FloatDivisor = m_DivisorList[0] * MU0;
767 if (l_FloatDivisor >= 1. && l_FloatDivisor <= 65535.)
768 {
769 m_UnitsList.push_back(kApm);
770 m_DivisorList.push_back(static_cast<U32>(l_FloatDivisor + 0.5));
771 }
772 l_FloatDivisor = m_DivisorList[0] * MU0 * 1000.;
773 if (l_FloatDivisor >= 1. && l_FloatDivisor <= 65535.)
774 {
775 m_UnitsList.push_back(kkApm);
776 m_DivisorList.push_back(static_cast<U32>(l_FloatDivisor + 0.5));
777 }
778 l_FloatDivisor = m_DivisorList[0] * MU0 / 1000;
779 if (l_FloatDivisor >= 1. && l_FloatDivisor <= 65535.)
780 {
781 m_UnitsList.push_back(kmApm);
782 m_DivisorList.push_back(static_cast<U32>(l_FloatDivisor + 0.5));
783 }
784
785 // Add the fake "ADC" units.
786 m_UnitsList.push_back(kADC);
787 m_DivisorList.push_back(1);
788
789} // CTHM1176InstrumentController::MakeUnitsList
790
791void CTHM1176InstrumentController::GetCurrentUnits (std::string Context)
792{
793 eUnits l_Units;
794 bool l_UseCalibration;
795 if (!m_pTHM1176->ParmUnitsGet(l_Units) ||
796 !m_pTHM1176->ParmUseCalibrationGet(l_UseCalibration))
797 throw CException<CTHM1176InstrumentManager>("Cannot get Units", Context);
798 m_Units = static_cast<eTHM1176Units>(l_Units);
799 if (!l_UseCalibration)
800 m_Units = kADC;
801
802} // CTHM1176InstrumentController::GetCurrentUnits
803
804void CTHM1176InstrumentController::TranslateUnits (CMeasurement & Measurement,
805 eUnits Units)
806{
807 F32 l_Multiplier;
808 switch (m_Units)
809 {
810 case kADC:
811 Measurement.Units = kADC;
812 break;
813
814 case kApm:
815 l_Multiplier = 1.f / MU0;
816 goto HandleApm;
817 case kkApm:
818 l_Multiplier = 0.001f / MU0;
819 goto HandleApm;
820 case kmApm:
821 l_Multiplier = 1000.f / MU0;
822 HandleApm:
823 if (Units == THM1176Types::kT)
824 {
825 for (size_t i = 0; i < Measurement.Bx.size(); i++)
826 Measurement.Bx[i] *= l_Multiplier;
827 for (size_t i = 0; i < Measurement.By.size(); i++)
828 Measurement.By[i] *= l_Multiplier;
829 for (size_t i = 0; i < Measurement.Bz.size(); i++)
830 Measurement.Bz[i] *= l_Multiplier;
831 Measurement.Units = m_Units;
832 }
833 else
834 Measurement.Units = static_cast<eTHM1176Units>(Units);
835 break;
836
837 default:
838 Measurement.Units = static_cast<eTHM1176Units>(Units);
839 break;
840 }
841
842} // CTHM1176InstrumentController::TranslateUnits
843
844//----------------------------------------------------------------------//
845// THM1176 Instrument Controller slots: Parameters //
846//----------------------------------------------------------------------//
848{
849 if (m_AveragingParms != AveragingParms)
850 {
851 if (m_pTHM1176 == nullptr ||
852 !m_pTHM1176->ParmAveragingSet(AveragingParms))
853 {
854 HandleError("Cannot change averaging parameters", __func__);
855 if(m_pTHM1176 == nullptr ||
856 !m_pTHM1176->ParmAveragingGet(m_AveragingParms))
857 HandleError("Cannot retrieve averaging parameters", __func__);
858 }
859 else
860 {
861 m_AveragingParms = AveragingParms;
862
863 // This change aborts any measurements in progress.
864 if (kTHM1176MeasureContinuously == m_OperatingMode &&
865 kInputTrigSrcTimer == m_TriggerParms.Source)
866 {
867 if (0 == m_TimerID ||
868 !m_pTHM1176->Initiate(true))
869 {
870 HandleError("Error restarting continous measurements", __func__);
871 m_OperatingMode = kTHM1176Idle;
872 emit UpdateOperatingMode(m_OperatingMode);
873 }
874 }
875 }
876 }
877 emit UpdateAveragingParms(m_AveragingParms);
878
879} // CTHM1176InstrumentController::SetAveragingParms
880
882{
883 if (m_TriggerParms != TriggerParms)
884 {
885 if (m_pTHM1176 == nullptr ||
886 !m_pTHM1176->ParmTriggerInputSet(TriggerParms))
887 {
888 HandleError("Cannot change trigger parameters", __func__);
889 if (m_pTHM1176 == nullptr ||
890 !m_pTHM1176->ParmTriggerInputGet(m_TriggerParms))
891 HandleError("Cannot retrieve trigger parameters", __func__);
892 }
893 else
894 {
895 m_TriggerParms = TriggerParms;
896
897 // This change aborts any measurements in progress.
898 if (kTHM1176MeasureContinuously == m_OperatingMode &&
899 kInputTrigSrcTimer == m_TriggerParms.Source)
900 {
901 if (0 == m_TimerID ||
902 !m_pTHM1176->Initiate(true))
903 {
904 HandleError("Error restarting continous measurements", __func__);
905 m_OperatingMode = kTHM1176Idle;
906 emit UpdateOperatingMode(m_OperatingMode);
907 }
908 }
909 }
910 }
911 emit UpdateTriggerParms(m_TriggerParms);
912
913} // CTHM1176InstrumentController::SetTriggerParms
914
916{
917 if (m_OutputSelect != OutputSelect)
918 {
919 if (m_pTHM1176 == nullptr)
920 HandleError("Cannot change output selection", __func__);
921 else
922 m_OutputSelect = OutputSelect;
923 }
924 emit UpdateOutputSelect(m_OutputSelect);
925
926} // CTHM1176InstrumentController::SetOutputSelect
927
929{
930 if (m_SleepParm != SleepParm)
931 {
932 if (m_pTHM1176 == nullptr ||
933 !m_pTHM1176->ParmSleepSet(SleepParm))
934 {
935 HandleError("Cannot change sleep parameter", __func__);
936 if (m_pTHM1176 == nullptr ||
937 !m_pTHM1176->ParmSleepGet(m_SleepParm))
938 HandleError("Cannot retrieve sleep parameter", __func__);
939 }
940 else
941 m_SleepParm = SleepParm;
942 }
943 emit UpdateSleepParm(m_SleepParm);
944
945} // CTHM1176InstrumentController::SetSleepParm
946
948{
949 if (m_Units != Units)
950 {
951 try
952 {
953 if (m_pTHM1176 == nullptr)
955
956 switch (Units)
957 {
958 case kApm:
959 case kkApm:
960 case kmApm:
961 if (!m_pTHM1176->ParmUseCalibrationSet(true) ||
962 !m_pTHM1176->ParmUnitsSet(THM1176Types::kT))
964 break;
965 case kADC:
966 if (!m_pTHM1176->ParmUseCalibrationSet(false))
968 break;
969 default:
970 eUnits l_Units = static_cast<eUnits>(Units);
971 if (!m_pTHM1176->ParmUseCalibrationSet(true) ||
972 !m_pTHM1176->ParmUnitsSet(l_Units))
974 break;
975 }
976 m_Units = Units;
977 }
979 {
980 MTL_Unused(rE);
981 HandleError("Cannot change units", __func__);
982 }
983 }
984 emit UpdateUnits(m_Units);
985
986} // CTHM1176InstrumentController::SetUnits
987
989{
990 if (m_RangeParms != RangeParms)
991 {
992 if (m_pTHM1176 == nullptr ||
993 !m_pTHM1176->ParmRangeSet(RangeParms))
994 {
995 HandleError("Cannot change range parameters", __func__);
996 if (m_pTHM1176 == nullptr ||
997 !m_pTHM1176->ParmRangeGet(m_RangeParms))
998 HandleError("Cannot retrieve range parameters", __func__);
999 }
1000 else
1001 m_RangeParms = RangeParms;
1002 }
1003 emit UpdateRangeParms(m_RangeParms);
1004
1005} // CTHM1176InstrumentController::SetRangeParms
1006
1008{
1009 if (m_CommFormat != CommFormat)
1010 {
1011 if (m_pTHM1176 == nullptr ||
1012 !m_pTHM1176->SetFormat(CommFormat))
1013 {
1014 HandleError("Cannot change communication format", __func__);
1015 if (m_pTHM1176 == nullptr ||
1016 !m_pTHM1176->GetFormat(m_CommFormat))
1017 HandleError("Cannot retrieve communication format", __func__);
1018 }
1019 else
1020 m_CommFormat = CommFormat;
1021 }
1022 emit UpdateCommFormat(m_CommFormat);
1023
1024} // CTHM1176InstrumentController::SetCommFormat
1025
1027{
1028 m_CalibrationOverride = Override;
1029
1030} // CTHM1176InstrumentManager::SetCalibrationOverride
1031
1032
1034//----------------------------------------------------------------------//
1035// THM1176 Instrument Manager: Error reporting //
1036//----------------------------------------------------------------------//
1037void CTHM1176InstrumentManager::HandleError (QString Description,
1038 QString Context)
1039{
1040 // Create the error structure.
1041 sError l_Error;
1043 l_Error.Description = Description.toStdString();
1044 l_Error.Context = Context.toStdString();
1045
1046 // Emit the update.
1047 CErrorList l_ErrorList;
1048 l_ErrorList.push_back(l_Error);
1049 emit UpdateErrorList(l_ErrorList);
1050
1051} // CTHM1176InstrumentController::HandleError
1052
1053//----------------------------------------------------------------------//
1054// THM1176 Instrument Manager: Start / Stop //
1055//----------------------------------------------------------------------//
1057{
1058 // Create Instrument Scanner and Controller
1059 m_pInstrumentScanner = new CTHM1176InstrumentScanner();
1060 m_pInstrumentController = new CTHM1176InstrumentController();
1061
1062 // Connect the Instrument Scanner slots.
1064 m_pInstrumentScanner, &CTHM1176InstrumentScanner::Start);
1066 m_pInstrumentScanner, &CTHM1176InstrumentScanner::Stop);
1067
1068 // Connect the Instrument Scanner signals.
1069 connect(m_pInstrumentScanner, &CTHM1176InstrumentScanner::UpdateInstrumentList,
1070 this, &CTHM1176InstrumentManager::UpdateInstrumentList);
1071 connect(m_pInstrumentScanner, &CTHM1176InstrumentScanner::UpdateErrorList,
1072 this, &CTHM1176InstrumentManager::UpdateErrorList);
1073
1074 // Connect the Instrument Controller slots.
1075 // - Startup and shutdown.
1077 m_pInstrumentController, &CTHM1176InstrumentController::Start);
1079 m_pInstrumentController, &CTHM1176InstrumentController::Stop);
1080 // - Connection
1081 connect(m_pInstrumentScanner, &CTHM1176InstrumentScanner::UpdateInstrumentList,
1082 m_pInstrumentController, &CTHM1176InstrumentController::UpdateInstrumentList);
1084 m_pInstrumentController, &CTHM1176InstrumentController::SetCurrentInstrument);
1085 // - Instrument control
1087 m_pInstrumentController, &CTHM1176InstrumentController::SetOperatingMode);
1089 m_pInstrumentController, &CTHM1176InstrumentController::SendTrigger,
1090 Qt::BlockingQueuedConnection);
1091 // - Parameters
1093 m_pInstrumentController, &CTHM1176InstrumentController::SetAveragingParms);
1095 m_pInstrumentController, &CTHM1176InstrumentController::SetTriggerParms);
1097 m_pInstrumentController, &CTHM1176InstrumentController::SetOutputSelect);
1099 m_pInstrumentController, &CTHM1176InstrumentController::SetSleepParm);
1101 m_pInstrumentController, &CTHM1176InstrumentController::SetUnits);
1103 m_pInstrumentController, &CTHM1176InstrumentController::SetRangeParms);
1105 m_pInstrumentController, &CTHM1176InstrumentController::SetCommFormat);
1108
1109 // Connect the Instrument Controller signals.
1110 // - Basic instrument control:
1111 connect(m_pInstrumentController, &CTHM1176InstrumentController::UpdateCurrentInstrument,
1112 this, &CTHM1176InstrumentManager::UpdateCurrentInstrument);
1113 connect(m_pInstrumentController, &CTHM1176InstrumentController::UpdateInstrumentPointer,
1114 this, &CTHM1176InstrumentManager::UpdateInstrumentPointer);
1115 connect(m_pInstrumentController, &CTHM1176InstrumentController::UpdateOperatingMode,
1116 this, &CTHM1176InstrumentManager::UpdateOperatingMode);
1117 connect(m_pInstrumentController, &CTHM1176InstrumentController::UpdateMeasurement,
1118 this, &CTHM1176InstrumentManager::UpdateMeasurement);
1119 connect(m_pInstrumentController, &CTHM1176InstrumentController::UpdateErrorList,
1120 this, &CTHM1176InstrumentManager::UpdateErrorList);
1121 // - Instrument information and parameter bounds:
1122 connect(m_pInstrumentController, &CTHM1176InstrumentController::UpdateIdentification,
1123 this, &CTHM1176InstrumentManager::UpdateIdentification);
1124 connect(m_pInstrumentController, &CTHM1176InstrumentController::UpdateRangeList,
1125 this, &CTHM1176InstrumentManager::UpdateRangeList);
1126 connect(m_pInstrumentController, &CTHM1176InstrumentController::UpdateUnitsList,
1127 this, &CTHM1176InstrumentManager::UpdateUnitsList);
1128 connect(m_pInstrumentController, &CTHM1176InstrumentController::UpdateDivisorList,
1129 this, &CTHM1176InstrumentManager::UpdateDivisorList);
1130 connect(m_pInstrumentController, &CTHM1176InstrumentController::UpdateAveragingParmBounds,
1131 this, &CTHM1176InstrumentManager::UpdateAveragingParmBounds);
1132 connect(m_pInstrumentController, &CTHM1176InstrumentController::UpdateTriggerParmBounds,
1133 this, &CTHM1176InstrumentManager::UpdateTriggerParmBounds);
1134 connect(m_pInstrumentController, &CTHM1176InstrumentController::UpdateRangeParmBounds,
1135 this, &CTHM1176InstrumentManager::UpdateRangeParmBounds);
1136 // - Parameters
1137 connect(m_pInstrumentController, &CTHM1176InstrumentController::UpdateAveragingParms,
1138 this, &CTHM1176InstrumentManager::UpdateAveragingParms);
1139 connect(m_pInstrumentController, &CTHM1176InstrumentController::UpdateTriggerParms,
1140 this, &CTHM1176InstrumentManager::UpdateTriggerParms);
1141 connect(m_pInstrumentController, &CTHM1176InstrumentController::UpdateOutputSelect,
1142 this, &CTHM1176InstrumentManager::UpdateOutputSelect);
1143 connect(m_pInstrumentController, &CTHM1176InstrumentController::UpdateSleepParm,
1144 this, &CTHM1176InstrumentManager::UpdateSleepParm);
1145 connect(m_pInstrumentController, &CTHM1176InstrumentController::UpdateUnits,
1146 this, &CTHM1176InstrumentManager::UpdateUnits);
1147 connect(m_pInstrumentController, &CTHM1176InstrumentController::UpdateRangeParms,
1148 this, &CTHM1176InstrumentManager::UpdateRangeParms);
1149 connect(m_pInstrumentController, &CTHM1176InstrumentController::UpdateCommFormat,
1150 this, &CTHM1176InstrumentManager::UpdateCommFormat);
1151
1152 // Create and initialize the resource manager.
1153 m_pResourceManager = new THM1176_RSRC_MGR_CLS;
1154 if (nullptr == m_pResourceManager || !m_pResourceManager->Initialize())
1155 HandleError("Cannot initialize Resource Manager", __func__);
1156
1157 // Move the Instrument Scanner to its own thread.
1158 m_pInstrumentScanner->moveToThread(&m_InstrumentScanThread);
1159 m_InstrumentScanThread.start();
1160
1161 // Initialize the Instrument Scanner.
1162 emit StartInstrumentScanner(m_pResourceManager);
1163
1164 // Move the Instrument Controller to its own thread.
1165 m_pInstrumentController->moveToThread(&m_InstrumentControlThread);
1166 m_InstrumentControlThread.start();
1167
1168 // Set up the Instrument Controller to clean up after itself.
1169 connect(&m_InstrumentControlThread, &QThread::finished,
1170 m_pInstrumentController, &CTHM1176InstrumentController::deleteLater);
1171 connect(&m_InstrumentControlThread, &QThread::finished,
1172 m_pInstrumentScanner, &CTHM1176InstrumentScanner::Stop);
1173 connect(&m_InstrumentScanThread, &QThread::finished,
1174 m_pInstrumentScanner, &CTHM1176InstrumentScanner::deleteLater);
1175
1176 // Initialize the Instrument Controller.
1177 emit StartInstrumentController(m_pResourceManager);
1178
1179} // CTHM1176InstrumentManager::Start
1180
1182{
1183 // Shut down the Instrument Controller.
1184 // Its thread's finished() signal will in turn shut down the Instrument Scanner.
1186
1187 // Wait for the Instrument Controller thread to shut down.
1188 if (!m_InstrumentControlThread.wait())
1189 HandleError("Cannot quit Instrument Controller thread", __func__);
1190
1191 // Wait for the Instrument Scanner thread to shut down.
1192 m_InstrumentScanThread.quit();
1193 if (!m_InstrumentScanThread.wait())
1194 HandleError("Cannot quit Instrument Scanner thread", __func__);
1195
1196 // Kill the Resource Manager.
1197 delete m_pResourceManager;
1198
1199 // Reset the object pointers to NULL, just to be sure.
1200 m_pResourceManager = nullptr;
1201 m_pTHM1176 = nullptr;
1202 m_pInstrumentScanner = nullptr;
1203 m_pInstrumentController = nullptr;
1204
1205} // CTHM1176InstrumentManager::Stop
1206
1207//----------------------------------------------------------------------//
1208// THM1176 Instrument Manager communication with Instrument Scanner //
1209//----------------------------------------------------------------------//
1210void CTHM1176InstrumentManager::UpdateInstrumentList (CResourceList InstrumentList)
1211{
1212 if (m_InstrumentList != InstrumentList)
1213 {
1214 m_InstrumentList = InstrumentList;
1215 emit NotifyInstrumentList(m_InstrumentList);
1216 }
1217
1218} //CTHM1176InstrumentManager::UpdateInstrumentList
1219
1220//----------------------------------------------------------------------//
1221// THM1176 Instrument Manager communication with Instrument Controller //
1222//----------------------------------------------------------------------//
1223// Basic instrument control:
1224void CTHM1176InstrumentManager::UpdateCurrentInstrument (tResourceName CurrentInstrument)
1225{
1226 // Only emit notification if the current instrument changes.
1227 if (m_CurrentInstrument != CurrentInstrument)
1228 {
1229 m_CurrentInstrument = CurrentInstrument;
1230 emit NotifyCurrentInstrument(m_CurrentInstrument);
1231 }
1232
1233} // CTHM1176InstrumentManager::UpdateCurrentInstrument
1234
1235void CTHM1176InstrumentManager::UpdateInstrumentPointer (CTHM1176Instrument<THM1176_INSTR_CLS, THM1176_RSRC_MGR_CLS> * pTHM1176)
1236{
1237 // The instrument pointer is for internal consumption only: just store it.
1238 m_pTHM1176 = pTHM1176;
1239
1240} // CTHM1176InstrumentManager::UpdateInstrumentPointer
1241
1242void CTHM1176InstrumentManager::UpdateOperatingMode (eTHM1176OperatingMode OperatingMode)
1243{
1244 // Only emit notification if the parameter changes.
1245 if (m_OperatingMode != OperatingMode)
1246 {
1247 m_OperatingMode = OperatingMode;
1248 emit NotifyOperatingMode(m_OperatingMode);
1249 }
1250
1251} // CTHM1176InstrumentManager::UpdateOperatingMode
1252
1253void CTHM1176InstrumentManager::UpdateMeasurement (CMeasurement Measurement)
1254{
1255 // Always emit notification of measurements.
1256 m_Measurement = Measurement;
1257 emit NotifyMeasurement(m_Measurement);
1258
1259} // CTHM1176InstrumentManager::UpdateMeasurement
1260
1261void CTHM1176InstrumentManager::UpdateErrorList (CErrorList ErrorList)
1262{
1263 // Always emit notification of errors.
1264 m_ErrorList = ErrorList;
1265 emit NotifyErrorList(m_ErrorList);
1266
1267} // CTHM1176InstrumentManager::UpdateErrorList
1268
1269// Instrument information and parameter bounds:
1270void CTHM1176InstrumentManager::UpdateIdentification (sIdentifier Identification)
1271{
1272 // Always emit – only done when connecting an instrument.
1273 m_Identification = Identification;
1274 emit NotifyIdentification(m_Identification);
1275
1276} // CTHM1176InstrumentManager::UpdateIdentification
1277
1278void CTHM1176InstrumentManager::UpdateRangeList (CFluxList RangeList)
1279{
1280 // Always emit – only done when connecting an instrument.
1281 m_RangeList = RangeList;
1282 emit NotifyRangeList(m_RangeList);
1283
1284} // CTHM1176InstrumentManager::UpdateRangeList
1285
1286void CTHM1176InstrumentManager::UpdateUnitsList (CTHM1176UnitsList UnitsList)
1287{
1288 // Always emit – only done when connecting an instrument.
1289 m_UnitsList = UnitsList;
1290 emit NotifyUnitsList(m_UnitsList);
1291
1292} // CTHM1176InstrumentManager::UpdateUnitsList
1293
1294void CTHM1176InstrumentManager::UpdateDivisorList (CDivisorList DivisorList)
1295{
1296 // Always emit – only done when connecting an instrument.
1297 m_DivisorList = DivisorList;
1298 emit NotifyDivisorList(m_DivisorList);
1299
1300} // CTHM1176InstrumentManager::UpdateDivisorList
1301
1302void CTHM1176InstrumentManager::UpdateAveragingParmBounds (sAveraging<sBoundedParm> AveragingParmBounds)
1303{
1304 // Always emit – only done when connecting an instrument.
1305 m_AveragingParmBounds = AveragingParmBounds;
1306 emit NotifyAveragingParmBounds(m_AveragingParmBounds);
1307
1308 // Also recover and emit the current parameter value.
1309 m_AveragingParms.NoPoints = m_AveragingParmBounds.NoPoints.Val;
1310 emit NotifyAveragingParms(m_AveragingParms);
1311
1312} // CTHM1176InstrumentManager::UpdateAveragingParmBounds
1313
1314void CTHM1176InstrumentManager::UpdateTriggerParmBounds (sInputTrigger<sBoundedParm> TriggerParmBounds)
1315{
1316 // Always emit – only done when connecting an instrument.
1317 m_TriggerParmBounds = TriggerParmBounds;
1318 emit NotifyTriggerParmBounds(m_TriggerParmBounds);
1319
1320 // Also recover and emit the current parameter value.
1321 m_TriggerParms.Source = TriggerParmBounds.Source;
1322 m_TriggerParms.Period_s = TriggerParmBounds.Period_s.Val;
1323 m_TriggerParms.Count = TriggerParmBounds.Count.Val;
1324 emit NotifyTriggerParms(m_TriggerParms);
1325
1326} // CTHM1176InstrumentManager::UpdateTriggerParmBounds
1327
1328void CTHM1176InstrumentManager::UpdateRangeParmBounds (sRange<sBoundedParm> RangeParmBounds)
1329{
1330 // Always emit – only done when connecting an instrument.
1331 m_RangeParmBounds = RangeParmBounds;
1332 emit NotifyRangeParmBounds(m_RangeParmBounds);
1333
1334 // Also recover and emit the current parameter value.
1335 m_RangeParms.Auto = m_RangeParmBounds.Auto;
1336 m_RangeParms.Range = m_RangeParmBounds.Range.Val;
1337 emit NotifyRangeParms(m_RangeParms);
1338
1339} // CTHM1176InstrumentManager::UpdateRangeParmBounds
1340
1341// Parameters
1342void CTHM1176InstrumentManager::UpdateAveragingParms (sAveraging<uParm> AveragingParms)
1343{
1344 // Only emit notification if the parameter changes.
1345 // Note: notification of averaging parameters at connection is handled by UpdateAveragingParmBounds.
1346 if (m_AveragingParms != AveragingParms)
1347 {
1348 m_AveragingParms = AveragingParms;
1349 emit NotifyAveragingParms(m_AveragingParms);
1350 }
1351
1352} // CTHM1176InstrumentManager::UpdateAveragingParms
1353
1354void CTHM1176InstrumentManager::UpdateTriggerParms (sInputTrigger<uParm> TriggerParms)
1355{
1356 // Only emit notification if the parameter changes.
1357 // Note: notification of trigger parameters at connection is handled by UpdateTriggerParmBounds.
1358 if (m_TriggerParms != TriggerParms)
1359 {
1360 m_TriggerParms = TriggerParms;
1361 emit NotifyTriggerParms(m_TriggerParms);
1362 }
1363
1364} // CTHM1176InstrumentManager::UpdateTriggerParms
1365
1366void CTHM1176InstrumentManager::UpdateOutputSelect (sArbitraryMeasurements OutputSelect)
1367{
1368 // Only emit notification if the parameter changes, or if instrument is not connected (i.e. connecting).
1369 if (m_OutputSelect != OutputSelect || kTHM1176NotConnected == m_OperatingMode)
1370 {
1371 m_OutputSelect = OutputSelect;
1372 emit NotifyOutputSelect(m_OutputSelect);
1373 }
1374
1375} // CTHM1176InstrumentManager::UpdateOutputSelect
1376
1377void CTHM1176InstrumentManager::UpdateSleepParm (bool SleepParm)
1378{
1379 // Only emit notification if the parameter changes, or if instrument is not connected (i.e. connecting).
1380 if (m_SleepParm != SleepParm || kTHM1176NotConnected == m_OperatingMode)
1381 {
1382 m_SleepParm = SleepParm;
1383 emit NotifySleepParm(m_SleepParm);
1384 }
1385
1386} // CTHM1176InstrumentManager::UpdateSleepParm
1387
1388void CTHM1176InstrumentManager::UpdateUnits (eTHM1176Units Units)
1389{
1390 // Only emit notification if the parameter changes, or if instrument is not connected (i.e. connecting).
1391 if (m_Units != Units || kTHM1176NotConnected == m_OperatingMode)
1392 {
1393 m_Units = Units;
1394 emit NotifyUnits(m_Units);
1395 }
1396
1397} // CTHM1176InstrumentManager::UpdateUnits
1398
1399void CTHM1176InstrumentManager::UpdateRangeParms (sRange<uParm> RangeParms)
1400{
1401 // Only emit notification if the parameter changes.
1402 // Note: notification of range parameters at connection is handled by UpdateRangeParmBounds.
1403 if (m_RangeParms != RangeParms)
1404 {
1405 m_RangeParms = RangeParms;
1406 emit NotifyRangeParms(m_RangeParms);
1407 }
1408
1409} // CTHM1176InstrumentManager::UpdateRangeParms
1410
1411void CTHM1176InstrumentManager::UpdateCommFormat (eCommunicationFormat CommFormat)
1412{
1413 // Only emit notification if the parameter changes, or if instrument is not connected (i.e. connecting).
1414 if (m_CommFormat != CommFormat || kTHM1176NotConnected == m_OperatingMode)
1415 {
1416 m_CommFormat = CommFormat;
1417 emit NotifyCommFormat(m_CommFormat);
1418 }
1419
1420} // CTHM1176InstrumentManager::UpdateCommFormat
1421
1422
1423//----------------------------------------------------------------------//
1424// THM1176 Instrument Manager property Get methods //
1425//----------------------------------------------------------------------//
1426// Basic instrument control:
1428{
1429 return m_InstrumentList;
1430
1431} // CTHM1176InstrumentManager::GetInstrumentList
1432
1434{
1435 return m_CurrentInstrument;
1436
1437} // CTHM1176InstrumentManager::GetCurrentInstrument
1438
1440{
1441 return m_OperatingMode;
1442
1443} // CTHM1176InstrumentManager::GetOperatingMode
1444
1446{
1447 if (m_pTHM1176 == nullptr)
1448 return true;
1449 return false;
1450
1451} // CTHM1176InstrumentManager::GetIsTHMNullptr
1452
1454{
1455 if (m_pTHM1176 == nullptr)
1456 HandleError("Instrument not connected", __func__);
1457 return m_Measurement;
1458
1459} // CTHM1176InstrumentManager::GetOperatingMode
1460
1462{
1463 return m_ErrorList;
1464
1465} // CTHM1176InstrumentManager::GetErrorList
1466
1467
1468// Instrument information and parameter bounds:
1470{
1471 if (m_pTHM1176 == nullptr)
1472 HandleError("Instrument not connected", __func__);
1473 return m_Identification;
1474
1475} // CTHM1176InstrumentManager::GetIdentification
1476
1478{
1479 if (m_pTHM1176 == nullptr)
1480 HandleError("Instrument not connected", __func__);
1481 return m_RangeList;
1482
1483} // CTHM1176InstrumentManager::GetRangeList
1484
1486{
1487 if (m_pTHM1176 == nullptr)
1488 HandleError("Instrument not connected", __func__);
1489 return m_UnitsList;
1490
1491} // CTHM1176InstrumentManager::GetUnitsList
1492
1494{
1495 if (m_pTHM1176 == nullptr)
1496 HandleError("Instrument not connected", __func__);
1497 return m_DivisorList;
1498
1499} // CTHM1176InstrumentManager::GetDivisorList
1500
1502{
1503 if (m_pTHM1176 == nullptr)
1504 HandleError("Instrument not connected", __func__);
1505 return m_AveragingParmBounds;
1506
1507} // CTHM1176InstrumentManager::GetAveragingParmBounds
1508
1510{
1511 if (m_pTHM1176 == nullptr)
1512 HandleError("Instrument not connected", __func__);
1513 return m_TriggerParmBounds;
1514
1515} // CTHM1176InstrumentManager::GetTriggerParmBounds
1516
1518{
1519 if (m_pTHM1176 == nullptr)
1520 HandleError("Instrument not connected", __func__);
1521 return m_RangeParmBounds;
1522
1523} // CTHM1176InstrumentManager::GetRangeParmBounds
1524
1525
1526// Parameters:
1528{
1529 if (m_pTHM1176 == nullptr)
1530 HandleError("Instrument not connected", __func__);
1531 return m_AveragingParms;
1532
1533} // CTHM1176InstrumentManager::GetAveragingParms
1534
1536{
1537 if (m_pTHM1176 == nullptr)
1538 HandleError("Instrument not connected", __func__);
1539 return m_TriggerParms;
1540
1541} // CTHM1176InstrumentManager::GetTriggerParms
1542
1544{
1545 if (m_pTHM1176 == nullptr)
1546 HandleError("Instrument not connected", __func__);
1547 return m_OutputSelect;
1548
1549} // CTHM1176InstrumentManager::GetOutputSelect
1550
1552{
1553 if (m_pTHM1176 == nullptr)
1554 HandleError("Instrument not connected", __func__);
1555 return m_SleepParm;
1556
1557} // CTHM1176InstrumentManager::GetSleepParm
1558
1560{
1561 if (m_pTHM1176 == nullptr)
1562 HandleError("Instrument not connected", __func__);
1563 return m_Units;
1564
1565} // CTHM1176InstrumentManager::GetUnits
1566
1568{
1569 if (m_pTHM1176 == nullptr)
1570 HandleError("Instrument not connected", __func__);
1571 return m_RangeParms;
1572
1573} // CTHM1176InstrumentManager::GetRangeParms
1574
1576{
1577 if (m_pTHM1176 == nullptr)
1578 HandleError("Instrument not connected", __func__);
1579 return m_CommFormat;
1580
1581} // CTHM1176InstrumentManager::GetCommFormat
1582
1584{
1585 if (m_pTHM1176 == nullptr)
1586 {
1587 HandleError("Instrument not connected", __func__);
1588 return false;
1589 }
1590 else
1591 {
1592 return m_pTHM1176->GetImmediateMeasurementPeriod(rAvg, GetIdentification().ModelRevision, rPeriod);
1593 }
1594}
1595
1596bool CTHM1176InstrumentManager::ReadInformationDates(QDateTime& rManufacturingDate, QDateTime& rCalibrationDate)
1597{
1598 if (m_pTHM1176 == nullptr)
1599 {
1600 HandleError("Instrument not connected", __func__);
1601 return false;
1602 }
1603 else
1604 {
1605 std::string l_SManufacturingDate;
1606 std::time_t l_ManufacturingDate;
1607 std::string l_SCalibrationDate;
1608 std::time_t l_CalibrationDate;
1609 bool l_Success = m_pTHM1176->ReadInformationDates(l_SManufacturingDate, l_ManufacturingDate, l_SCalibrationDate, l_CalibrationDate);
1610
1611 if(l_Success)
1612 {
1613 rManufacturingDate = QDateTime::fromSecsSinceEpoch(l_ManufacturingDate);
1614 rCalibrationDate = QDateTime::fromSecsSinceEpoch(l_CalibrationDate);
1615 }
1616
1617 return l_Success;
1618 }
1619} // CTHM1176InstrumentManager::ReadInformationDates
1620
1621
1622//----------------------------------------------------------------------//
1623// THM1176 Instrument Manager property Set methods/slots //
1624//----------------------------------------------------------------------//
1625// - Basic instrument control:
1627{
1628 // Return immediately if the value has not changed.
1629 if (CurrentInstrument == m_CurrentInstrument)
1630 return;
1631 // Ensure that the resource name is in the current resource list.
1632 auto l_pResource = m_InstrumentList.begin();
1633 for (; l_pResource < m_InstrumentList.end(); l_pResource++)
1634 if (*l_pResource == CurrentInstrument) break;
1635 if (l_pResource >= m_InstrumentList.end())
1636 {
1637 HandleError("Resource name not in resource list", __func__);
1638 return;
1639 }
1640 // If appropriate, abort any outstanding Reads blocking the Instrument Controller.
1641 if (m_pTHM1176 != nullptr &&
1642 (m_OperatingMode == kTHM1176Measure || m_OperatingMode == kTHM1176MeasureContinuously) &&
1643 m_Identification.FirmwareVersion.Major >= THM1176_MIN_VERSION_WITH_ABORTREAD &&
1644 !m_pTHM1176->AbortRead())
1645 HandleError("Cannot abort read", __func__);
1646 // Send it on to the Instrument Controller.
1648} // CTHM1176InstrumentManager::SetCurrentInstrument
1649
1651{
1652 // Ensure that the instrument is connected.
1653 if (m_pTHM1176 == nullptr)
1654 {
1655 HandleError("Instrument not connected", __func__);
1656 return;
1657 }
1658 // Return immediately if the value has not changed.
1659 if (OperatingMode == m_OperatingMode) return;
1660 // If appropriate, abort any outstanding Reads blocking the Instrument Controller.
1661 if ((m_OperatingMode == kTHM1176Measure || m_OperatingMode == kTHM1176MeasureContinuously) &&
1662 m_Identification.FirmwareVersion.Major >= THM1176_MIN_VERSION_WITH_ABORTREAD &&
1663 !m_pTHM1176->AbortRead())
1664 HandleError("Cannot abort read", __func__);
1665 // Send it on to the Instrument Controller.
1667} // CTHM1176InstrumentManager::SetOperatingMode
1668
1669// - Parameters:
1671{
1672 // Ensure that the instrument is connected.
1673 if (m_pTHM1176 == nullptr)
1674 {
1675 HandleError("Instrument not connected", __func__);
1676 return;
1677 }
1678 // Return immediately if the value has not changed.
1679 if (AveragingParms == m_AveragingParms) return;
1680 // Ensure the averaging count is in range.
1681 if (AveragingParms.NoPoints < m_AveragingParmBounds.NoPoints.Min ||
1682 AveragingParms.NoPoints > m_AveragingParmBounds.NoPoints.Max)
1683 {
1684 HandleError("Averaging parameter out of range", __func__);
1685 return;
1686 }
1687 // If appropriate, abort any outstanding Reads blocking the Instrument Controller.
1688 if ((m_OperatingMode == kTHM1176Measure || m_OperatingMode == kTHM1176MeasureContinuously) &&
1689 m_Identification.FirmwareVersion.Major >= THM1176_MIN_VERSION_WITH_ABORTREAD &&
1690 !m_pTHM1176->AbortRead())
1691 HandleError("Cannot abort read", __func__);
1692 // Send it on to the Instrument Controller.
1694} // CTHM1176InstrumentManager::SetAveragingParms
1695
1697{
1698 // Ensure that the instrument is connected.
1699 if (m_pTHM1176 == nullptr)
1700 {
1701 HandleError("Instrument not connected", __func__);
1702 return;
1703 }
1704 // Return immediately if the value has not changed.
1705 if (TriggerParms == m_TriggerParms) return;
1706 // Ensure that the trigger parameters are in range.
1707 if (TriggerParms.Count < m_TriggerParmBounds.Count.Min ||
1708 TriggerParms.Count > m_TriggerParmBounds.Count.Max ||
1709 (TriggerParms.Source == kInputTrigSrcTimer &&
1710 (TriggerParms.Period_s < m_TriggerParmBounds.Period_s.Min ||
1711 TriggerParms.Period_s > m_TriggerParmBounds.Period_s.Max)))
1712 {
1713 HandleError("Trigger parameter out of bounds", __func__);
1714 return;
1715 }
1716 // If appropriate, abort any outstanding Reads blocking the Instrument Controller.
1717 if ((m_OperatingMode == kTHM1176Measure || m_OperatingMode == kTHM1176MeasureContinuously) &&
1718 m_Identification.FirmwareVersion.Major >= THM1176_MIN_VERSION_WITH_ABORTREAD &&
1719 !m_pTHM1176->AbortRead())
1720 HandleError("Cannot abort read", __func__);
1721 // Send it on to the Instrument Controller.
1723} // CTHM1176InstrumentManager::SetTriggerParms
1724
1726{
1727 // Ensure that the instrument is connected.
1728 if (m_pTHM1176 == nullptr)
1729 {
1730 HandleError("Instrument not connected", __func__);
1731 return;
1732 }
1733 // Return immediately if the value has not changed.
1734 if (OutputSelect == m_OutputSelect) return;
1735 // Ensure that the output selection count is in range.
1736 if (OutputSelect.NoMeasurements <= 0 ||
1737 OutputSelect.NoMeasurements > m_TriggerParms.Count)
1738 {
1739 HandleError("Invalid measurement count", __func__);
1740 return;
1741 }
1742 // If appropriate, abort any outstanding Reads blocking the Instrument Controller.
1743 if ((m_OperatingMode == kTHM1176Measure || m_OperatingMode == kTHM1176MeasureContinuously) &&
1744 m_Identification.FirmwareVersion.Major >= THM1176_MIN_VERSION_WITH_ABORTREAD &&
1745 !m_pTHM1176->AbortRead())
1746 HandleError("Cannot abort read", __func__);
1747 // Send it on to the Instrument Controller.
1749} // CTHM1176InstrumentManager::SetOutputSelect
1750
1752{
1753 // Ensure that the instrument is connected.
1754 if (m_pTHM1176 == nullptr)
1755 {
1756 HandleError("Instrument not connected", __func__);
1757 return;
1758 }
1759 // Return immediately if the value has not changed.
1760 if (SleepParm == m_SleepParm) return;
1761 // If appropriate, abort any outstanding Reads blocking the Instrument Controller.
1762 if ((m_OperatingMode == kTHM1176Measure || m_OperatingMode == kTHM1176MeasureContinuously) &&
1763 m_Identification.FirmwareVersion.Major >= THM1176_MIN_VERSION_WITH_ABORTREAD &&
1764 !m_pTHM1176->AbortRead())
1765 HandleError("Cannot abort read", __func__);
1766 // Send it on to the Instrument Controller.
1768} // CTHM1176InstrumentManager::SetSleepParm
1769
1771{
1772 // Ensure that the instrument is connected.
1773 if (m_pTHM1176 == nullptr)
1774 {
1775 HandleError("Instrument not connected", __func__);
1776 return;
1777 }
1778 // Return immediately if the value has not changed.
1779 if (Units == m_Units) return;
1780 // Ensure that the selected units are supported by this instrument.
1781 auto l_pUnits = m_UnitsList.begin();
1782 for (; l_pUnits < m_UnitsList.end(); l_pUnits++)
1783 if (*l_pUnits == Units) break;
1784 if (l_pUnits >= m_UnitsList.end())
1785 {
1786 HandleError("Invalid Units", __func__);
1787 return;
1788 }
1789 // If appropriate, abort any outstanding Reads blocking the Instrument Controller.
1790 if ((m_OperatingMode == kTHM1176Measure || m_OperatingMode == kTHM1176MeasureContinuously) &&
1791 m_Identification.FirmwareVersion.Major >= THM1176_MIN_VERSION_WITH_ABORTREAD &&
1792 !m_pTHM1176->AbortRead())
1793 HandleError("Cannot abort read", __func__);
1794 // Send it on to the Instrument Controller.
1795 emit RelayUnits(Units);
1796} // CTHM1176InstrumentManager::SetUnits
1797
1799{
1800 // Ensure that the instrument is connected.
1801 if (m_pTHM1176 == nullptr)
1802 {
1803 HandleError("Instrument not connected", __func__);
1804 return;
1805 }
1806 // Return immediately if the value has not changed.
1807 if (RangeParms == m_RangeParms) return;
1808 // Ensure that any manual range selections are in range.
1809 tFlux l_Tolerance = 0.001f * RangeParms.Range;
1810 if (!RangeParms.Auto)
1811 {
1812 auto l_pRange = m_RangeList.begin();
1813 for (; l_pRange < m_RangeList.end(); l_pRange++)
1814 if (abs(*l_pRange - RangeParms.Range) < l_Tolerance) break;
1815 if (l_pRange >= m_RangeList.end())
1816 {
1817 HandleError("Invalid range selection", __func__);
1818 return;
1819 }
1820 }
1821 // If appropriate, abort any outstanding Reads blocking the Instrument Controller.
1822 if ((m_OperatingMode == kTHM1176Measure || m_OperatingMode == kTHM1176MeasureContinuously) &&
1823 m_Identification.FirmwareVersion.Major >= THM1176_MIN_VERSION_WITH_ABORTREAD &&
1824 !m_pTHM1176->AbortRead())
1825 HandleError("Cannot abort read", __func__);
1826 // Send it on to the Instrument Controller.
1828} // CTHM1176InstrumentManager::SetRangeParms
1829
1831{
1832 // Ensure that the instrument is connected.
1833 if (m_pTHM1176 == nullptr)
1834 {
1835 HandleError("Instrument not connected", __func__);
1836 return;
1837 }
1838 // Return immediately if the value has not changed.
1839 if (CommFormat == m_CommFormat) return;
1840 // If appropriate, abort any outstanding Reads blocking the Instrument Controller.
1841 if ((m_OperatingMode == kTHM1176Measure || m_OperatingMode == kTHM1176MeasureContinuously) &&
1842 m_Identification.FirmwareVersion.Major >= THM1176_MIN_VERSION_WITH_ABORTREAD &&
1843 !m_pTHM1176->AbortRead())
1844 HandleError("Cannot abort read", __func__);
1845 // Send it on to the Instrument Controller.
1847} // CTHM1176InstrumentManager::SetCommFormat
Interface definition for Metrolab THM1176/TFM1186 Instrument Manager.
Exception handling utilities.
Collection of utility macros for error messages.
#define MTL_Unused(x)
Definition Helpers.h:47
Platform Dependent Definitions.
float F32
32-bit floating-point number.
Definition OSDefines.h:33
unsigned int U32
32-bit unsigned integer.
Definition OSDefines.h:31
double F64
64-bit floating-point number.
Definition OSDefines.h:34
Exception to be thrown.
Definition Exception.h:17
const char * message() const noexcept
Return the message.
Definition Exception.h:40
const char * context() const noexcept
Return the context.
Definition Exception.h:46
Data returned for one measurement.
CErrorList Warnings
Any warnings returned during the measurement.
CFluxList Bx
Bx value for each measurement.
eTHM1176Units Units
Measurement units for Bx, By, Bz.
sInputTrigger< uParm > TriggerParms
Trigger parameters used for measurement.
CTimestampList TimestampList
Timestamp for each measurement.
sRange< uParm > RangeParms
Range parameters used for measurement.
sAveraging< uParm > AveragingParms
Averaging parameters used for measurement.
sArbitraryMeasurements OutputSelect
Output selection parameters used for measurement.
bool SleepParm
Sleep parameters used for measurement.
CFluxList By
By value for each measurement.
ushort Temp
Temperature, in arbitrary units.
CFluxList Bz
Bz value for each measurement.
eCommunicationFormat CommFormat
Communication parameters used for measurement.
THM1176 Instrument Controller class: communicate with instrument.
void UpdateOutputSelect(sArbitraryMeasurements OutputSelect)
Signal a change of the output selection parameters.
void UpdateIdentification(sIdentifier Identification)
Signal to report identifier information for newly connected instrument.
void UpdateCurrentInstrument(tResourceName CurrentInstrument)
Signal that current instrument selection has changed.
void UpdateAveragingParms(sAveraging< uParm > AveragingParms)
Signal a change of the averaging parameters.
void UpdateErrorList(CErrorList LatestErrors)
Signal that new errors have been reported.
void UpdateRangeParms(sRange< uParm > RangeParms)
Signal a change of the range parameters.
void UpdateUnitsList(CTHM1176UnitsList UnitsList)
Signal to report list of valid measurement units for newly connected instrument.
void UpdateRangeList(CFluxList RangeList)
Signal to report list of valid ranges for newly connected instrument.
void SetCommFormat(eCommunicationFormat CommFormat)
Set communication format.
void UpdateRangeParmBounds(sRange< sBoundedParm > RangeParmBounds)
Signal to report bounds of range parameters for newly connected instrument.
void UpdateInstrumentList(CResourceList InstrumentList)
Update the Instrument Controller's copy of the list of detected instruments.
void UpdateUnits(eTHM1176Units Units)
Signal a change of the measurement units.
void SetAveragingParms(sAveraging< uParm > AveragingParms)
Set the averaging parameters.
void SetUnits(eTHM1176Units Units)
Select the measurement units.
void SetOutputSelect(sArbitraryMeasurements OutputSelect)
Select what data is returned.
void UpdateTriggerParms(sInputTrigger< uParm > TriggerParms)
Signal a change of the trigger parameters.
void UpdateDivisorList(CDivisorList DivisorList)
Signal to report divisors associated with valid measurement units for newly connected instrument.
void UpdateAveragingParmBounds(sAveraging< sBoundedParm > AveragingParmBounds)
Signal to report bounds of averaging parameters for newly connected instrument.
void Stop(void)
Shut down the Instrument Controller.
void UpdateMeasurement(CMeasurement Measurement)
Signal that a new measurement is available.
void Start(THM1176_RSRC_MGR_CLS *pResourceManager)
Initialize the Instrument Controller.
void SetOperatingMode(eTHM1176OperatingMode OperatingMode)
Set operating mode.
void UpdateSleepParm(bool SleepParm)
Signal a change of the sleep parameter.
void UpdateOperatingMode(eTHM1176OperatingMode OperatingMode)
Signal that the operating mode has changed.
void UpdateTriggerParmBounds(sInputTrigger< sBoundedParm > TriggerParmBounds)
Signal to report bounds of trigger parameters for newly connected instrument.
void SetCurrentInstrument(tResourceName CurrentInstrument)
Select the instrument to connect to.
void UpdateCommFormat(eCommunicationFormat CommFormat)
Signal a change of the communication format.
void SetTriggerParms(sInputTrigger< uParm > TriggerParms)
Set the trigger parameters.
void UpdateInstrumentPointer(CTHM1176Instrument< THM1176_INSTR_CLS, THM1176_RSRC_MGR_CLS > *pTHM1176)
Signal to broadcast updated pointer to THM1176 Instrument object.
void SetRangeParms(sRange< uParm > RangeParms)
Set range parameters.
void SetCalibrationOverride(bool Override)
Set whether or not to override the check for instruments whose zero offset should not be calibrated.
void SetSleepParm(bool SleepParm)
Set whether or not the instrument sleeps after each measurement.
void SetAveragingParms(sAveraging< uParm > AveragingParms)
Set the averaging parameters.
CErrorList GetErrorList(void)
Get the current error list.
void RelayOperatingMode(eTHM1176OperatingMode OperatingMode)
Internal signal to relay the operating mode selection to the Instrument Controller.
sArbitraryMeasurements GetOutputSelect(void)
Get the output selection parameters.
sAveraging< sBoundedParm > AveragingParmBounds
Bounds on averaging parameter.
bool ReadInformationDates(QDateTime &rManufacturingDate, QDateTime &rCalibrationDate)
Fetch the intrument's date information.
static const I32 THM1176_INST_MGR_ERROR
Additional error code: Instrument Manager Error.
eTHM1176Units Units
Current measurement units.
void SetSleepParm(bool SleepParm)
Set the sleep parameter.
eTHM1176Units GetUnits(void)
Get the measurement units.
eTHM1176OperatingMode GetOperatingMode(void)
Get the current operating mode.
sInputTrigger< sBoundedParm > GetTriggerParmBounds(void)
Get the bounds on trigger parameters.
void RelayTriggerParms(sInputTrigger< uParm > TriggerParms)
Internal signal to relay the trigger parameters to the Instrument Controller.
void SetOutputSelect(sArbitraryMeasurements OutputSelect)
Set the output selection parameters.
bool SleepParm
Sleep parameter: true if instrument should sleep after each measurement.
sRange< uParm > RangeParms
Current range parameters.
CTHM1176UnitsList GetUnitsList(void)
Get the list of valid measurement units for this instrument model.
CMeasurement GetMeasurement(void)
Get the last set of measurements.
sInputTrigger< uParm > GetTriggerParms(void)
Get the trigger parameters.
void NotifyTriggerParmBounds(sInputTrigger< sBoundedParm > TriggerParmBounds)
Notify that the bounds on trigger parameters have changed.
static const I32 THM1176_INST_CTLR_ERROR
Additional error code: Instrument Controller Error.
CFluxList RangeList
List of valid ranges for this instrument model.
eCommunicationFormat GetCommFormat(void)
Get the communication format parameters.
void RelayCurrentInstrument(tResourceName CurrentInstrument)
Internal signal to relay the instrument selection to the Instrument Controller.
void NotifyAveragingParmBounds(sAveraging< sBoundedParm > AveragingParmBounds)
Notify that the bounds on averaging parameters have changed.
CDivisorList DivisorList
List of divisors for each measurement unit for this instrument model, to convert "base" units to the ...
void NotifyAveragingParms(sAveraging< uParm > AveragingParms)
Notify that the averaging parameters have changed.
sInputTrigger< sBoundedParm > TriggerParmBounds
Bounds on trigger parameters.
bool GetIsTHMNullptr(void)
Get the test result of m_pTHM1176 pointer is Nullptr.
void NotifyUnits(eTHM1176Units Units)
Notify that the measurement units have changed.
sAveraging< uParm > GetAveragingParms(void)
Get the averaging parameters.
void NotifyCurrentInstrument(tResourceName CurrentInstrument)
Notify that the currently connected instrument has changed.
void NotifySleepParm(bool SleepParm)
Notify that the sleep parameter has changed.
void NotifyUnitsList(CTHM1176UnitsList UnitsList)
Notify that the list of valid measurement units has changed.
void NotifyRangeParms(sRange< uParm > RangeParms)
Notify that the range parameters have changed.
bool GetImmediateMeasurementPeriod(const sAveraging< uParm > &rAvg, F64 &rPeriod)
Get measurement interval for Immediate Trigger, for a given averaging parameter.
void SetCalibrationOverride(bool Override)
Set whether or not to override the check for instruments whose zero offset should not be calibrated.
sIdentifier GetIdentification(void)
Get the current instrument's identification information.
void NotifyDivisorList(CDivisorList DivisorList)
Notify that the list of divisors associated with each measurement unit for this instrument model has ...
void SendTrigger(void)
Send a bus trigger to the instrument (both slot and signal).
void RelayAveragingParms(sAveraging< uParm > AveragingParms)
Internal signal to relay the averaging parameters to the Instrument Controller.
void RelayUnits(eTHM1176Units Units)
Internal signal to relay the measurement units to the Instrument Controller.
void RelayOutputSelect(sArbitraryMeasurements OutputSelect)
Internal signal to relay the output selection parameters to the Instrument Controller.
void NotifyCommFormat(eCommunicationFormat CommFormat)
Notify that the communication format parameters have changed.
sArbitraryMeasurements OutputSelect
Output selection parameters: select what data elements are returned.
CMeasurement Measurement
Last measurement set returned.
sRange< sBoundedParm > RangeParmBounds
Bounds on range parameters.
static const I32 THM1176_INST_SCANNER_ERROR
Additional error code: Instrument Scanner Error.
void SetRangeParms(sRange< uParm > RangeParms)
Set the range parameters.
void NotifyMeasurement(CMeasurement Measurement)
Notify that a new set of measurements is available.
bool GetSleepParm(void)
Get the sleep parameter.
void SetOperatingMode(eTHM1176OperatingMode OperatingMode)
Set a new operating mode, for example to start measuring.
void NotifyTriggerParms(sInputTrigger< uParm > TriggerParms)
Notify that the trigger parameters have changed.
void StopInstrumentController(void)
Internal signal to stop the Instrument Controller.
void StopInstrumentScanner(void)
Internal signal to stop the Instrument Scanner.
void NotifyInstrumentList(CResourceList InstrumentList)
Notify that the list of detected instruments has changed.
CResourceList GetInstrumentList(void)
Get the list of connected instruments.
void RelayCommFormat(eCommunicationFormat CommFormat)
Internal signal to relay the communications format to the Instrument Controller.
void SetTriggerParms(sInputTrigger< uParm > TriggerParms)
Set the trigger parameters.
tResourceName CurrentInstrument
Currently connected instrument.
sIdentifier Identification
Identification information of currently connected instrument.
CResourceList InstrumentList
List of detected instruments.
CErrorList ErrorList
Current error list.
void StartInstrumentScanner(THM1176_RSRC_MGR_CLS *pResourceManager)
Internal signal to start the Instrument Scanner.
void SetCommFormat(eCommunicationFormat CommFormat)
Set the communication format parameters.
void StartInstrumentController(THM1176_RSRC_MGR_CLS *pResourceManager)
Internal signal to start to Instrument Controller.
void NotifyRangeParmBounds(sRange< sBoundedParm > RangeParmBounds)
Notify that the bounds on range parameters have changed.
tResourceName GetCurrentInstrument(void)
Get VISA resource name of currently connected instrument.
void NotifyOperatingMode(eTHM1176OperatingMode OperatingMode)
Notify that the operating mode has changed.
void NotifyErrorList(CErrorList ErrorList)
Notify that new errors are present.
void Start(void)
Initialize the THM1176 Instrument Manager.
void RelaySleepParm(bool SleepParm)
Internal signal to relay the sleep parameter to the Instrument Controller.
void NotifyRangeList(CFluxList RangeList)
Notify that the list of valid ranges has changed.
void Stop(void)
Shut down the THM1176 Instrument Manager.
eCommunicationFormat CommFormat
Current communication format parameter.
void RelayRangeParms(sRange< uParm > RangeParms)
Internal signal to relay the range parameters to the Instrument Controller.
sRange< uParm > GetRangeParms(void)
Get the range parameters.
sAveraging< uParm > AveragingParms
Current averaging parameters.
sRange< sBoundedParm > GetRangeParmBounds(void)
Get the bounds on range parameters.
void SetCurrentInstrument(tResourceName CurrentInstrument)
Connect a new instrument.
sAveraging< sBoundedParm > GetAveragingParmBounds(void)
Get the bounds on averaging parameters.
CDivisorList GetDivisorList(void)
Get the list of divisors associated with each measurement unit for this instrument model.
CFluxList GetRangeList(void)
Get list of valid ranges for this instrument model.
void NotifyIdentification(sIdentifier Identification)
Notify that the instrument identification information has changed.
void NotifyOutputSelect(sArbitraryMeasurements OutputSelect)
Notify that the output selection parameters have changed.
sInputTrigger< uParm > TriggerParms
Current trigger parameters.
eTHM1176OperatingMode OperatingMode
Current operating mode.
CTHM1176UnitsList UnitsList
List of valid measurement units for this instrument model.
void SetUnits(eTHM1176Units Units)
Set the measurement units.
THM1176 Instrument Scanner class: scan for connected instruments.
void UpdateErrorList(CErrorList ErrorList)
An update to the error list is available.
void Stop(void)
Shut down THM1176 Instrument Scanner.
void Start(THM1176_RSRC_MGR_CLS *pResourceManager)
Initialize THM1176 Instrument Scanner.
void UpdateInstrumentList(CResourceList InstrumentList)
An update to the instrument list is available.
List of VISA resource names.
THM1176 instrument class.
Definition THM1176.h:98
bool ParmAveragingGet(sAveraging< uParm > &rAvg)
Fetch the currently selected averaging parameter.
Definition THM1176.cpp:942
bool GetIdentification(std::string &rIdentification)
Fetch the intrument's identification string.
Definition THM1176.cpp:1991
bool Initiate(bool Continuous=false)
Initiate measurements.
Definition THM1176.cpp:1447
bool GetAllRanges(CFluxList &rRanges)
Fetch all the intrument's ranges.
Definition THM1176.cpp:2011
bool ParmSleepGet(bool &rSleep)
Fetch parameter whether to sleep after each acquisition.
Definition THM1176.cpp:1004
bool ParmRangeGet(sRange< uParm > &rRange)
Fetch currently selected measurement range.
Definition THM1176.cpp:1247
bool ParmTriggerInputGet(sInputTrigger< uParm > &rInputTrig)
Fetch current trigger input parameters.
Definition THM1176.cpp:1052
bool GetFormat(eCommunicationFormat &Format)
Retrieve whether data is returned as text or binary.
Definition THM1176.cpp:1717
const CErrorList & CurrentErrorList()
Fetch current error list.
Definition THM1176.cpp:832
bool MeasurementsGet(U32 NoMeasurements, CFluxList &rBx, CFluxList &rBy, CFluxList &rBz, eUnits &rUnits, U16 &rTemp, CTimestampList &rTimestampList, sMeasurementConditions *pMeasurementConditions=NULL)
Retrieve measurements: short form.
Definition THM1176.cpp:1491
List of divisors, one per measurement unit.
List of errors returned by the instrument.
List of flux density values.
F32 tFlux
Flux density value, as 32-bit floating-point number.
eCommunicationFormat
Enumeration of possible formats for returned data.
@ kComFormatAscii
Human-legible text.
@ 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.
eUnits
Enumeration of possible measurement units.
std::string tResourceName
IEEE488 resource name.
eTHM1176OperatingMode
Operating modes used to initiate actions or provide status.
@ kTHM1176RestoreZeroOffset
Restore the factory zero-offset setting.
@ kTHM1176CalibrateZeroOffset
Initiate the zero-offset calibration procedure.
@ kTHM1176Reset
Reset instrument.
@ kTHM1176NotConnected
Disconnect instrument.
@ kTHM1176Measure
Start a single measurement.
@ kTHM1176MeasureContinuously
Start a continuous measurement.
@ kTHM1176Idle
Place the instrument in idle mode.
eTHM1176Units
Enumeration of possible measurement units, including "ADC".
@ kmApm
Equivalent H in a vacuum, in mA/m.
@ kkApm
Equivalent H in a vacuum, in kA/m.
@ kApm
Equivalent H in a vacuum, in A/m.
@ kADC
Raw ADC values.
Specify the measurement data to be returned.
U32 NoMeasurements
Return this number of measurements.
ParmType< U16 > NoPoints
Number of points in block average.
void clear(void)
Clear to default (zero).
Error returned by the instrument.
std::string Context
SCPI commands being executed at time of error.
std::string Description
Error description.
Instrument's identification string - parsed version.
ParmType< U16 > Count
Trigger count: take this many measurements before sending results.
eInputTriggerSource Source
Trigger source.
ParmType< F64 > Period_s
Trigger period, for timed trigger.
Summary of the parameters used to make a measurement.
sAveraging< uParm > AveragingParms
Averaging parameters.
sInputTrigger< uParm > TriggerParms
Trigger parameters.
Measurement range parameter.
void clear(void)
Clear to default values.
bool Auto
Auto-ranging enabled.
ParmType< tFlux > Range
Measurement range, if auto-ranging is not enabled.