THM1176InstrumentManager 1.1
Qt Object abstraction for Metrolab THM1176
Loading...
Searching...
No Matches
CTHM1176MeasurementsTest.cpp
Go to the documentation of this file.
1// Copyright (c) 2020 Metrolab Technology S.A., Geneva, Switzerland (www.metrolab.com)
2// See the included file LICENSE.txt for the licensing conditions.
3
7
8#include "gtest/gtest.h"
10#include <ctime>
11#include <chrono>
12#include <thread>
13
14using namespace MTL::Instrument;
15using namespace MTL::Instrument::THM1176Types;
16
18static const U32 THM1176_AVG_COUNT (100);
19static const F64 THM1176_IMMEDIATE_TIME_PER_ACQ (1.0281823091218700E+05); // ns
20static const F64 THM1176_IMMEDIATE_TIME_PER_MEAS (4.4532792007542600E+04); // ns
22
24class CTHM1176MeasuresTest : public ::testing::Test
25{
26protected:
27 static THM1176_TEST_RESOURCE_MANAGER_CLASS * pResourceManager;
29
30 static void SetUpTestCase()
31 {
33 ASSERT_NE(nullptr, pResourceManager);
34 ASSERT_NE(nullptr, pTHM1176);
35 ASSERT_EQ(true, pTHM1176->IsOpen());
36 ASSERT_EQ(true, pTHM1176->Reset());
37 }
38
39 static void TearDownTestCase()
40 {
41 delete pTHM1176;
42 pTHM1176 = nullptr;
43 delete pResourceManager;
44 pResourceManager = nullptr;
45 }
46
47 virtual void SetUp()
48 {
49 // Reset the instrument.
50 ASSERT_NE(pTHM1176, nullptr);
51 ASSERT_EQ(true, pTHM1176->Reset());
52
53 // Set lowest range and enable averaging, so that PACKED,1 will hopefully work.
54 sRange<sBoundedParm> l_RangeBounds;
55 ASSERT_EQ(true, pTHM1176->ParmRangeGet(l_RangeBounds));
56 sRange<uParm> l_Range;
57 l_Range.Auto = false;
58 l_Range.Range = l_RangeBounds.Range.Min;
59 ASSERT_EQ(true, pTHM1176->ParmRangeSet(l_Range));
60
61 sAveraging<sBoundedParm> l_AvgBounds;
62 ASSERT_EQ(true, pTHM1176->ParmAveragingGet(l_AvgBounds));
65 ASSERT_EQ(true, pTHM1176->ParmAveragingSet(l_Avg));
66
67 // Acquire THM1176_NO_MEASUREMENTS measurements with immediate trigger.
68 sInputTrigger<sBoundedParm> l_TrigBounds;
69 ASSERT_EQ(true, pTHM1176->ParmTriggerInputGet(l_TrigBounds));
73 ASSERT_EQ(true, pTHM1176->ParmTriggerInputSet(l_Trig));
74 ASSERT_EQ(true, pTHM1176->Initiate());
75 }
76};
77THM1176_TEST_RESOURCE_MANAGER_CLASS * CTHM1176MeasuresTest::pResourceManager = nullptr;
79
82{
83 // Format should be ASCII by default.
84 CSCPIBuffer l_Buffer;
85 ASSERT_EQ(true, pTHM1176->Write("FORM?") && pTHM1176->Read(l_Buffer));
86 EXPECT_EQ("ASCII\n", std::string(l_Buffer.begin(), l_Buffer.end()));
87
88 // Test setting to INTEGER.
89 ASSERT_EQ(true, pTHM1176->SetFormat(kComFormatInteger));
90 ASSERT_EQ(true, pTHM1176->Write("FORM?") && pTHM1176->Read(l_Buffer));
91 EXPECT_EQ("INTEGER\n", std::string(l_Buffer.begin(), l_Buffer.end()));
92
93 // Test setting back to ASCII.
94 ASSERT_EQ(true, pTHM1176->SetFormat(kComFormatAscii));
95 ASSERT_EQ(true, pTHM1176->Write("FORM?") && pTHM1176->Read(l_Buffer));
96 EXPECT_EQ("ASCII\n", std::string(l_Buffer.begin(), l_Buffer.end()));
97
98 // Test setting to PACKED,2.
99 ASSERT_EQ(true, pTHM1176->SetFormat(kComFormatPacked2Byte));
100 ASSERT_EQ(true, pTHM1176->Write("FORM?") && pTHM1176->Read(l_Buffer));
101 EXPECT_EQ("PACKED,2\n", std::string(l_Buffer.begin(), l_Buffer.end()));
102
103 // Test setting to PACKED,1.
104 ASSERT_EQ(true, pTHM1176->SetFormat(kComFormatPacked1Byte));
105 ASSERT_EQ(true, pTHM1176->Write("FORM?") && pTHM1176->Read(l_Buffer));
106 EXPECT_EQ("PACKED,1\n", std::string(l_Buffer.begin(), l_Buffer.end()));
107}
108
111{
112 eCommunicationFormat l_Format;
113
114 // Format should be ASCII by default.
115 ASSERT_EQ(true, pTHM1176->GetFormat(l_Format) && l_Format == kComFormatAscii);
116
117 // Test setting to INTEGER.
118 ASSERT_EQ(true, pTHM1176->Write("FORM INTEGER"));
119 ASSERT_EQ(true, pTHM1176->GetFormat(l_Format) && l_Format == kComFormatInteger);
120
121 // Test setting back to ASCII.
122 ASSERT_EQ(true, pTHM1176->Write("FORM ASCII"));
123 ASSERT_EQ(true, pTHM1176->GetFormat(l_Format) && l_Format == kComFormatAscii);
124
125 // Test setting to PACKED,2.
126 ASSERT_EQ(true, pTHM1176->Write("FORM PACKED,2"));
127 ASSERT_EQ(true, pTHM1176->GetFormat(l_Format) && l_Format == kComFormatPacked2Byte);
128
129 // Test setting to PACKED,1.
130 ASSERT_EQ(true, pTHM1176->Write("FORM PACKED,1"));
131 ASSERT_EQ(true, pTHM1176->GetFormat(l_Format) && l_Format == kComFormatPacked1Byte);
132}
133
136{
137 CFluxList l_Bx, l_By, l_Bz;
138 eUnits l_Units;
139 U16 l_Temperature;
140 CTimestampList l_TimestampList;
141 U64 l_TimestampInterval;
142 CErrorList l_ErrorList;
143
144 // NoMeasurements = 0.
145 {
146 // ASCII format.
147 l_Bx.clear(); l_By.clear(); l_Bz.clear(); l_Temperature = 0; l_TimestampList.clear();
148 ASSERT_EQ(true, pTHM1176->SetFormat(kComFormatAscii));
149 ASSERT_EQ(false, pTHM1176->MeasurementsGet(0, l_Bx, l_By, l_Bz, l_Units, l_Temperature, l_TimestampList));
150 {
151 l_ErrorList = pTHM1176->CurrentErrorList();
152 EXPECT_EQ(3, l_ErrorList.size());
153 EXPECT_EQ(-222, l_ErrorList[0].Code);
154 EXPECT_EQ(-222, l_ErrorList[1].Code);
155 EXPECT_EQ(-222, l_ErrorList[2].Code);
156 }
157 EXPECT_EQ(0, l_Bx.size());
158 EXPECT_EQ(0, l_By.size());
159 EXPECT_EQ(0, l_Bz.size());
160 EXPECT_EQ(0, l_Temperature);
161 ASSERT_EQ(0, l_TimestampList.size());
162
163 // Retrieve the data in INTEGER format.
164 l_Bx.clear(); l_By.clear(); l_Bz.clear(); l_Temperature = 0; l_TimestampList.clear();
165 ASSERT_EQ(true, pTHM1176->SetFormat(kComFormatInteger));
166 ASSERT_EQ(false, pTHM1176->MeasurementsGet(0, l_Bx, l_By, l_Bz, l_Units, l_Temperature, l_TimestampList));
167 {
168 l_ErrorList = pTHM1176->CurrentErrorList();
169 EXPECT_EQ(3, l_ErrorList.size());
170 EXPECT_EQ(-222, l_ErrorList[0].Code);
171 EXPECT_EQ(-222, l_ErrorList[1].Code);
172 EXPECT_EQ(-222, l_ErrorList[2].Code);
173 }
174 EXPECT_EQ(0, l_Bx.size());
175 EXPECT_EQ(0, l_By.size());
176 EXPECT_EQ(0, l_Bz.size());
177 EXPECT_EQ(0, l_Temperature);
178 ASSERT_EQ(0, l_TimestampList.size());
179
180 // Retrieve the data in PACKED,2 format.
181 l_Bx.clear(); l_By.clear(); l_Bz.clear(); l_Temperature = 0; l_TimestampList.clear();
182 ASSERT_EQ(true, pTHM1176->SetFormat(kComFormatPacked2Byte));
183 ASSERT_EQ(false, pTHM1176->MeasurementsGet(0, l_Bx, l_By, l_Bz, l_Units, l_Temperature, l_TimestampList));
184 {
185 l_ErrorList = pTHM1176->CurrentErrorList();
186 EXPECT_EQ(3, l_ErrorList.size());
187 EXPECT_EQ(-222, l_ErrorList[0].Code);
188 EXPECT_EQ(-222, l_ErrorList[1].Code);
189 EXPECT_EQ(-222, l_ErrorList[2].Code);
190 }
191 EXPECT_EQ(0, l_Bx.size());
192 EXPECT_EQ(0, l_By.size());
193 EXPECT_EQ(0, l_Bz.size());
194 EXPECT_EQ(0, l_Temperature);
195 ASSERT_EQ(0, l_TimestampList.size());
196
197 // Retrieve the data in PACKED,1 format.
198 l_Bx.clear(); l_By.clear(); l_Bz.clear(); l_Temperature = 0; l_TimestampList.clear();
199 ASSERT_EQ(true, pTHM1176->SetFormat(kComFormatPacked1Byte));
200 ASSERT_EQ(false, pTHM1176->MeasurementsGet(0, l_Bx, l_By, l_Bz, l_Units, l_Temperature, l_TimestampList));
201 {
202 l_ErrorList = pTHM1176->CurrentErrorList();
203 EXPECT_EQ(3, l_ErrorList.size());
204 EXPECT_EQ(-222, l_ErrorList[0].Code);
205 EXPECT_EQ(-222, l_ErrorList[1].Code);
206 EXPECT_EQ(-222, l_ErrorList[2].Code);
207 }
208 EXPECT_EQ(0, l_Bx.size());
209 EXPECT_EQ(0, l_By.size());
210 EXPECT_EQ(0, l_Bz.size());
211 EXPECT_EQ(0, l_Temperature);
212 ASSERT_EQ(0, l_TimestampList.size());
213 }
214
215 // NoMeasurements = THM1176_NO_MEASUREMENTS.
216 {
217 // ASCII format.
218 l_Bx.clear(); l_By.clear(); l_Bz.clear(); l_Temperature = 0; l_TimestampList.clear();
219 ASSERT_EQ(true, pTHM1176->SetFormat(kComFormatAscii));
220 ASSERT_EQ(true, pTHM1176->MeasurementsGet(THM1176_NO_MEASUREMENTS, l_Bx, l_By, l_Bz, l_Units, l_Temperature, l_TimestampList));
221 EXPECT_EQ(THM1176_NO_MEASUREMENTS, l_Bx.size());
222 EXPECT_EQ(THM1176_NO_MEASUREMENTS, l_By.size());
223 EXPECT_EQ(THM1176_NO_MEASUREMENTS, l_Bz.size());
224 EXPECT_LT(0, l_Temperature);
225 ASSERT_EQ(THM1176_NO_MEASUREMENTS, l_TimestampList.size());
226 for (int i = 0; i < THM1176_NO_MEASUREMENTS - 1; i++)
227 {
228 l_TimestampInterval = l_TimestampList[i+1] - l_TimestampList[i];
229 EXPECT_EQ(l_TimestampInterval, THM1176_TIME_PER_MEASUREMENT);
230 }
231
232 // Retrieve the data in INTEGER format.
233 l_Bx.clear(); l_By.clear(); l_Bz.clear(); l_Temperature = 0; l_TimestampList.clear();
234 ASSERT_EQ(true, pTHM1176->SetFormat(kComFormatInteger));
235 ASSERT_EQ(true, pTHM1176->MeasurementsGet(THM1176_NO_MEASUREMENTS, l_Bx, l_By, l_Bz, l_Units, l_Temperature, l_TimestampList));
236 EXPECT_EQ(THM1176_NO_MEASUREMENTS, l_Bx.size());
237 EXPECT_EQ(THM1176_NO_MEASUREMENTS, l_By.size());
238 EXPECT_EQ(THM1176_NO_MEASUREMENTS, l_Bz.size());
239 EXPECT_LT(0, l_Temperature);
240 ASSERT_EQ(THM1176_NO_MEASUREMENTS, l_TimestampList.size());
241 for (int i = 0; i < THM1176_NO_MEASUREMENTS - 1; i++)
242 {
243 l_TimestampInterval = l_TimestampList[i+1] - l_TimestampList[i];
244 EXPECT_EQ(l_TimestampInterval, THM1176_TIME_PER_MEASUREMENT);
245 }
246
247 // Retrieve the data in PACKED,2 format.
248 l_Bx.clear(); l_By.clear(); l_Bz.clear(); l_Temperature = 0; l_TimestampList.clear();
249 ASSERT_EQ(true, pTHM1176->SetFormat(kComFormatPacked2Byte));
250 ASSERT_EQ(true, pTHM1176->MeasurementsGet(THM1176_NO_MEASUREMENTS, l_Bx, l_By, l_Bz, l_Units, l_Temperature, l_TimestampList));
251 EXPECT_EQ(THM1176_NO_MEASUREMENTS, l_Bx.size());
252 EXPECT_EQ(THM1176_NO_MEASUREMENTS, l_By.size());
253 EXPECT_EQ(THM1176_NO_MEASUREMENTS, l_Bz.size());
254 EXPECT_LT(0, l_Temperature);
255 ASSERT_EQ(THM1176_NO_MEASUREMENTS, l_TimestampList.size());
256 for (int i = 0; i < THM1176_NO_MEASUREMENTS - 1; i++)
257 {
258 l_TimestampInterval = l_TimestampList[i+1] - l_TimestampList[i];
259 EXPECT_EQ(l_TimestampInterval, THM1176_TIME_PER_MEASUREMENT);
260 }
261
262 // Retrieve the data in PACKED,1 format.
263 l_Bx.clear(); l_By.clear(); l_Bz.clear(); l_Temperature = 0; l_TimestampList.clear();
264 ASSERT_EQ(true, pTHM1176->SetFormat(kComFormatPacked1Byte));
265 ASSERT_EQ(true, pTHM1176->MeasurementsGet(THM1176_NO_MEASUREMENTS, l_Bx, l_By, l_Bz, l_Units, l_Temperature, l_TimestampList));
266 EXPECT_EQ(THM1176_NO_MEASUREMENTS, l_Bx.size());
267 EXPECT_EQ(THM1176_NO_MEASUREMENTS, l_By.size());
268 EXPECT_EQ(THM1176_NO_MEASUREMENTS, l_Bz.size());
269 EXPECT_LT(0, l_Temperature);
270 ASSERT_EQ(THM1176_NO_MEASUREMENTS, l_TimestampList.size());
271 for (int i = 0; i < THM1176_NO_MEASUREMENTS - 1; i++)
272 {
273 l_TimestampInterval = l_TimestampList[i+1] - l_TimestampList[i];
274 EXPECT_EQ(l_TimestampInterval, THM1176_TIME_PER_MEASUREMENT);
275 }
276 }
277
278 // NoMeasurements = THM1176_NO_MEASUREMENTS-1.
279 {
280 // ASCII format.
281 l_Bx.clear(); l_By.clear(); l_Bz.clear(); l_Temperature = 0; l_TimestampList.clear();
282 ASSERT_EQ(true, pTHM1176->SetFormat(kComFormatAscii));
283 ASSERT_EQ(true, pTHM1176->MeasurementsGet(THM1176_NO_MEASUREMENTS-1, l_Bx, l_By, l_Bz, l_Units, l_Temperature, l_TimestampList));
284 EXPECT_EQ(THM1176_NO_MEASUREMENTS-1, l_Bx.size());
285 EXPECT_EQ(THM1176_NO_MEASUREMENTS-1, l_By.size());
286 EXPECT_EQ(THM1176_NO_MEASUREMENTS-1, l_Bz.size());
287 EXPECT_LT(0, l_Temperature);
288 ASSERT_EQ(THM1176_NO_MEASUREMENTS-1, l_TimestampList.size());
289 for (int i = 0; i < THM1176_NO_MEASUREMENTS - 2; i++)
290 {
291 l_TimestampInterval = l_TimestampList[i+1] - l_TimestampList[i];
292 EXPECT_EQ(l_TimestampInterval, THM1176_TIME_PER_MEASUREMENT);
293 }
294
295 // Retrieve the data in INTEGER format.
296 l_Bx.clear(); l_By.clear(); l_Bz.clear(); l_Temperature = 0; l_TimestampList.clear();
297 ASSERT_EQ(true, pTHM1176->SetFormat(kComFormatInteger));
298 ASSERT_EQ(true, pTHM1176->MeasurementsGet(THM1176_NO_MEASUREMENTS-1, l_Bx, l_By, l_Bz, l_Units, l_Temperature, l_TimestampList));
299 EXPECT_EQ(THM1176_NO_MEASUREMENTS-1, l_Bx.size());
300 EXPECT_EQ(THM1176_NO_MEASUREMENTS-1, l_By.size());
301 EXPECT_EQ(THM1176_NO_MEASUREMENTS-1, l_Bz.size());
302 EXPECT_LT(0, l_Temperature);
303 ASSERT_EQ(THM1176_NO_MEASUREMENTS-1, l_TimestampList.size());
304 for (int i = 0; i < THM1176_NO_MEASUREMENTS - 2; i++)
305 {
306 l_TimestampInterval = l_TimestampList[i+1] - l_TimestampList[i];
307 EXPECT_EQ(l_TimestampInterval, THM1176_TIME_PER_MEASUREMENT);
308 }
309
310 // Retrieve the data in PACKED,2 format.
311 l_Bx.clear(); l_By.clear(); l_Bz.clear(); l_Temperature = 0; l_TimestampList.clear();
312 ASSERT_EQ(true, pTHM1176->SetFormat(kComFormatPacked2Byte));
313 ASSERT_EQ(true, pTHM1176->MeasurementsGet(THM1176_NO_MEASUREMENTS-1, l_Bx, l_By, l_Bz, l_Units, l_Temperature, l_TimestampList));
314 EXPECT_EQ(THM1176_NO_MEASUREMENTS-1, l_Bx.size());
315 EXPECT_EQ(THM1176_NO_MEASUREMENTS-1, l_By.size());
316 EXPECT_EQ(THM1176_NO_MEASUREMENTS-1, l_Bz.size());
317 EXPECT_LT(0, l_Temperature);
318 ASSERT_EQ(THM1176_NO_MEASUREMENTS-1, l_TimestampList.size());
319 for (int i = 0; i < THM1176_NO_MEASUREMENTS - 2; i++)
320 {
321 l_TimestampInterval = l_TimestampList[i+1] - l_TimestampList[i];
322 EXPECT_EQ(l_TimestampInterval, THM1176_TIME_PER_MEASUREMENT);
323 }
324
325 // Retrieve the data in PACKED,1 format.
326 l_Bx.clear(); l_By.clear(); l_Bz.clear(); l_Temperature = 0; l_TimestampList.clear();
327 ASSERT_EQ(true, pTHM1176->SetFormat(kComFormatPacked1Byte));
328 ASSERT_EQ(true, pTHM1176->MeasurementsGet(THM1176_NO_MEASUREMENTS-1, l_Bx, l_By, l_Bz, l_Units, l_Temperature, l_TimestampList));
329 EXPECT_EQ(THM1176_NO_MEASUREMENTS-1, l_Bx.size());
330 EXPECT_EQ(THM1176_NO_MEASUREMENTS-1, l_By.size());
331 EXPECT_EQ(THM1176_NO_MEASUREMENTS-1, l_Bz.size());
332 EXPECT_LT(0, l_Temperature);
333 ASSERT_EQ(THM1176_NO_MEASUREMENTS-1, l_TimestampList.size());
334 for (int i = 0; i < THM1176_NO_MEASUREMENTS - 2; i++)
335 {
336 l_TimestampInterval = l_TimestampList[i+1] - l_TimestampList[i];
337 EXPECT_EQ(l_TimestampInterval, THM1176_TIME_PER_MEASUREMENT);
338 }
339 }
340 // NoMeasurements = THM1176_NO_MEASUREMENTS+1.
341 {
342 // ASCII format.
343 l_Bx.clear(); l_By.clear(); l_Bz.clear(); l_Temperature = 0; l_TimestampList.clear();
344 ASSERT_EQ(true, pTHM1176->SetFormat(kComFormatAscii));
345 ASSERT_EQ(false, pTHM1176->MeasurementsGet(THM1176_NO_MEASUREMENTS+1, l_Bx, l_By, l_Bz, l_Units, l_Temperature, l_TimestampList));
346 {
347 l_ErrorList = pTHM1176->CurrentErrorList();
348 EXPECT_EQ(3, l_ErrorList.size());
349 EXPECT_EQ(-222, l_ErrorList[0].Code);
350 EXPECT_EQ(-222, l_ErrorList[1].Code);
351 EXPECT_EQ(-222, l_ErrorList[2].Code);
352 }
353 EXPECT_EQ(0, l_Bx.size());
354 EXPECT_EQ(0, l_By.size());
355 EXPECT_EQ(0, l_Bz.size());
356 EXPECT_EQ(0, l_Temperature);
357 ASSERT_EQ(0, l_TimestampList.size());
358
359 // Retrieve the data in INTEGER format.
360 l_Bx.clear(); l_By.clear(); l_Bz.clear(); l_Temperature = 0; l_TimestampList.clear();
361 ASSERT_EQ(true, pTHM1176->SetFormat(kComFormatInteger));
362 ASSERT_EQ(false, pTHM1176->MeasurementsGet(THM1176_NO_MEASUREMENTS+1, l_Bx, l_By, l_Bz, l_Units, l_Temperature, l_TimestampList));
363 {
364 l_ErrorList = pTHM1176->CurrentErrorList();
365 EXPECT_EQ(3, l_ErrorList.size());
366 EXPECT_EQ(-222, l_ErrorList[0].Code);
367 EXPECT_EQ(-222, l_ErrorList[1].Code);
368 EXPECT_EQ(-222, l_ErrorList[2].Code);
369 }
370 EXPECT_EQ(0, l_Bx.size());
371 EXPECT_EQ(0, l_By.size());
372 EXPECT_EQ(0, l_Bz.size());
373 EXPECT_EQ(0, l_Temperature);
374 ASSERT_EQ(0, l_TimestampList.size());
375
376 // Retrieve the data in PACKED,2 format.
377 l_Bx.clear(); l_By.clear(); l_Bz.clear(); l_Temperature = 0; l_TimestampList.clear();
378 ASSERT_EQ(true, pTHM1176->SetFormat(kComFormatPacked2Byte));
379 ASSERT_EQ(false, pTHM1176->MeasurementsGet(THM1176_NO_MEASUREMENTS+1, l_Bx, l_By, l_Bz, l_Units, l_Temperature, l_TimestampList));
380 {
381 l_ErrorList = pTHM1176->CurrentErrorList();
382 EXPECT_EQ(3, l_ErrorList.size());
383 EXPECT_EQ(-222, l_ErrorList[0].Code);
384 EXPECT_EQ(-222, l_ErrorList[1].Code);
385 EXPECT_EQ(-222, l_ErrorList[2].Code);
386 }
387 EXPECT_EQ(0, l_Bx.size());
388 EXPECT_EQ(0, l_By.size());
389 EXPECT_EQ(0, l_Bz.size());
390 EXPECT_EQ(0, l_Temperature);
391 ASSERT_EQ(0, l_TimestampList.size());
392
393 // Retrieve the data in PACKED,1 format.
394 l_Bx.clear(); l_By.clear(); l_Bz.clear(); l_Temperature = 0; l_TimestampList.clear();
395 ASSERT_EQ(true, pTHM1176->SetFormat(kComFormatPacked1Byte));
396 ASSERT_EQ(false, pTHM1176->MeasurementsGet(THM1176_NO_MEASUREMENTS+1, l_Bx, l_By, l_Bz, l_Units, l_Temperature, l_TimestampList));
397 {
398 l_ErrorList = pTHM1176->CurrentErrorList();
399 EXPECT_EQ(3, l_ErrorList.size());
400 EXPECT_EQ(-222, l_ErrorList[0].Code);
401 EXPECT_EQ(-222, l_ErrorList[1].Code);
402 EXPECT_EQ(-222, l_ErrorList[2].Code);
403 }
404 EXPECT_EQ(0, l_Bx.size());
405 EXPECT_EQ(0, l_By.size());
406 EXPECT_EQ(0, l_Bz.size());
407 EXPECT_EQ(0, l_Temperature);
408 ASSERT_EQ(0, l_TimestampList.size());
409 }
410 // Try changing units.
411 {
412 CFluxList l_Bx1, l_By1, l_Bz1;
413
414 l_Bx.clear(); l_By.clear(); l_Bz.clear(); l_Temperature = 0; l_TimestampList.clear();
415 ASSERT_EQ(true, pTHM1176->SetFormat(kComFormatInteger));
416
417 CUnitsList l_AllUnits;
418 ASSERT_EQ(true, pTHM1176->GetAllUnits(l_AllUnits));
419 ASSERT_LT(1, l_AllUnits.size());
420
421 ASSERT_EQ(true, pTHM1176->ParmUnitsSet(l_AllUnits[0]));
422 ASSERT_EQ(true, pTHM1176->MeasurementsGet(THM1176_NO_MEASUREMENTS, l_Bx, l_By, l_Bz, l_Units, l_Temperature, l_TimestampList));
423 EXPECT_EQ(THM1176_NO_MEASUREMENTS, l_Bx.size());
424 EXPECT_EQ(THM1176_NO_MEASUREMENTS, l_By.size());
425 EXPECT_EQ(THM1176_NO_MEASUREMENTS, l_Bz.size());
426
427 ASSERT_EQ(true, pTHM1176->ParmUnitsSet(l_AllUnits[1]));
428 ASSERT_EQ(true, pTHM1176->MeasurementsGet(THM1176_NO_MEASUREMENTS, l_Bx1, l_By1, l_Bz1, l_Units, l_Temperature, l_TimestampList));
429 EXPECT_EQ(THM1176_NO_MEASUREMENTS, l_Bx1.size());
430 EXPECT_EQ(THM1176_NO_MEASUREMENTS, l_By1.size());
431 EXPECT_EQ(THM1176_NO_MEASUREMENTS, l_Bz1.size());
432
433 U32 l_Divisor, l_Divisor1;
434 ASSERT_EQ(true, pTHM1176->GetDivisor(l_AllUnits[0], l_Divisor));
435 ASSERT_EQ(true, pTHM1176->GetDivisor(l_AllUnits[1], l_Divisor1));
436
437 for (auto l_pBx = l_Bx.begin(), l_pBx1 = l_Bx1.begin();
438 l_pBx < l_Bx.end() && l_pBx1 < l_Bx1.end();
439 l_pBx++, l_pBx1++)
440 EXPECT_FLOAT_EQ(*l_pBx * l_Divisor, *l_pBx1 * l_Divisor1);
441 for (auto l_pBy = l_By.begin(), l_pBy1 = l_By1.begin();
442 l_pBy < l_By.end() && l_pBy1 < l_By1.end();
443 l_pBy++, l_pBy1++)
444 EXPECT_FLOAT_EQ(*l_pBy * l_Divisor, *l_pBy1 * l_Divisor1);
445 for (auto l_pBz = l_Bz.begin(), l_pBz1 = l_Bz1.begin();
446 l_pBz < l_Bz.end() && l_pBz1 < l_Bz1.end();
447 l_pBz++, l_pBz1++)
448 EXPECT_FLOAT_EQ(*l_pBz * l_Divisor, *l_pBz1 * l_Divisor1);
449 }
450 // Try with UseCalibration off, in ASCII and Integer format.
451 {
452 CFluxList l_Bx1, l_By1, l_Bz1;
453
454 l_Bx.clear(); l_By.clear(); l_Bz.clear(); l_Temperature = 0; l_TimestampList.clear();
455 ASSERT_EQ(true, pTHM1176->SetFormat(kComFormatAscii));
456 ASSERT_EQ(true, pTHM1176->ParmUseCalibrationSet(false));
457
458 ASSERT_EQ(true, pTHM1176->MeasurementsGet(THM1176_NO_MEASUREMENTS, l_Bx, l_By, l_Bz, l_Units, l_Temperature, l_TimestampList));
459 EXPECT_EQ(THM1176_NO_MEASUREMENTS, l_Bx.size());
460 EXPECT_EQ(THM1176_NO_MEASUREMENTS, l_By.size());
461 EXPECT_EQ(THM1176_NO_MEASUREMENTS, l_Bz.size());
462
463 for (auto l_pBx = l_Bx.begin(); l_pBx < l_Bx.end(); l_pBx++)
464 EXPECT_FLOAT_EQ(*l_pBx, std::round(*l_pBx));
465 for (auto l_pBy = l_By.begin(); l_pBy < l_By.end(); l_pBy++)
466 EXPECT_FLOAT_EQ(*l_pBy, std::round(*l_pBy));
467 for (auto l_pBz = l_Bz.begin(); l_pBz < l_Bz.end(); l_pBz++)
468 EXPECT_FLOAT_EQ(*l_pBz, std::round(*l_pBz));
469
470 ASSERT_EQ(true, pTHM1176->SetFormat(kComFormatInteger));
471 ASSERT_EQ(true, pTHM1176->ParmUseCalibrationSet(false));
472
473 ASSERT_EQ(true, pTHM1176->MeasurementsGet(THM1176_NO_MEASUREMENTS, l_Bx1, l_By1, l_Bz1, l_Units, l_Temperature, l_TimestampList));
474 EXPECT_EQ(THM1176_NO_MEASUREMENTS, l_Bx1.size());
475 EXPECT_EQ(THM1176_NO_MEASUREMENTS, l_By1.size());
476 EXPECT_EQ(THM1176_NO_MEASUREMENTS, l_Bz1.size());
477
478 for (auto l_pBx = l_Bx.begin(), l_pBx1 = l_Bx1.begin();
479 l_pBx < l_Bx.end() && l_pBx1 < l_Bx1.end();
480 l_pBx++, l_pBx1++)
481 EXPECT_FLOAT_EQ(*l_pBx, *l_pBx1);
482 for (auto l_pBy = l_By.begin(), l_pBy1 = l_By1.begin();
483 l_pBy < l_By.end() && l_pBy1 < l_By1.end();
484 l_pBy++, l_pBy1++)
485 EXPECT_FLOAT_EQ(*l_pBy, *l_pBy1);
486 for (auto l_pBz = l_Bz.begin(), l_pBz1 = l_Bz1.begin();
487 l_pBz < l_Bz.end() && l_pBz1 < l_Bz1.end();
488 l_pBz++, l_pBz1++)
489 EXPECT_FLOAT_EQ(*l_pBz, *l_pBz1);
490
491 ASSERT_EQ(true, pTHM1176->ParmUseCalibrationSet(true));
492 }
493 // Continuous measurements.
494 {
495 // Set timed trigger with 10 ms period and 20 measurements.
496 sInputTrigger<sBoundedParm> l_TrigBounds;
497 ASSERT_EQ(true, pTHM1176->ParmTriggerInputGet(l_TrigBounds));
499 l_Trig.Source = kInputTrigSrcTimer;
500 l_Trig.Count = 20;
501 l_Trig.Period_s = 0.01;
502 ASSERT_EQ(true, pTHM1176->ParmTriggerInputSet(l_Trig));
503
504 // Initiate continuously.
505 ASSERT_EQ(true, pTHM1176->Initiate(true));
506
507 // Wait a little, to consistently cause overrun errors
508 // (but this should be the only error!).
509 std::this_thread::sleep_for(std::chrono::seconds(1));
510
511 // Read the data in ASCII format (just to be consistent, not relevant for the test).
512 l_Bx.clear(); l_By.clear(); l_Bz.clear(); l_Temperature = 0; l_TimestampList.clear();
513 ASSERT_EQ(true, pTHM1176->SetFormat(kComFormatAscii));
514 ASSERT_EQ(true, pTHM1176->MeasurementsGet(l_Trig.Count, l_Bx, l_By, l_Bz, l_Units, l_Temperature, l_TimestampList));
515 EXPECT_EQ(l_Trig.Count, l_Bx.size());
516 EXPECT_EQ(l_Trig.Count, l_By.size());
517 EXPECT_EQ(l_Trig.Count, l_Bz.size());
518 EXPECT_LT(0, l_Temperature);
519
520 // Check the timestamp list.
521 ASSERT_EQ(l_Trig.Count, l_TimestampList.size());
522 for (int i = 0; i < l_Trig.Count - 1; i++)
523 {
524 l_TimestampInterval = l_TimestampList[i+1] - l_TimestampList[i];
525 EXPECT_EQ(l_TimestampInterval, l_Trig.Period_s * 1E9);
526 }
527
528 // Wait a second, then do another fetch, this time retrieving the Measurement Conditions.
529 std::this_thread::sleep_for(std::chrono::seconds(1));
530
531 sMeasurementConditions l_MeasurementConditions;
532 ASSERT_EQ(true, pTHM1176->MeasurementsGet(l_Trig.Count, l_Bx, l_By, l_Bz, l_Units, l_Temperature, l_TimestampList, &l_MeasurementConditions));
533 EXPECT_EQ(l_Trig.Count, l_Bx.size());
534 EXPECT_EQ(l_Trig.Count, l_By.size());
535 EXPECT_EQ(l_Trig.Count, l_Bz.size());
536 EXPECT_LT(0, l_Temperature);
537
538 // Check the timestamp list.
539 ASSERT_EQ(l_Trig.Count, l_TimestampList.size());
540 for (int i = 0; i < l_Trig.Count - 1; i++)
541 {
542 l_TimestampInterval = l_TimestampList[i+1] - l_TimestampList[i];
543 EXPECT_EQ(l_TimestampInterval, l_Trig.Period_s * 1E9);
544 }
545
546 // Check the Measurement Conditions.
547 EXPECT_EQ(l_MeasurementConditions.AveragingParms.NoPoints, THM1176_AVG_COUNT);
548 EXPECT_EQ(l_MeasurementConditions.TriggerParms.Source, l_Trig.Source);
549 EXPECT_EQ(l_MeasurementConditions.TriggerParms.Count, l_Trig.Count);
550 EXPECT_EQ(l_MeasurementConditions.TriggerParms.Period_s, l_Trig.Period_s);
551 EXPECT_EQ(l_MeasurementConditions.UseCalibration, true);
552 EXPECT_LT(0, l_MeasurementConditions.Range);
553
554 // Test the GetEstimatedPeriod() method.
555 F64 l_Period;
556 ASSERT_EQ(true, l_TimestampList.GetEstimatedPeriod(l_Period));
557 EXPECT_DOUBLE_EQ(l_Period, l_Trig.Period_s * 1E9);
558
559 // Check to make sure we got a Data Overrun error.
560 l_ErrorList = pTHM1176->CurrentErrorList();
561 EXPECT_EQ(1, l_ErrorList.size());
562 EXPECT_EQ(204, l_ErrorList[0].Code);
563 }
564 // Bus Triggered measurements.
565 {
566 // Reset to have a clean slate.
567 pTHM1176->Reset();
568
569 // Set bus trigger.
571 l_Trig.Source = kInputTrigSrcBus;
573 l_Trig.Period_s = 0;
574 ASSERT_EQ(true, pTHM1176->ParmTriggerInputSet(l_Trig));
575
576 // Initiate.
577 ASSERT_EQ(true, pTHM1176->Initiate(false));
578
579 // Trigger at 1-second intervals.
580 std::vector<std::chrono::time_point<std::chrono::high_resolution_clock>> l_TriggerTimes;
581 for (int i = 0; i < THM1176_NO_MEASUREMENTS; i++)
582 {
583 ASSERT_EQ(true, pTHM1176->SendBusTrigger());
584
585 // Save the current time.
586 l_TriggerTimes.push_back (std::chrono::high_resolution_clock::now());
587
588 // Print it out for debugging.
589 std::time_t l_Now = std::chrono::system_clock::to_time_t(std::chrono::system_clock::now());
590 char l_DateTimeString[32];
591 std::strftime(l_DateTimeString, 31, "%FT%T", std::localtime(&l_Now));
592 std::cout << "Send trigger " << i << std::string(l_DateTimeString) << std::endl;
593
594 // NOTE: We seem to be getting spurious 206 (Timer Overrun) errors here – firmware bug?
595 // To catch it, uncomment the assertion, below.
596 U16 l_Status;
597 ASSERT_EQ(true, pTHM1176->StatusGet(sStatusRegister(kStatusByte, kStatusEvent), l_Status));
598 // ASSERT_EQ(0, l_Status);
599 pTHM1176->ClearErrorList();
600
601 std::this_thread::sleep_for(std::chrono::seconds(1));
602 }
603
604 // Read the data in ASCII format (just to be consistent, not relevant for the test).
605 l_Bx.clear(); l_By.clear(); l_Bz.clear(); l_Temperature = 0; l_TimestampList.clear();
606 ASSERT_EQ(true, pTHM1176->SetFormat(kComFormatAscii));
607 ASSERT_EQ(true, pTHM1176->MeasurementsGet(THM1176_NO_MEASUREMENTS, l_Bx, l_By, l_Bz, l_Units, l_Temperature, l_TimestampList));
608 EXPECT_EQ(THM1176_NO_MEASUREMENTS, l_Bx.size());
609 EXPECT_EQ(THM1176_NO_MEASUREMENTS, l_By.size());
610 EXPECT_EQ(THM1176_NO_MEASUREMENTS, l_Bz.size());
611 EXPECT_LT(0, l_Temperature);
612
613 // Pay particular attention to the timestamps.
614 ASSERT_EQ(THM1176_NO_MEASUREMENTS, l_TimestampList.size());
615 for (int i = 0; i < THM1176_NO_MEASUREMENTS - 1; i++)
616 {
617 l_TimestampInterval = l_TimestampList[i+1] - l_TimestampList[i];
618 F64 l_ExpectedTimestampInterval = std::chrono::duration_cast<std::chrono::nanoseconds>(l_TriggerTimes[i+1] - l_TriggerTimes[i]).count();
619 EXPECT_NEAR(static_cast<F64>(l_TimestampInterval), l_ExpectedTimestampInterval, 1E7);
620 }
621
622 // Convert the timestamps to absolute timestamps, and print them out.
623 for (int i = 0; i < THM1176_NO_MEASUREMENTS; i++)
624 {
625 CAbsoluteTimestamp l_AbsolutTimestamp;
626 ASSERT_EQ(true, pTHM1176->ConvertTimestamp(l_TimestampList[i], l_AbsolutTimestamp));
627 std::cout << "Timestamp: " << l_AbsolutTimestamp << std::endl;
628 }
629
630 // We expect no errors.
631 l_ErrorList = pTHM1176->CurrentErrorList();
632 EXPECT_EQ(0, l_ErrorList.size());
633 }
634}
635
637TEST_F(CTHM1176MeasuresTest, MeasurementsGetArbitrary)
638{
639 CFluxList l_Bx, l_By, l_Bz;
640 eUnits l_Units;
641 U16 l_Temperature;
642 CTimestampList l_TimestampList;
643 U64 l_TimestampInterval;
644 CErrorList l_ErrorList;
645
646 // NoMeasurements = 0, retrieve all.
647 {
648 sArbitraryMeasurements l_Select = { true, true, true, true, true, 0 };
649
650 // ASCII format.
651 l_Bx.clear(); l_By.clear(); l_Bz.clear(); l_Temperature = 0; l_TimestampList.clear();
652 ASSERT_EQ(true, pTHM1176->SetFormat(kComFormatAscii));
653 ASSERT_EQ(false, pTHM1176->MeasurementsGet(l_Select, l_Bx, l_By, l_Bz, l_Units, l_Temperature, l_TimestampList));
654 {
655 l_ErrorList = pTHM1176->CurrentErrorList();
656 EXPECT_EQ(3, l_ErrorList.size());
657 EXPECT_EQ(-222, l_ErrorList[0].Code);
658 EXPECT_EQ(-222, l_ErrorList[1].Code);
659 EXPECT_EQ(-222, l_ErrorList[2].Code);
660 }
661 EXPECT_EQ(0, l_Bx.size());
662 EXPECT_EQ(0, l_By.size());
663 EXPECT_EQ(0, l_Bz.size());
664 EXPECT_EQ(0, l_Temperature);
665 ASSERT_EQ(0, l_TimestampList.size());
666
667 // Retrieve the data in INTEGER format.
668 l_Bx.clear(); l_By.clear(); l_Bz.clear(); l_Temperature = 0; l_TimestampList.clear();
669 ASSERT_EQ(true, pTHM1176->SetFormat(kComFormatInteger));
670 ASSERT_EQ(false, pTHM1176->MeasurementsGet(l_Select, l_Bx, l_By, l_Bz, l_Units, l_Temperature, l_TimestampList));
671 {
672 l_ErrorList = pTHM1176->CurrentErrorList();
673 EXPECT_EQ(3, l_ErrorList.size());
674 EXPECT_EQ(-222, l_ErrorList[0].Code);
675 EXPECT_EQ(-222, l_ErrorList[1].Code);
676 EXPECT_EQ(-222, l_ErrorList[2].Code);
677 }
678 EXPECT_EQ(0, l_Bx.size());
679 EXPECT_EQ(0, l_By.size());
680 EXPECT_EQ(0, l_Bz.size());
681 EXPECT_EQ(0, l_Temperature);
682 ASSERT_EQ(0, l_TimestampList.size());
683
684 // Retrieve the data in PACKED,2 format.
685 l_Bx.clear(); l_By.clear(); l_Bz.clear(); l_Temperature = 0; l_TimestampList.clear();
686 ASSERT_EQ(true, pTHM1176->SetFormat(kComFormatPacked2Byte));
687 ASSERT_EQ(false, pTHM1176->MeasurementsGet(l_Select, l_Bx, l_By, l_Bz, l_Units, l_Temperature, l_TimestampList));
688 {
689 l_ErrorList = pTHM1176->CurrentErrorList();
690 EXPECT_EQ(3, l_ErrorList.size());
691 EXPECT_EQ(-222, l_ErrorList[0].Code);
692 EXPECT_EQ(-222, l_ErrorList[1].Code);
693 EXPECT_EQ(-222, l_ErrorList[2].Code);
694 }
695 EXPECT_EQ(0, l_Bx.size());
696 EXPECT_EQ(0, l_By.size());
697 EXPECT_EQ(0, l_Bz.size());
698 EXPECT_EQ(0, l_Temperature);
699 ASSERT_EQ(0, l_TimestampList.size());
700
701 // Retrieve the data in PACKED,1 format.
702 l_Bx.clear(); l_By.clear(); l_Bz.clear(); l_Temperature = 0; l_TimestampList.clear();
703 ASSERT_EQ(true, pTHM1176->SetFormat(kComFormatPacked1Byte));
704 ASSERT_EQ(false, pTHM1176->MeasurementsGet(l_Select, l_Bx, l_By, l_Bz, l_Units, l_Temperature, l_TimestampList));
705 {
706 l_ErrorList = pTHM1176->CurrentErrorList();
707 EXPECT_EQ(3, l_ErrorList.size());
708 EXPECT_EQ(-222, l_ErrorList[0].Code);
709 EXPECT_EQ(-222, l_ErrorList[1].Code);
710 EXPECT_EQ(-222, l_ErrorList[2].Code);
711 }
712 EXPECT_EQ(0, l_Bx.size());
713 EXPECT_EQ(0, l_By.size());
714 EXPECT_EQ(0, l_Bz.size());
715 EXPECT_EQ(0, l_Temperature);
716 ASSERT_EQ(0, l_TimestampList.size());
717 }
718
719 // NoMeasurements = THM1176_NO_MEASUREMENTS, retrieve first set.
720 {
721 sArbitraryMeasurements l_Select = { true, false, true, false, true, static_cast<U32>(THM1176_NO_MEASUREMENTS) };
722
723 // ASCII format.
724 l_Bx.clear(); l_By.clear(); l_Bz.clear(); l_Temperature = 0; l_TimestampList.clear();
725 ASSERT_EQ(true, pTHM1176->SetFormat(kComFormatAscii));
726 ASSERT_EQ(true, pTHM1176->MeasurementsGet(l_Select, l_Bx, l_By, l_Bz, l_Units, l_Temperature, l_TimestampList));
727 EXPECT_EQ(THM1176_NO_MEASUREMENTS, l_Bx.size());
728 EXPECT_EQ(0, l_By.size());
729 EXPECT_EQ(THM1176_NO_MEASUREMENTS, l_Bz.size());
730 EXPECT_EQ(0, l_Temperature);
731 ASSERT_EQ(THM1176_NO_MEASUREMENTS, l_TimestampList.size());
732 for (int i = 0; i < THM1176_NO_MEASUREMENTS - 1; i++)
733 {
734 l_TimestampInterval = l_TimestampList[i+1] - l_TimestampList[i];
735 EXPECT_EQ(l_TimestampInterval, THM1176_TIME_PER_MEASUREMENT);
736 }
737 l_ErrorList = pTHM1176->CurrentErrorList();
738 ASSERT_EQ(1, l_ErrorList.size());
739 EXPECT_EQ(THM1176_NO_ANGLE_CORRECTION_CODE, l_ErrorList[0].Code);
740 pTHM1176->ClearErrorList();
741
742 // Retrieve the data in INTEGER format.
743 l_Bx.clear(); l_By.clear(); l_Bz.clear(); l_Temperature = 0; l_TimestampList.clear();
744 ASSERT_EQ(true, pTHM1176->SetFormat(kComFormatInteger));
745 ASSERT_EQ(true, pTHM1176->MeasurementsGet(l_Select, l_Bx, l_By, l_Bz, l_Units, l_Temperature, l_TimestampList));
746 EXPECT_EQ(THM1176_NO_MEASUREMENTS, l_Bx.size());
747 EXPECT_EQ(0, l_By.size());
748 EXPECT_EQ(THM1176_NO_MEASUREMENTS, l_Bz.size());
749 EXPECT_EQ(0, l_Temperature);
750 ASSERT_EQ(THM1176_NO_MEASUREMENTS, l_TimestampList.size());
751 for (int i = 0; i < THM1176_NO_MEASUREMENTS - 1; i++)
752 {
753 l_TimestampInterval = l_TimestampList[i+1] - l_TimestampList[i];
754 EXPECT_EQ(l_TimestampInterval, THM1176_TIME_PER_MEASUREMENT);
755 }
756 l_ErrorList = pTHM1176->CurrentErrorList();
757 ASSERT_EQ(1, l_ErrorList.size());
758 EXPECT_EQ(THM1176_NO_ANGLE_CORRECTION_CODE, l_ErrorList[0].Code);
759 pTHM1176->ClearErrorList();
760
761 // Retrieve the data in PACKED,2 format.
762 l_Bx.clear(); l_By.clear(); l_Bz.clear(); l_Temperature = 0; l_TimestampList.clear();
763 ASSERT_EQ(true, pTHM1176->SetFormat(kComFormatPacked2Byte));
764 ASSERT_EQ(true, pTHM1176->MeasurementsGet(l_Select, l_Bx, l_By, l_Bz, l_Units, l_Temperature, l_TimestampList));
765 EXPECT_EQ(THM1176_NO_MEASUREMENTS, l_Bx.size());
766 EXPECT_EQ(0, l_By.size());
767 EXPECT_EQ(THM1176_NO_MEASUREMENTS, l_Bz.size());
768 EXPECT_EQ(0, l_Temperature);
769 ASSERT_EQ(THM1176_NO_MEASUREMENTS, l_TimestampList.size());
770 for (int i = 0; i < THM1176_NO_MEASUREMENTS - 1; i++)
771 {
772 l_TimestampInterval = l_TimestampList[i+1] - l_TimestampList[i];
773 EXPECT_EQ(l_TimestampInterval, THM1176_TIME_PER_MEASUREMENT);
774 }
775 l_ErrorList = pTHM1176->CurrentErrorList();
776 ASSERT_EQ(1, l_ErrorList.size());
777 EXPECT_EQ(THM1176_NO_ANGLE_CORRECTION_CODE, l_ErrorList[0].Code);
778 pTHM1176->ClearErrorList();
779
780 // Retrieve the data in PACKED,1 format.
781 l_Bx.clear(); l_By.clear(); l_Bz.clear(); l_Temperature = 0; l_TimestampList.clear();
782 ASSERT_EQ(true, pTHM1176->SetFormat(kComFormatPacked1Byte));
783 ASSERT_EQ(true, pTHM1176->MeasurementsGet(l_Select, l_Bx, l_By, l_Bz, l_Units, l_Temperature, l_TimestampList));
784 EXPECT_EQ(THM1176_NO_MEASUREMENTS, l_Bx.size());
785 EXPECT_EQ(0, l_By.size());
786 EXPECT_EQ(THM1176_NO_MEASUREMENTS, l_Bz.size());
787 EXPECT_EQ(0, l_Temperature);
788 ASSERT_EQ(THM1176_NO_MEASUREMENTS, l_TimestampList.size());
789 for (int i = 0; i < THM1176_NO_MEASUREMENTS - 1; i++)
790 {
791 l_TimestampInterval = l_TimestampList[i+1] - l_TimestampList[i];
792 EXPECT_EQ(l_TimestampInterval, THM1176_TIME_PER_MEASUREMENT);
793 }
794 l_ErrorList = pTHM1176->CurrentErrorList();
795 ASSERT_EQ(1, l_ErrorList.size());
796 EXPECT_EQ(THM1176_NO_ANGLE_CORRECTION_CODE, l_ErrorList[0].Code);
797 pTHM1176->ClearErrorList();
798 }
799
800 // NoMeasurements = THM1176_NO_MEASUREMENTS-1, retrieve second set.
801 {
802 sArbitraryMeasurements l_Select = { false, true, false, true, false, THM1176_NO_MEASUREMENTS-1 };
803
804 // ASCII format.
805 l_Bx.clear(); l_By.clear(); l_Bz.clear(); l_Temperature = 0; l_TimestampList.clear();
806 ASSERT_EQ(true, pTHM1176->SetFormat(kComFormatAscii));
807 ASSERT_EQ(true, pTHM1176->MeasurementsGet(l_Select, l_Bx, l_By, l_Bz, l_Units, l_Temperature, l_TimestampList));
808 EXPECT_EQ(0, l_Bx.size());
809 EXPECT_EQ(THM1176_NO_MEASUREMENTS-1, l_By.size());
810 EXPECT_EQ(0, l_Bz.size());
811 EXPECT_LT(0, l_Temperature);
812 ASSERT_EQ(0, l_TimestampList.size());
813 l_ErrorList = pTHM1176->CurrentErrorList();
814 ASSERT_EQ(1, l_ErrorList.size());
815 EXPECT_EQ(THM1176_NO_ANGLE_CORRECTION_CODE, l_ErrorList[0].Code);
816 pTHM1176->ClearErrorList();
817
818 // Retrieve the data in INTEGER format.
819 l_Bx.clear(); l_By.clear(); l_Bz.clear(); l_Temperature = 0; l_TimestampList.clear();
820 ASSERT_EQ(true, pTHM1176->SetFormat(kComFormatInteger));
821 ASSERT_EQ(true, pTHM1176->MeasurementsGet(l_Select, l_Bx, l_By, l_Bz, l_Units, l_Temperature, l_TimestampList));
822 EXPECT_EQ(0, l_Bx.size());
823 EXPECT_EQ(THM1176_NO_MEASUREMENTS-1, l_By.size());
824 EXPECT_EQ(0, l_Bz.size());
825 EXPECT_LT(0, l_Temperature);
826 ASSERT_EQ(0, l_TimestampList.size());
827 l_ErrorList = pTHM1176->CurrentErrorList();
828 ASSERT_EQ(1, l_ErrorList.size());
829 EXPECT_EQ(THM1176_NO_ANGLE_CORRECTION_CODE, l_ErrorList[0].Code);
830 pTHM1176->ClearErrorList();
831
832 // Retrieve the data in PACKED,2 format.
833 l_Bx.clear(); l_By.clear(); l_Bz.clear(); l_Temperature = 0; l_TimestampList.clear();
834 ASSERT_EQ(true, pTHM1176->SetFormat(kComFormatPacked2Byte));
835 ASSERT_EQ(true, pTHM1176->MeasurementsGet(l_Select, l_Bx, l_By, l_Bz, l_Units, l_Temperature, l_TimestampList));
836 EXPECT_EQ(0, l_Bx.size());
837 EXPECT_EQ(THM1176_NO_MEASUREMENTS-1, l_By.size());
838 EXPECT_EQ(0, l_Bz.size());
839 EXPECT_LT(0, l_Temperature);
840 ASSERT_EQ(0, l_TimestampList.size());
841 l_ErrorList = pTHM1176->CurrentErrorList();
842 ASSERT_EQ(1, l_ErrorList.size());
843 EXPECT_EQ(THM1176_NO_ANGLE_CORRECTION_CODE, l_ErrorList[0].Code);
844 pTHM1176->ClearErrorList();
845
846 // Retrieve the data in PACKED,1 format.
847 l_Bx.clear(); l_By.clear(); l_Bz.clear(); l_Temperature = 0; l_TimestampList.clear();
848 ASSERT_EQ(true, pTHM1176->SetFormat(kComFormatPacked1Byte));
849 ASSERT_EQ(true, pTHM1176->MeasurementsGet(l_Select, l_Bx, l_By, l_Bz, l_Units, l_Temperature, l_TimestampList));
850 EXPECT_EQ(0, l_Bx.size());
851 EXPECT_EQ(THM1176_NO_MEASUREMENTS-1, l_By.size());
852 EXPECT_EQ(0, l_Bz.size());
853 EXPECT_LT(0, l_Temperature);
854 ASSERT_EQ(0, l_TimestampList.size());
855 l_ErrorList = pTHM1176->CurrentErrorList();
856 ASSERT_EQ(1, l_ErrorList.size());
857 EXPECT_EQ(THM1176_NO_ANGLE_CORRECTION_CODE, l_ErrorList[0].Code);
858 pTHM1176->ClearErrorList();
859 }
860 // NoMeasurements = THM1176_NO_MEASUREMENTS+1, retrieve all.
861 {
862 sArbitraryMeasurements l_Select = { true, true, true, true, true, THM1176_NO_MEASUREMENTS+1 };
863
864 // ASCII format.
865 l_Bx.clear(); l_By.clear(); l_Bz.clear(); l_Temperature = 0; l_TimestampList.clear();
866 ASSERT_EQ(true, pTHM1176->SetFormat(kComFormatAscii));
867 ASSERT_EQ(false, pTHM1176->MeasurementsGet(l_Select, l_Bx, l_By, l_Bz, l_Units, l_Temperature, l_TimestampList));
868 {
869 l_ErrorList = pTHM1176->CurrentErrorList();
870 EXPECT_EQ(3, l_ErrorList.size());
871 EXPECT_EQ(-222, l_ErrorList[0].Code);
872 EXPECT_EQ(-222, l_ErrorList[1].Code);
873 EXPECT_EQ(-222, l_ErrorList[2].Code);
874 }
875 EXPECT_EQ(0, l_Bx.size());
876 EXPECT_EQ(0, l_By.size());
877 EXPECT_EQ(0, l_Bz.size());
878 EXPECT_EQ(0, l_Temperature);
879 ASSERT_EQ(0, l_TimestampList.size());
880
881 // Retrieve the data in INTEGER format.
882 l_Bx.clear(); l_By.clear(); l_Bz.clear(); l_Temperature = 0; l_TimestampList.clear();
883 ASSERT_EQ(true, pTHM1176->SetFormat(kComFormatInteger));
884 ASSERT_EQ(false, pTHM1176->MeasurementsGet(l_Select, l_Bx, l_By, l_Bz, l_Units, l_Temperature, l_TimestampList));
885 {
886 l_ErrorList = pTHM1176->CurrentErrorList();
887 EXPECT_EQ(3, l_ErrorList.size());
888 EXPECT_EQ(-222, l_ErrorList[0].Code);
889 EXPECT_EQ(-222, l_ErrorList[1].Code);
890 EXPECT_EQ(-222, l_ErrorList[2].Code);
891 }
892 EXPECT_EQ(0, l_Bx.size());
893 EXPECT_EQ(0, l_By.size());
894 EXPECT_EQ(0, l_Bz.size());
895 EXPECT_EQ(0, l_Temperature);
896 ASSERT_EQ(0, l_TimestampList.size());
897
898 // Retrieve the data in PACKED,2 format.
899 l_Bx.clear(); l_By.clear(); l_Bz.clear(); l_Temperature = 0; l_TimestampList.clear();
900 ASSERT_EQ(true, pTHM1176->SetFormat(kComFormatPacked2Byte));
901 ASSERT_EQ(false, pTHM1176->MeasurementsGet(l_Select, l_Bx, l_By, l_Bz, l_Units, l_Temperature, l_TimestampList));
902 {
903 l_ErrorList = pTHM1176->CurrentErrorList();
904 EXPECT_EQ(3, l_ErrorList.size());
905 EXPECT_EQ(-222, l_ErrorList[0].Code);
906 EXPECT_EQ(-222, l_ErrorList[1].Code);
907 EXPECT_EQ(-222, l_ErrorList[2].Code);
908 }
909 EXPECT_EQ(0, l_Bx.size());
910 EXPECT_EQ(0, l_By.size());
911 EXPECT_EQ(0, l_Bz.size());
912 EXPECT_EQ(0, l_Temperature);
913 ASSERT_EQ(0, l_TimestampList.size());
914
915 // Retrieve the data in PACKED,1 format.
916 l_Bx.clear(); l_By.clear(); l_Bz.clear(); l_Temperature = 0; l_TimestampList.clear();
917 ASSERT_EQ(true, pTHM1176->SetFormat(kComFormatPacked1Byte));
918 ASSERT_EQ(false, pTHM1176->MeasurementsGet(l_Select, l_Bx, l_By, l_Bz, l_Units, l_Temperature, l_TimestampList));
919 {
920 l_ErrorList = pTHM1176->CurrentErrorList();
921 EXPECT_EQ(3, l_ErrorList.size());
922 EXPECT_EQ(-222, l_ErrorList[0].Code);
923 EXPECT_EQ(-222, l_ErrorList[1].Code);
924 EXPECT_EQ(-222, l_ErrorList[2].Code);
925 }
926 EXPECT_EQ(0, l_Bx.size());
927 EXPECT_EQ(0, l_By.size());
928 EXPECT_EQ(0, l_Bz.size());
929 EXPECT_EQ(0, l_Temperature);
930 ASSERT_EQ(0, l_TimestampList.size());
931 }
932 // Try changing units.
933 {
934 sArbitraryMeasurements l_Select = { true, true, true, false, false, static_cast<U32>(THM1176_NO_MEASUREMENTS) };
935 CFluxList l_Bx1, l_By1, l_Bz1;
936
937 l_Bx.clear(); l_By.clear(); l_Bz.clear(); l_Temperature = 0; l_TimestampList.clear();
938 ASSERT_EQ(true, pTHM1176->SetFormat(kComFormatInteger));
939
940 CUnitsList l_AllUnits;
941 ASSERT_EQ(true, pTHM1176->GetAllUnits(l_AllUnits));
942 ASSERT_LT(1, l_AllUnits.size());
943
944 ASSERT_EQ(true, pTHM1176->ParmUnitsSet(l_AllUnits[0]));
945 ASSERT_EQ(true, pTHM1176->MeasurementsGet(l_Select, l_Bx, l_By, l_Bz, l_Units, l_Temperature, l_TimestampList));
946 EXPECT_EQ(THM1176_NO_MEASUREMENTS, l_Bx.size());
947 EXPECT_EQ(THM1176_NO_MEASUREMENTS, l_By.size());
948 EXPECT_EQ(THM1176_NO_MEASUREMENTS, l_Bz.size());
949
950 ASSERT_EQ(true, pTHM1176->ParmUnitsSet(l_AllUnits[1]));
951 ASSERT_EQ(true, pTHM1176->MeasurementsGet(l_Select, l_Bx1, l_By1, l_Bz1, l_Units, l_Temperature, l_TimestampList));
952 EXPECT_EQ(THM1176_NO_MEASUREMENTS, l_Bx1.size());
953 EXPECT_EQ(THM1176_NO_MEASUREMENTS, l_By1.size());
954 EXPECT_EQ(THM1176_NO_MEASUREMENTS, l_Bz1.size());
955
956 U32 l_Divisor, l_Divisor1;
957 ASSERT_EQ(true, pTHM1176->GetDivisor(l_AllUnits[0], l_Divisor));
958 ASSERT_EQ(true, pTHM1176->GetDivisor(l_AllUnits[1], l_Divisor1));
959
960 for (auto l_pBx = l_Bx.begin(), l_pBx1 = l_Bx1.begin();
961 l_pBx < l_Bx.end() && l_pBx1 < l_Bx1.end();
962 l_pBx++, l_pBx1++)
963 EXPECT_FLOAT_EQ(*l_pBx * l_Divisor, *l_pBx1 * l_Divisor1);
964 for (auto l_pBy = l_By.begin(), l_pBy1 = l_By1.begin();
965 l_pBy < l_By.end() && l_pBy1 < l_By1.end();
966 l_pBy++, l_pBy1++)
967 EXPECT_FLOAT_EQ(*l_pBy * l_Divisor, *l_pBy1 * l_Divisor1);
968 for (auto l_pBz = l_Bz.begin(), l_pBz1 = l_Bz1.begin();
969 l_pBz < l_Bz.end() && l_pBz1 < l_Bz1.end();
970 l_pBz++, l_pBz1++)
971 EXPECT_FLOAT_EQ(*l_pBz * l_Divisor, *l_pBz1 * l_Divisor1);
972 }
973}
974
976TEST_F(CTHM1176MeasuresTest, ApplyRotationMatrix)
977{
978 // Note 1: This test is most meaningful with a magnetic field.
979 // Note 2: Initial testing compared results manually with LabVIEW THM1176 software (v 4.1).
980 CFluxList l_Bx, l_By, l_Bz;
981 eUnits l_Units;
982 U16 l_Temperature = 0;
983 CTimestampList l_TimestampList;
984 CErrorList l_ErrorList;
985
986 // Fetch Bx, By, Bz separately – cannot apply angle correction.
987 CFluxList l_BxRaw, l_ByRaw, l_BzRaw;
988 sArbitraryMeasurements l_Select;
989
990 l_Select = { true, false, false, false, false, 1 };
991 ASSERT_EQ(true, pTHM1176->MeasurementsGet(l_Select, l_BxRaw, l_By, l_Bz, l_Units, l_Temperature, l_TimestampList));
992 EXPECT_EQ(1, l_BxRaw.size());
993 EXPECT_EQ(0, l_By.size());
994 EXPECT_EQ(0, l_Bz.size());
995 EXPECT_EQ(0, l_Temperature);
996 ASSERT_EQ(0, l_TimestampList.size());
997 l_ErrorList = pTHM1176->CurrentErrorList();
998 ASSERT_EQ(1, l_ErrorList.size());
999 EXPECT_EQ(THM1176_NO_ANGLE_CORRECTION_CODE, l_ErrorList[0].Code);
1000 pTHM1176->ClearErrorList();
1001
1002 l_Select = { false, true, false, false, false, 1 };
1003 ASSERT_EQ(true, pTHM1176->MeasurementsGet(l_Select, l_Bx, l_ByRaw, l_Bz, l_Units, l_Temperature, l_TimestampList));
1004 EXPECT_EQ(0, l_Bx.size());
1005 EXPECT_EQ(1, l_ByRaw.size());
1006 EXPECT_EQ(0, l_Bz.size());
1007 EXPECT_EQ(0, l_Temperature);
1008 ASSERT_EQ(0, l_TimestampList.size());
1009 l_ErrorList = pTHM1176->CurrentErrorList();
1010 ASSERT_EQ(1, l_ErrorList.size());
1011 EXPECT_EQ(THM1176_NO_ANGLE_CORRECTION_CODE, l_ErrorList[0].Code);
1012 pTHM1176->ClearErrorList();
1013
1014 l_Select = { false, false, true, false, false, 1 };
1015 ASSERT_EQ(true, pTHM1176->MeasurementsGet(l_Select, l_Bx, l_By, l_BzRaw, l_Units, l_Temperature, l_TimestampList));
1016 EXPECT_EQ(0, l_Bx.size());
1017 EXPECT_EQ(0, l_By.size());
1018 EXPECT_EQ(1, l_BzRaw.size());
1019 EXPECT_EQ(0, l_Temperature);
1020 ASSERT_EQ(0, l_TimestampList.size());
1021 l_ErrorList = pTHM1176->CurrentErrorList();
1022 ASSERT_EQ(1, l_ErrorList.size());
1023 EXPECT_EQ(THM1176_NO_ANGLE_CORRECTION_CODE, l_ErrorList[0].Code);
1024 pTHM1176->ClearErrorList();
1025
1026 // Apply the rotation matrix.
1027 Matrix3f l_Matrix;
1028 ASSERT_EQ(true, pTHM1176->GetRotationMatrix(l_Matrix));
1029 Vector3f l_B;
1030 l_B << l_BxRaw[0], l_ByRaw[0], l_BzRaw[0];
1031 l_B = l_Matrix * l_B;
1032
1033 // Fetch l_Bx, By, Bz all together – angle correction applied.
1034 l_Select = { true, true, true, false, false, 1 };
1035 ASSERT_EQ(true, pTHM1176->MeasurementsGet(1, l_Bx, l_By, l_Bz, l_Units, l_Temperature, l_TimestampList));
1036 EXPECT_EQ(1, l_Bx.size());
1037 EXPECT_EQ(1, l_By.size());
1038 EXPECT_EQ(1, l_Bz.size());
1039 EXPECT_LT(0, l_Temperature);
1040 ASSERT_EQ(1, l_TimestampList.size());
1041 l_ErrorList = pTHM1176->CurrentErrorList();
1042 ASSERT_EQ(0, l_ErrorList.size());
1043
1044 // Check the results.
1045 EXPECT_FLOAT_EQ(l_B(0), l_Bx[0]);
1046 EXPECT_FLOAT_EQ(l_B(1), l_By[0]);
1047 EXPECT_FLOAT_EQ(l_B(2), l_Bz[0]);
1048
1049 // Make sure that we get a warning when Use Calibration is off.
1050 ASSERT_EQ(true, pTHM1176->ParmUseCalibrationSet(false));
1051 // NOTE: We seem to be getting spurious 206 (Timer Overrun) errors here – firmware bug?
1052 // To catch it, uncomment the assertion, below.
1053 U16 l_Status = pTHM1176->Initiate();
1054 // ASSERT_EQ(true, l_Status);
1055
1056 l_Select = { true, true, true, false, false, 1 };
1057 ASSERT_EQ(true, pTHM1176->MeasurementsGet(1, l_Bx, l_By, l_Bz, l_Units, l_Temperature, l_TimestampList));
1058 EXPECT_EQ(1, l_Bx.size());
1059 EXPECT_EQ(1, l_By.size());
1060 EXPECT_EQ(1, l_Bz.size());
1061 EXPECT_LT(0, l_Temperature);
1062 ASSERT_EQ(1, l_TimestampList.size());
1063 l_ErrorList = pTHM1176->CurrentErrorList();
1064 ASSERT_EQ(1, l_ErrorList.size());
1065 EXPECT_EQ(THM1176_NO_ANGLE_CORRECTION_CODE, l_ErrorList[0].Code);
1066 pTHM1176->ClearErrorList();
1067}
1068
static const I32 THM1176_NO_MEASUREMENTS(3)
static const F64 THM1176_IMMEDIATE_TIME_PER_MEAS(4.4532792007542600E+04)
TEST_F(CTHM1176MeasuresTest, SetFormat)
static const U64 THM1176_TIME_PER_MEASUREMENT(static_cast< U64 >(THM1176_IMMEDIATE_TIME_PER_MEAS+THM1176_AVG_COUNT *THM1176_IMMEDIATE_TIME_PER_ACQ+0.5))
static const F64 THM1176_IMMEDIATE_TIME_PER_ACQ(1.0281823091218700E+05)
static const U32 THM1176_AVG_COUNT(100)
unsigned long long U64
64-bit unsigned integer.
Definition OSDefines.h:32
int I32
32-bit signed integer.
Definition OSDefines.h:27
unsigned int U32
32-bit unsigned integer.
Definition OSDefines.h:31
double F64
64-bit floating-point number.
Definition OSDefines.h:34
unsigned short U16
16-bit unsigned integer.
Definition OSDefines.h:30
static const F64 THM1176_IMMEDIATE_TIME_PER_MEAS(4.4532792007542600E+04)
static const F64 THM1176_IMMEDIATE_TIME_PER_ACQ(1.0281823091218700E+05)
Utility functions used to test THM1176 API.
bool ConnectToTHM1176(THM1176_TEST_RESOURCE_MANAGER_CLASS *&rpResourceManager, CTHM1176Instrument< THM1176_TEST_INSTRUMENT_CLASS, THM1176_TEST_RESOURCE_MANAGER_CLASS > *&rpTHM1176)
Connect to a THM1176.
Test THM1176 API: MeasurementsGet, SetFormat.
static THM1176_TEST_RESOURCE_MANAGER_CLASS * pResourceManager
static CTHM1176Instrument< THM1176_TEST_INSTRUMENT_CLASS, THM1176_TEST_RESOURCE_MANAGER_CLASS > * pTHM1176
std::vector< MTL_INSTRUMENT_BUFFER_TYPE >::iterator end()
Return an iterator to the end of the buffer.
std::vector< MTL_INSTRUMENT_BUFFER_TYPE >::iterator begin()
Return an iterator to the beginning of the buffer.
THM1176 instrument class.
Definition THM1176.h:98
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.
@ kStatusEvent
Event register.
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.
@ 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.
static const I32 THM1176_NO_ANGLE_CORRECTION_CODE
Warning that angle correction was not applied.
Definition THM1176.h:82
Specify the measurement data to be returned.
ParmType< U16 > NoPoints
Number of points in block average.
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.
bool Auto
Auto-ranging enabled.
ParmType< tFlux > Range
Measurement range, if auto-ranging is not enabled.
Complete identification of a SCPI status register.