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 [[0, 23, 45, 4.35],
120 [0.1, 24, -525, 1.78]
121 ]
122 """
123
124 daqCtrl = ic.CDAQController(cmgr)
125
126
127 daqInfo = daqCtrl.info()
128 if daqInfo.getMaxItems() == 0:
129 raise Exception("Data Acquisition (DAQ) system is not available.")
130
131 print('MaxItems = ', daqInfo.getMaxItems())
132
133 daqVariables = ic.DAQConfigVector()
134 for varSamplData in variables:
135 varName = varSamplData[0]
136 samplTime = realTimeToDAQTimeFlags(varSamplData[1])
137
138 if varName.startswith('0x'):
139
140 memAddr = int(varName)
141 daqVariables.append(ic.CDAQConfigItem(4, 0, memAddr, samplTime))
142 else:
143
144 daqVariables.append(ic.CDAQConfigItem(varName, samplTime))
145
146
147 daqTimeStart = daqCtrl.status().getTime()
148
149 daqCtrl.configure(daqVariables)
150
151
152 daqCtrl.enableGlobal(True)
153
154 startTime = time.time()
155 endTime = startTime + recordingTimeInSeconds
156
157 numVars = len(variables)
158 recordedData = []
159
160 with open(fileName, 'w') as csvFile:
161
162
163
164
165 csvWriter = csv.writer(csvFile)
166
167 varNames = []
168 for varData in variables:
169 varNames.append(varData[0])
170
171 csvWriter.writerow(['Time'] + varNames)
172
173 sampleCounter = 0
174
175 lastTime = 0
176 row = [''] * (1 + numVars)
177
178 while time.time() < endTime:
179
180 daqStatus = daqCtrl.status()
181
182 if daqStatus.getNumSamplesAvailable() > 0:
183
184 if daqStatus.getOverflow():
185 print('SAMPLING OVERFLOW!')
186
187
188 daqSamples = ic.DAQSampleVector()
189 daqCtrl.read(daqSamples)
190
191
192 for daqSample in daqSamples:
193
194 sampleTime = daqSample.getTime() - daqTimeStart
195 columnIndex = daqSample.getIndex()+1
196
197 var = daqCtrl.getDataValue(daqSample)
198
199 if var.isTypeUnsigned() or var.isTypeSigned():
200 value = var.getLong()
201 elif var.isTypeFloat():
202 value = var.getDouble()
203 elif var.isTypeAddress():
204 value = var.getAddress().m_aAddress
205 elif var.isTypeCompound():
206 value = 'Struct'
207
208
209 if (sampleTime != lastTime):
210
211
212
213 if (lastTime != 0):
214 csvWriter.writerow(row)
215 if isPrintToStdOut:
216 print(row)
217 if isRecordToMemory:
218 recordedData.append(row)
219
220
221 row = [''] * (numVars+1)
222 row[0] = sampleTime
223
224
225 lastTime = sampleTime
226
227 row[columnIndex] = value
228
229
230 if (lastTime != 0):
231 csvWriter.writerow(row)
232 if isPrintToStdOut:
233 print(row)
234 if isRecordToMemory:
235 recordedData.append(row)
236
237 return recordedData
238
239
240def writeDataToXLSX(fileName, data, expressions):
241 book = openpyxl.Workbook()
242 sheet = book.create_sheet()
243 sheet.title = 'Variables'
244
245
246 sheet.append(['Time'] + expressions)
247
248 for row in data:
249 sheet.append(row)
250
251 book.save(fileName)
252
253
254def main():
255
256 if len(sys.argv) < 2:
257 printHelp()
258 return
259
260 samplingInfo = []
261 varNames = []
262
263
264
265
266
267
268 for idx in range(1, len(sys.argv), 2):
269 varName = sys.argv[idx]
270 varNames.append(varName)
271 samplingInfo.append([varName, float(sys.argv[idx + 1])])
272
273 cmgr = ic.ConnectionMgr()
274 cmgr.initLogger('daq', 'daqExample.log', ic.CLogger.PYTHON)
275 cmgr.connect(ic.CConnectionConfig().instanceId(winidea_id))
276 if not cmgr.isAttached():
277 print("The connection to winIDEA has not been established - exiting script.")
278 sys.exit(-1)
279 else:
280 print("Established connection to winIDEA.")
281 debugCtrl = initTarget(cmgr)
282
283
284 recordingTimeInSeconds = 3
285 filePrefix = 'daqData'
286 isRecordToMemory = True
287 isPrintToStdOut = True
288 print('Recording ...')
289
290 daqResults = recordVariables(cmgr,
291 debugCtrl,
292 samplingInfo,
293 recordingTimeInSeconds,
294 filePrefix + '.csv',
295 isRecordToMemory,
296 isPrintToStdOut)
297
298 if isOpenPyXLInstalled and daqResults:
299 writeDataToXLSX(filePrefix + '.xlsx', daqResults, varNames)
300
301 if isPyLabInstalled:
302 lineTypes = ['k', 'r', 'g', 'b', 'k:', 'r:', 'g:', 'b:']
303
304
305 data = plab.array(daqResults).astype('S12')
306
307 plotIdx = 1
308 for varName in varNames:
309 plab.subplot(len(varNames), 1, plotIdx)
310
311
312
313
314 linesData = data[data[:, plotIdx] != b'']
315 times = linesData[:, 0]
316 plab.plot(times, linesData[:, plotIdx], lineTypes[(plotIdx - 1)% len(lineTypes)])
317 plab.ylabel(varName)
318 plotIdx += 1
319
320 plab.xlabel('t[s]')
321 plab.show()
322
323 print('Done!')
324
325if __name__ == '__main__':
326 main()