1
2
3
4
5
6
7
8
9
10
11
12
13
14
15import sys
16import csv
17import time
18import isystem.connect as ic
19
20winidea_id = ''
21
22
23try:
24 import openpyxl
25 isOpenPyXLInstalled = True
26except (ImportError) as ex:
27 isOpenPyXLInstalled = False
28
29try:
30 import pylab as plab
31 isPyLabInstalled = True
32except (ImportError) as ex:
33 isPyLabInstalled = False
34
35
36def printHelp():
37 print("Usage: dataRecorderWithDAQ.py <variableName1 samplingRateInSeconds1> ...")
38 print("")
39 print(" If 'samplingRateInSeconds' == 0, the smallest possible sampling")
40 print(" time is used. Supported values: 0.001, 0.01, 0.1, 1 second.")
41 print(" See CDAQController::EDAQSampligFlags for all possible")
42 print(" values.")
43 print("")
44 print("")
45 print("Example: dataRecorderWithDAQ.py main_loop_counter 0.1 g_baseStruct.i_base 0.01")
46 print(" records main_loop_counter each 100 ms, and g_baseStruct.i_base with 10 ms period.")
47
48
49def initTarget(cmgr):
50 """
51 This function initializes the target. Customize it according to
52 your needs.
53 """
54
55 debugCtrl = ic.CDebugFacade(cmgr)
56
57 debugCtrl.download()
58 debugCtrl.runUntilFunction("main")
59 debugCtrl.waitUntilStopped()
60
61 debugCtrl.run()
62
63 return debugCtrl
64
65
66def realTimeToDAQTimeFlags(samplTime):
67 """
68 Converts the given sampling time in seconds to EDAQSamplingFlags.
69 """
70 if samplTime < 0.001:
71 return ic.CDAQController.daqSampleMax
72 elif samplTime < 0.01:
73 return ic.CDAQController.daqSample1ms
74 elif samplTime < 0.1:
75 return ic.CDAQController.daqSample10ms
76 elif samplTime < 1:
77 return ic.CDAQController.daqSample100ms
78 else:
79 return ic.CDAQController.daqSample1s
80
81
82def recordVariables(cmgr,
83 debugCtrl,
84 variables,
85 recordingTimeInSeconds,
86 fileName,
87 isRecordToMemory,
88 isPrintToStdOut):
89 """
90 This function reads varibles and writes them to CSV file.
91 If isRecordToMemory == False, the amount of data that can be recorded is
92 limited by the free disk size.
93
94 Parameters:
95
96 debugCtrl - iSYSTEM's debugCtrl controller, which provides access to target
97
98 variables - array of two element arrays, where the first element contains
99 variable name and the second element contains sampling interval,
100 for example: [['main_loop_counter', 0.1], ['g_baseStruct.i_base', 0]].
101 Sampling interval set to 0 means the smallest interval possible.
102
103 recordingTimeInSeconds - how long to record the data, in seconds. Recording
104 can also be terminated by pressing the 'q' key
105
106 fileName - name of the output CSV file.
107
108 isRecordToMemory - if True, then data is also stored into memory
109 array and returned as function return value. Be
110 aware of memory usage in this case. If false,
111 an empty list is returned.
112
113 isPrintToStdOut - if True, each row is printed to stdout during recording
114
115 Returns:
116 List of rows, where each row is a list containing time stamp and recorded
117 values in the same order as variable names were specified. Example for
118 two samples of three variables::
119
120 [[0, 23, 45, 4.35],
121 [0.1, 24, -525, 1.78]
122 ]
123
124 """
125
126 daqCtrl = ic.CDAQController(cmgr)
127
128
129 daqInfo = daqCtrl.info()
130 if daqInfo.getMaxItems() == 0:
131 raise Exception("Data Acquisition (DAQ) system is not available.")
132
133 print('MaxItems = ', daqInfo.getMaxItems())
134
135 daqVariables = ic.DAQConfigVector()
136 for varSamplData in variables:
137 varName = varSamplData[0]
138 samplTime = realTimeToDAQTimeFlags(varSamplData[1])
139
140 if varName.startswith('0x'):
141
142 memAddr = int(varName)
143 daqVariables.append(ic.CDAQConfigItem(4, 0, memAddr, samplTime))
144 else:
145
146 daqVariables.append(ic.CDAQConfigItem(varName, samplTime))
147
148
149 daqTimeStart = daqCtrl.status().getTime()
150
151 daqCtrl.configure(daqVariables)
152
153
154 daqCtrl.enableGlobal(True)
155
156 startTime = time.time()
157 endTime = startTime + recordingTimeInSeconds
158
159 numVars = len(variables)
160 recordedData = []
161
162 with open(fileName, 'w') as csvFile:
163
164
165
166
167 csvWriter = csv.writer(csvFile)
168
169 varNames = []
170 for varData in variables:
171 varNames.append(varData[0])
172
173 csvWriter.writerow(['Time'] + varNames)
174
175 sampleCounter = 0
176
177 lastTime = 0
178 row = [''] * (1 + numVars)
179
180 while time.time() < endTime:
181
182 daqStatus = daqCtrl.status()
183
184 if daqStatus.getNumSamplesAvailable() > 0:
185
186 if daqStatus.getOverflow():
187 print('SAMPLING OVERFLOW!')
188
189
190 daqSamples = ic.DAQSampleVector()
191 daqCtrl.read(daqSamples)
192
193
194 for daqSample in daqSamples:
195
196 sampleTime = daqSample.getTime() - daqTimeStart
197 columnIndex = daqSample.getIndex()+1
198
199 var = daqCtrl.getDataValue(daqSample)
200
201 if var.isTypeUnsigned() or var.isTypeSigned():
202 value = var.getLong()
203 elif var.isTypeFloat():
204 value = var.getDouble()
205 elif var.isTypeAddress():
206 value = var.getAddress().m_aAddress
207 elif var.isTypeCompound():
208 value = 'Struct'
209
210
211 if (sampleTime != lastTime):
212
213
214
215 if (lastTime != 0):
216 csvWriter.writerow(row)
217 if isPrintToStdOut:
218 print(row)
219 if isRecordToMemory:
220 recordedData.append(row)
221
222
223 row = [''] * (numVars+1)
224 row[0] = sampleTime
225
226
227 lastTime = sampleTime
228
229 row[columnIndex] = value
230
231
232 if (lastTime != 0):
233 csvWriter.writerow(row)
234 if isPrintToStdOut:
235 print(row)
236 if isRecordToMemory:
237 recordedData.append(row)
238
239 return recordedData
240
241
242def writeDataToXLSX(fileName, data, expressions):
243 book = openpyxl.Workbook()
244 sheet = book.create_sheet()
245 sheet.title = 'Variables'
246
247
248 sheet.append(['Time'] + expressions)
249
250 for row in data:
251 sheet.append(row)
252
253 book.save(fileName)
254
255
256def main():
257
258 if len(sys.argv) < 2:
259 printHelp()
260 return
261
262 samplingInfo = []
263 varNames = []
264
265
266
267
268
269
270 for idx in range(1, len(sys.argv), 2):
271 varName = sys.argv[idx]
272 varNames.append(varName)
273 samplingInfo.append([varName, float(sys.argv[idx + 1])])
274
275 cmgr = ic.ConnectionMgr()
276 cmgr.initLogger('daq', 'daqExample.log', ic.CLogger.PYTHON)
277 cmgr.connect(ic.CConnectionConfig().instanceId(winidea_id))
278 if not cmgr.isAttached():
279 print("The connection to winIDEA has not been established - exiting script.")
280 sys.exit(-1)
281 else:
282 print("Established connection to winIDEA.")
283 debugCtrl = initTarget(cmgr)
284
285
286 recordingTimeInSeconds = 3
287 filePrefix = 'daqData'
288 isRecordToMemory = True
289 isPrintToStdOut = True
290 print('Recording ...')
291
292 daqResults = recordVariables(cmgr,
293 debugCtrl,
294 samplingInfo,
295 recordingTimeInSeconds,
296 filePrefix + '.csv',
297 isRecordToMemory,
298 isPrintToStdOut)
299
300 if isOpenPyXLInstalled and daqResults:
301 writeDataToXLSX(filePrefix + '.xlsx', daqResults, varNames)
302
303 if isPyLabInstalled:
304 lineTypes = ['k', 'r', 'g', 'b', 'k:', 'r:', 'g:', 'b:']
305
306
307 data = plab.array(daqResults).astype('S12')
308
309 plotIdx = 1
310 for varName in varNames:
311 plab.subplot(len(varNames), 1, plotIdx)
312
313
314
315
316 linesData = data[data[:, plotIdx] != b'']
317 times = linesData[:, 0]
318 plab.plot(times, linesData[:, plotIdx], lineTypes[(plotIdx - 1)% len(lineTypes)])
319 plab.ylabel(varName)
320 plotIdx += 1
321
322 plab.xlabel('t[s]')
323 plab.show()
324
325 print('Done!')
326
327if __name__ == '__main__':
328 main()