1// Copyright [2017] Zurich Instruments AG
2
3#include <stdio.h>
4#include <stdlib.h>
5
6#include "ziAPI.h"
7#include "ziUtils.hpp"
8
9
10void decodeChunk(ZIModuleEventPtr ev);
11
12int main()
13{
14 // Define the device address of the device to run the example on.
15 const char* deviceAddress = ziUtilsGetEnv("LABONE_DEVICE", "dev2123");
16 printf("ENV LABONE_DEVICE=%s\n", deviceAddress);
17
18 // Address of the data server.
19 const char* dataServer = ziUtilsGetEnv("LABONE_SERVER", "localhost");
20
21 // Port of the data server.
22 const uint16_t port = 8004;
23
24 // Over which interface the connection to the
25 // device should be established. Can be either
26 // - 1: "1GbE" - Ethernet
27 // - 2: "USB" - USB
28 // - 3: "PCIe" - PCIe
29 const char* deviceInterface = "1GbE";
30
31 ZIConnection conn = nullptr;
32
33 if (isError(ziAPIInit(&conn)))
34 {
35 return 1;
36 }
37
38 ziAPISetDebugLevel(0);
39 ziAPIWriteDebugLog(0, "Logging enabled.");
40
41 try
42 {
43 checkError(
44 ziAPIConnectEx(conn, dataServer, port, ZI_API_VERSION_6, nullptr));
45 ziApiServerVersionCheck(conn);
46 checkError(
47 ziAPIConnectDevice(conn, deviceAddress, deviceInterface, nullptr));
48 // Note, no device settings applied here; the device should be
49 // configured appropriately for the sweep beforehand.
50 ZIModuleHandle sweeper;
51 checkError(ziAPIModCreate(conn, &sweeper, "sweep"));
52 printf("module created, handle=%" PRIu64 "\n", sweeper);
53 checkError(ziAPIModSetString(conn, sweeper, "device", deviceAddress));
54 checkError(ziAPIModSetIntegerData(conn, sweeper, "xmapping", 1));
55 checkError(ziAPIModSetDoubleData(conn, sweeper, "start", 1000.0000000));
56 checkError(ziAPIModSetDoubleData(conn, sweeper, "stop", 1000000.0000000));
57 checkError(ziAPIModSetIntegerData(conn, sweeper, "scan", 0));
58 checkError(ziAPIModSetIntegerData(conn, sweeper, "samplecount", 100));
59 checkError(ziAPIModSetIntegerData(conn, sweeper, "loopcount", 1));
60 checkError(ziAPIModSetString(conn, sweeper, "gridnode", "oscs/0/freq"));
61 checkError(
62 ziAPIModSetDoubleData(conn, sweeper, "settling/time", 0.0000000));
63 checkError(
64 ziAPIModSetDoubleData(conn, sweeper, "settling/inaccuracy", 0.0001000));
65 checkError(ziAPIModSetIntegerData(conn, sweeper, "averaging/sample", 10));
66 checkError(ziAPIModSetDoubleData(conn, sweeper, "averaging/tc", 5.0000000));
67 checkError(ziAPIModSetDoubleData(conn, sweeper, "bandwidth", 0.0000000));
68 checkError(
69 ziAPIModSetDoubleData(conn, sweeper, "maxbandwidth", 1250000.0000000));
70 checkError(
71 ziAPIModSetDoubleData(conn, sweeper, "omegasuppression", 40.0000000));
72 checkError(ziAPIModSetIntegerData(conn, sweeper, "bandwidthcontrol", 2));
73
74 char savepath[] = "/tmp/";
75 checkError(ziAPIModSetString(conn, sweeper, "save/directory", savepath));
76 checkError(ziAPIModSetIntegerData(conn, sweeper, "order", 4));
77 checkError(ziAPIModSetIntegerData(conn, sweeper, "phaseunwrap", 0));
78 checkError(ziAPIModSetIntegerData(conn, sweeper, "sincfilter", 0));
79 checkError(ziAPIModSetIntegerData(conn, sweeper, "historylength", 100));
80 checkError(ziAPIModSetIntegerData(conn, sweeper, "endless", 0));
81
82 printf("Finished writing sweep parameters.\n");
83
84 char path[1024];
85 snprintf(path, sizeof(path), "/%s/demods/0/sample", deviceAddress);
86 checkError(ziAPIModSubscribe(conn, sweeper, path));
87 printf("Executing\n");
88 checkError(ziAPIModExecute(conn, sweeper));
89 ZIIntegerData finished;
90 printf("Checking if finished\n");
91 checkError(ziAPIModFinished(conn, sweeper, &finished));
92 ZIModuleEventPtr ev = NULL;
93
94 while (finished == 0)
95 {
96 sleep(500); // 500 [ms]
97
98 // Read out intermediate results. Data for grid points that
99 // have not been measured yet will be nan.
100 checkError(ziAPIModRead(conn, sweeper, ""));
101 ZIValueType_enum valueType;
102 uint64_t chunks;
103 ZIResult_enum res =
104 ziAPIModNextNode(conn, sweeper, path, 1024, &valueType, &chunks);
105 while (res == ZI_INFO_SUCCESS)
106 {
107 printf(
108 "Reading intermediate results, got node: %s with %" PRIu64
109 " chunks of type ",
110 path,
111 chunks);
112 for (uint64_t chunk = 0; chunk < chunks; ++chunk)
113 {
114 checkError(ziAPIModGetChunk(conn, sweeper, chunk, &ev));
115 printf(
116 "Data of chunk %" PRIu64 ": type %d, header time %" PRId64 "\n",
117 chunk,
118 ev->value->valueType,
119 ev->header->systemTime);
120 decodeChunk(ev);
121 }
122 printf("\n");
123 res = ziAPIModNextNode(conn, sweeper, path, 1024, &valueType, &chunks);
124 }
125
126 ZIDoubleData progress;
127 checkError(ziAPIModProgress(conn, sweeper, &progress));
128 printf("Progress: %.2f%% \n", progress * 100);
129
130 checkError(ziAPIModFinished(conn, sweeper, &finished));
131 }
132 printf("\n\n");
133 checkError(ziAPIModFinish(conn, sweeper));
134 checkError(ziAPIModUnSubscribe(conn, sweeper, "*"));
135
136 // Note: The final data may have been read out above in an "intermediate"
137 // after the sweeper had actually finished.
138 checkError(ziAPIModRead(conn, sweeper, ""));
139 ZIValueType_enum valueType;
140 uint64_t chunks;
141 ZIResult_enum res =
142 ziAPIModNextNode(conn, sweeper, path, 1024, &valueType, &chunks);
143 while (res == ZI_INFO_SUCCESS)
144 {
145 printf(
146 "Reading finished result, got node: %s with %" PRIu64
147 " chunks of type ",
148 path,
149 chunks);
150 printf("%d\n", valueType);
151 for (uint64_t chunk = 0; chunk < chunks; ++chunk)
152 {
153 checkError(ziAPIModGetChunk(conn, sweeper, chunk, &ev));
154 printf(
155 "Data of chunk %" PRIu64 ": type %d, header time %" PRId64 "\n",
156 chunk,
157 ev->value->valueType,
158 ev->header->systemTime);
159 decodeChunk(ev);
160 }
161 printf("\n");
162 res = ziAPIModNextNode(conn, sweeper, path, 1024, &valueType, &chunks);
163 }
164 if (res != ZI_WARNING_NOTFOUND)
165 {
166 checkError(res);
167 }
168 checkError(ziAPIModEventDeallocate(conn, sweeper, ev));
169
170 // Release module resources. Especially important if modules are created
171 // inside a loop to prevent excessive resource consumption.
172 checkError(ziAPIModClear(conn, sweeper));
173 ziAPIDisconnect(conn);
174 }
175 catch (std::runtime_error& e)
176 {
177 char extErrorMessage[1024] = "";
178 ziAPIGetLastError(conn, extErrorMessage, 1024);
179 fprintf(stderr, "Error: %s\ndetails: %s\n", e.what(), extErrorMessage);
180 return 1;
181 }
182
183 ziAPIDestroy(conn);
184 return 0;
185}
186
187void decodeChunk(ZIModuleEventPtr ev)
188{
189 printf(
190 " - Chunk header: created=%" PRId64 ", changed=%" PRId64 "\n",
191 ev->header->createdTimeStamp,
192 ev->header->changedTimeStamp);
193 switch (ev->value->valueType)
194 {
195 case ZI_VALUE_TYPE_NONE: // 0
196 printf(" - Type 'None' can't be decoded and should not appear in the "
197 "lookup!\n");
198 break;
199 case ZI_VALUE_TYPE_DOUBLE_DATA: // 1
200 {
201 ZIEvent& e = *ev->value;
202 printf(" - %d samples:\n", e.count);
203 for (size_t i = 0; i < e.count; ++i)
204 {
205 printf(" - sample %" PRsize_t "d = %f\n", i, e.value.doubleData[i]);
206 }
207 }
208 break;
209 case ZI_VALUE_TYPE_INTEGER_DATA: // 2
210 {
211 ZIEvent& e = *ev->value;
212 printf(" - %d samples:\n", e.count);
213 for (size_t i = 0; i < e.count; ++i)
214 {
215 printf(
216 " - sample %" PRsize_t "d = %" PRId64 "\n",
217 i,
218 e.value.integerData[i]);
219 }
220 }
221 break;
222 case ZI_VALUE_TYPE_DEMOD_SAMPLE: // 3
223 printf(" - Not implemented!\n");
224 break;
225 case ZI_VALUE_TYPE_SCOPE_WAVE_OLD: // 4
226 printf(" - Not implemented!\n");
227 break;
228 case ZI_VALUE_TYPE_AUXIN_SAMPLE: // 5
229 printf(" - Not implemented!\n");
230 break;
231 case ZI_VALUE_TYPE_DIO_SAMPLE: // 6
232 printf(" - Not implemented!\n");
233 break;
234 case ZI_VALUE_TYPE_BYTE_ARRAY: // 7
235 {
236 ZIByteArray& v = *ev->value->value.byteArray;
237 printf(" - length = %u\n", v.length);
238 char* str = reinterpret_cast<char*>(malloc(v.length + 1));
239 strncpy(str, reinterpret_cast<char*>(v.bytes), v.length);
240 str[v.length] = '\0';
241 printf(" - value = '%s'\n", str);
242 free(str);
243 }
244 break;
245 case ZI_VALUE_TYPE_PWA_WAVE: // 8
246 printf(" - Not implemented!\n");
247 break;
248 case ZI_VALUE_TYPE_TREE_CHANGE_DATA_OLD: // 16
249 printf(" - Not implemented!\n");
250 break;
251 case ZI_VALUE_TYPE_DOUBLE_DATA_TS: // 32
252 printf(" - Not implemented!\n");
253 break;
254 case ZI_VALUE_TYPE_INTEGER_DATA_TS: // 33
255 printf(" - Not implemented!\n");
256 break;
257 case ZI_VALUE_TYPE_SCOPE_WAVE: // 35
258 printf(" - Not implemented!\n");
259 break;
260 case ZI_VALUE_TYPE_SCOPE_WAVE_EX: // 36
261 printf(" - Not implemented!\n");
262 break;
263 case ZI_VALUE_TYPE_BYTE_ARRAY_TS: // 38
264 {
265 ZIByteArrayTS& v = *ev->value->value.byteArrayTS;
266 printf(" - timeStamp = %" PRIu64 "\n", v.timeStamp);
267 printf(" - length = %u\n", v.length);
268 char* str = reinterpret_cast<char*>(malloc(v.length + 1));
269 strncpy(str, reinterpret_cast<char*>(v.bytes), v.length);
270 str[v.length] = '\0';
271 printf(" - value = '%s'\n", str);
272 free(str);
273 }
274 break;
275 case ZI_VALUE_TYPE_TREE_CHANGE_DATA: // 48
276 printf(" - Not implemented!\n");
277 break;
278 case ZI_VALUE_TYPE_ASYNC_REPLY: // 50
279 printf(" - Not implemented!\n");
280 break;
281 case ZI_VALUE_TYPE_SWEEPER_WAVE: // 64
282 {
283 ZISweeperWave& v = *ev->value->value.sweeperWave;
284 printf(" - timeStamp = %" PRIu64 "\n", v.timeStamp);
285 printf(" - sampleCount = %" PRIu64 "\n", v.header.sampleCount);
286 printf(" - flags = %d\n", v.header.flags);
287 printf(" - sampleFormat = %d\n", v.header.sampleFormat);
288 printf(" - sweepMode = %d\n", v.header.sweepMode);
289 printf(" - bandwidthMode = %d\n", v.header.bandwidthMode);
290 for (size_t i = 0; i < v.header.sampleCount; ++i)
291 {
292 printf(" - sample %" PRsize_t "d:\n", i);
293 switch (v.header.sampleFormat)
294 {
295 case 0:
296 {
297 ZISweeperDoubleSample& s = v.data.dataDouble[i];
298 printf(" - grid = %f\n", s.grid);
299 printf(" - bandwidth = %f\n", s.bandwidth);
300 printf(" - count = %" PRIu64 "\n", s.count);
301 printf(" - v.avg = %f\n", s.value.avg);
302 printf(" - v.stddev = %f\n", s.value.stddev);
303 printf(" - v.pwr = %f\n", s.value.pwr);
304 }
305 break;
306 case 1:
307 {
308 ZISweeperDemodSample& s = v.data.dataDemod[i];
309 // printf(" - grid = %f\n", s.grid);
310 // printf(" - bandwidth = %f\n", s.bandwidth);
311 // printf(" - count = %" PRIu64 "\n", s.count);
312 // printf(" - tc = %f\n", s.tc);
313 // printf(" - tcMeas = %f\n", s.tcMeas);
314 // printf(" - settling = %f\n", s.settling);
315 // printf(" - setTimeStamp = %" PRIu64 "\n", s.setTimeStamp);
316 // printf(" - nextTimeStamp = %" PRIu64 "\n", s.nextTimeStamp);
317 // printf(" - x.avg = %f\n", s.x.avg);
318 // printf(" - x.stddev = %f\n", s.x.stddev);
319 // printf(" - x.pwr = %f\n", s.x.pwr);
320 // printf(" - y.avg = %f\n", s.y.avg);
321 // printf(" - y.stddev = %f\n", s.y.stddev);
322 // printf(" - y.pwr = %f\n", s.y.pwr);
323 printf(" - r.avg = %f\n", s.r.avg);
324 // printf(" - r.stddev = %f\n", s.r.stddev);
325 // printf(" - r.pwr = %f\n", s.r.pwr);
326 // printf(" - phase.avg = %f\n", s.phase.avg);
327 // printf(" - phase.stddev = %f\n", s.phase.stddev);
328 // printf(" - phase.pwr = %f\n", s.phase.pwr);
329 // printf(" - frequency.avg = %f\n", s.frequency.avg);
330 // printf(" - frequency.stddev = %f\n", s.frequency.stddev);
331 // printf(" - frequency.pwr = %f\n", s.frequency.pwr);
332 // printf(" - auxin0.avg = %f\n", s.auxin0.avg);
333 // printf(" - auxin0.stddev = %f\n", s.auxin0.stddev);
334 // printf(" - auxin0.pwr = %f\n", s.auxin0.pwr);
335 // printf(" - auxin1.avg = %f\n", s.auxin1.avg);
336 // printf(" - auxin1.stddev = %f\n", s.auxin1.stddev);
337 // printf(" - auxin1.pwr = %f\n", s.auxin1.pwr);
338 }
339 break;
340 case 2:
341 {
342 ZISweeperImpedanceSample& s = v.data.dataImpedance[i];
343 // printf(" - grid = %f\n", s.grid);
344 // printf(" - bandwidth = %f\n", s.bandwidth);
345 // printf(" - count = %" PRIu64 "\n", s.count);
346 // printf(" - tc = %f\n", s.tc);
347 // printf(" - tcMeas = %f\n", s.tcMeas);
348 // printf(" - settling = %f\n", s.settling);
349 // printf(" - setTimeStamp = %" PRIu64 "\n", s.setTimeStamp);
350 // printf(" - nextTimeStamp = %" PRIu64 "\n", s.nextTimeStamp);
351 printf(" - realz.avg = %f\n", s.realz.avg);
352 // printf(" - realz.stddev = %f\n", s.realz.stddev);
353 // printf(" - realz.pwr = %f\n", s.realz.pwr);
354 // printf(" - imagz.avg = %f\n", s.imagz.avg);
355 // printf(" - imagz.stddev = %f\n", s.imagz.stddev);
356 // printf(" - imagz.pwr = %f\n", s.imagz.pwr);
357 // printf(" - absz.avg = %f\n", s.absz.avg);
358 // printf(" - absz.stddev = %f\n", s.absz.stddev);
359 // printf(" - absz.pwr = %f\n", s.absz.pwr);
360 // printf(" - phasez.avg = %f\n", s.phasez.avg);
361 // printf(" - phasez.stddev = %f\n", s.phasez.stddev);
362 // printf(" - phasez.pwr = %f\n", s.phasez.pwr);
363 // printf(" - frequency.avg = %f\n", s.frequency.avg);
364 // printf(" - frequency.stddev = %f\n", s.frequency.stddev);
365 // printf(" - frequency.pwr = %f\n", s.frequency.pwr);
366 // printf(" - param0.avg = %f\n", s.param0.avg);
367 // printf(" - param0.stddev = %f\n", s.param0.stddev);
368 // printf(" - param0.pwr = %f\n", s.param0.pwr);
369 // printf(" - param1.avg = %f\n", s.param1.avg);
370 // printf(" - param1.stddev = %f\n", s.param1.stddev);
371 // printf(" - param1.pwr = %f\n", s.param1.pwr);
372 // printf(" - drive.avg = %f\n", s.drive.avg);
373 // printf(" - drive.stddev = %f\n", s.drive.stddev);
374 // printf(" - drive.pwr = %f\n", s.drive.pwr);
375 // printf(" - bias.avg = %f\n", s.bias.avg);
376 // printf(" - bias.stddev = %f\n", s.bias.stddev);
377 // printf(" - bias.pwr = %f\n", s.bias.pwr);
378 // printf(" - auxin0.avg = %f\n", s.auxin0.avg);
379 // printf(" - auxin0.stddev = %f\n", s.auxin0.stddev);
380 // printf(" - auxin0.pwr = %f\n", s.auxin0.pwr);
381 // printf(" - auxin1.avg = %f\n", s.auxin1.avg);
382 // printf(" - auxin1.stddev = %f\n", s.auxin1.stddev);
383 // printf(" - auxin1.pwr = %f\n", s.auxin1.pwr);
384 printf(" - flags = %d\n", s.flags);
385 }
386 break;
387 default:
388 printf(" - Unknown sample format!\n");
389 }
390 }
391 }
392 break;
393 case ZI_VALUE_TYPE_SPECTRUM_WAVE: // 65
394 printf(" - Not implemented!\n");
395 break;
396 default:
397 printf(" - Unknown data type!\n");
398 }
399}