-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathCorduroy_DAQ_utilityplot.ipf
executable file
·318 lines (255 loc) · 13 KB
/
Corduroy_DAQ_utilityplot.ipf
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
#pragma rtGlobals=2 // Use modern global access method.
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// CORDUROY_DAQ_utilityplot
// Please see READ-ME for relevant notes and information
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
Window UtilityPulsePanel() : Panel
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Get the variables necessary to customize panel
variable left = root:DAQ:Classes:UtilityPlot:left
variable top = root:DAQ:Classes:UtilityPlot:top
variable right = root:DAQ:Classes:UtilityPlot:right
variable bottom = root:DAQ:Classes:UtilityPlot:bottom
// Display function defines this string
PauseUpdate; Silent 1 // building the window...
NewPanel/W=(left,top,right,bottom)/K=1 as "UtilityPlot"
DoWindow/C UtilityPlot
SetDrawLayer UserBack
// Create the graph for test pulses and bridge balance pulses
// Make/O/N=(1000) testPulse
// testPulse = 0
// testPulse[250,750] = -5 // in mV/V
// SetScale x, 0, 0.05, "s", testPulse
// Display /HOST=UtilityPlot /K=1 /W=(0.05,0.15,0.95,0.95) testPulse
// ModifyGraph live=1
// Create the relevant panel items for monitoring seal resistance and bridge balance
SetDrawEnv fname="Verdana", fstyle=0, fsize=10, linefgc=(65278,55512,34438),textrgb=(65278,47802,17219)
GroupBox ControlGroup,pos={10,5},size={(right-left-20),(0.13*(bottom-top))},title="",fColor=(20000,40000,60000),fstyle=0,fsize=11,labelBack=(20000,40000,60000)
PopupMenu UP_CG_Popup1,bodyWidth=100,font="Verdana",proc=UP_SwitchMode,pos={115,18},title="Mode:",value="Test Pulse;Bridge Balance", font="Verdana", fsize=10
PopupMenu UP_CG_Popup2,bodyWidth=100,font="Verdana",proc=UP_SwitchChan,pos={115,43},title="Chan:",value="Channel_A;Channel_B;Channel_C;Channel_D", font="Verdana", fsize=10
ValDisplay UP_CG_ValDisp1,pos={185,20},size={140,20},title="R_seal (1e6):",font="Verdana",fsize=10
ValDisplay UP_CG_ValDisp1,limits={-Inf,Inf,0}, frame=2, value=root:DAQ:Classes:UtilityPlot:resistance
ValDisplay UP_CG_ValDisp2,pos={185,45},size={140,20},title="Fit error (arb):",font="Verdana",fsize=10
ValDisplay UP_CG_ValDisp2,limits={-Inf,Inf,0}, frame=2, value=root:DAQ:Classes:UtilityPlot:fiterr
Button UP_CG_Butt1, pos={338,18},font="Verdana",size={40,40}, proc=CORD_ToggleTest, title="Start", help={"Press to start/stop test pulse"}
ResumeUpdate
EndMacro //UtilityPulsePanel
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
Function CORD_CreateTestPulsePanel()
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
DoWindow/F UtilityPlot
if (V_Flag!=0)
return 0
endif
string restoreDF = GetDataFolder(1)
SetDataFolder root:
// Create globals that will need to be accessed by the panel
NewDataFolder/O root:DAQ
NewDataFolder/O root:DAQ:Classes
NewDataFolder/O root:DAQ:Classes:UtilityPlot
// Create necessary variables for the panel, and initialize popup menu values
SetDataFolder root:DAQ:Classes:UtilityPlot:
variable/G testType = 1
variable/G UtilG = 0
variable/G root:DAQ:Classes:UtilityPlot:counter = 0
string/G SwitchChan = "Channel_A"
CORD_CreateUtilityCoords()
// Launch the panel
DefaultFont/U "Verdana"
DoWindow/K UtilityPlot
Execute "UtilityPulsePanel()"
ModifyPanel /W=UtilityPlot cbRGB = (20000,20000,20000) //set background color
// Restore initial data folder
SetDataFolder restoreDF
End //CreateTestPulsePanel
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
Function CORD_CreateUtilityCoords()
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
string restoreDF = GetDataFolder(1)
SetDataFolder root:DAQ:Classes:UtilityPlot:
variable/G left = 0
variable/G right = 400
variable/G bottom = 1140
variable/G top = 640
variable/G resistance = 0
variable/G fiterr = 0
SetDataFolder restoreDF
End //CreateUtilityCoords
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
Function UP_SwitchMode(cntrlName,popNum,popStr) : PopupMenuControl
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
string cntrlName
variable popNum
string popStr
NVAR testType = root:DAQ:Classes:UtilityPlot:testType
testType = popNum
End //UP_SwitchMode
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
Function UP_SwitchChan(cntrlName,popNum,popStr) : PopupMenuControl
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
string cntrlName
variable popNum
string popStr
SVAR SwitchChan = root:DAQ:Classes:UtilityPlot:SwitchChan
SwitchChan = popStr
End //UP_SwitchChan
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
Function CORD_ToggleTest(ctrlName) : ButtonControl
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Similar to the main acquisition call, but instead this call is designed to execute and update more rapidly, no save ability
string ctrlName
// What channel is this?
SVAR SwitchChan = root:DAQ:Classes:UtilityPlot:SwitchChan
// Start or Stop
NVAR UtilG = root:DAQ:Classes:UtilityPlot:UtilG
// Call the testpulseACQ function
UtilG = !UtilG
CORD_testACQ(UtilG,SwitchChan)
string Titles = "Start;Stop"
Button $ctrlName title=StringFromList(UtilG,Titles)
End //StartTest
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
Function CORD_testACQ(Flag,channel)
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
variable Flag
string channel
if(Flag)
NVAR testFlag = root:DAQ:Classes:UtilityPlot:testType
NVAR UtilG = root:DAQ:Classes:UtilityPlot:UtilG
NVAR counter = root:DAQ:Classes:UtilityPlot:counter
// Create the test pulse to be injected
CORD_CreateTestPulse(testFlag,channel)
SetDataFolder root:DAQ:Classes:UtilityPlot:
string ChanInName = "test_"+channel
Duplicate /O testPulse, $ChanInName
WAVE local = $ChanInName
string ReadInWaves = ChanInName+", 0;"
string ExStr = ""
// Make sure to turn off the FIFO to prevent an error
FIFOStatus /Q TheFIFO
if(V_FIFORunning!=0)
fDAQmx_ScanStop("Dev1")
CtrlFIFO TheFIFO, stop
endif
switch(testFlag)
case 1:
ExStr = "CORD_InitialDisplayHook("+ChanInName+",counter)"
strswitch(channel) // string switch
case "Channel_A": // execute if case matches expression
ReadInWaves = ChanInName+", 0;"
DAQmx_Scan /DEV="Dev1" /TRIG={"/Dev1/Ctr0InternalOutput"} /EOSH="CORD_InitialDisplayHook(test_Channel_A,counter)" /RPT /BKG WAVES=ReadInWaves
DAQmx_WaveformGen /DEV="dev1" /TRIG={"/Dev1/Ctr0InternalOutput"} "testPulse, 0;"
break // exit from switch
case "Channel_B":
ReadInWaves = ChanInName+", 1;"
DAQmx_Scan /DEV="Dev1" /TRIG={"/Dev1/Ctr0InternalOutput"} /EOSH="CORD_InitialDisplayHook(test_Channel_B,counter)" /RPT /BKG WAVES=ReadInWaves
DAQmx_WaveformGen /DEV="dev1" /TRIG={"/Dev1/Ctr0InternalOutput"} "testPulse, 1;"
break
endswitch
DAQmx_CTR_OutputPulse /DEV="Dev1" /FREQ={40, 0.1} /NPLS=100000 0
break
case 2:
ExStr = "CORD_InitialDisplayHook("+ChanInName+",counter)"
strswitch(channel) // string switch
case "Channel_A": // execute if case matches expression
ReadInWaves = ChanInName+", 0;"
DAQmx_Scan /DEV="Dev1" /TRIG={"/Dev1/Ctr0InternalOutput"} /EOSH="CORD_InitialDisplayHook(test_Channel_A,counter)" /RPT /BKG WAVES=ReadInWaves
DAQmx_WaveformGen /DEV="dev1" /TRIG={"/Dev1/Ctr0InternalOutput"} "testPulse, 0;"
break // exit from switch
case "Channel_B":
ReadInWaves = ChanInName+", 1;"
DAQmx_Scan /DEV="Dev1" /TRIG={"/Dev1/Ctr0InternalOutput"} /EOSH="CORD_InitialDisplayHook(test_Channel_B,counter)" /RPT /BKG WAVES=ReadInWaves
DAQmx_WaveformGen /DEV="dev1" /TRIG={"/Dev1/Ctr0InternalOutput"} "testPulse, 1;"
break
endswitch
DAQmx_CTR_OutputPulse /DEV="Dev1" /FREQ={10, 0.1} /NPLS=100000 0
break
endswitch
else
fDAQmx_CTR_Finished("Dev1", 0)
fDAQmx_ScanStop("Dev1")
fDAQmx_WaveformStop("Dev1")
fDAQmx_WriteChan("Dev1", 0, 0.0, -0.1,1)
fDAQmx_WriteChan("Dev1", 1, 0.0, -0.1,1)
endif
End
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
Function CORD_InitialDisplayHook(local,counter)
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
WAVE local
variable counter
//WAVE local = $wave_name
if(counter==0)
Display /HOST=UtilityPlot /K=1 /W=(0.05,0.15,0.95,0.95) local
ModifyGraph live=1
counter+=1
endif
// Restore online analysis functionality to estimate resistance
// CORD_testOnlineAnalysis(testFlag,testWaveName,testPulse,channel)
End
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
Function CORD_CreateTestPulse(testFlag,channel)
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
variable testFlag
string channel
string WaveRef = "root:DAQ:Classes:Amplifiers:"+channel+"_gains"
if(WaveExists($WaveRef))
WAVE scaling = $WaveRef
else
Abort "Cannot find the appropriate amplifier gains. Need to setup using the Channel Configuration button."
endif
SetDataFolder root:DAQ:Classes:UtilityPlot
switch(testFlag)
case 1:
// make the VC test pulse
Make/O/N=(500) testPulse
testPulse = 0
testPulse[100,400] = -0.25 // in mV/V
SetScale x, 0, 0.025, "s", testPulse
break
case 2:
// make the CC bridge test pulse
Make/O/N=(2000) testPulse
testPulse = 0
testPulse[500,1500] = -0.25 // in pA/V
SetScale x, 0, 0.1, "s", testPulse
break
endswitch
End
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
Function CORD_testOnlineAnalysis(testFlag,testWaveName,testPulse,channel)
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
variable testFlag
string testWaveName
WAVE testPulse
string channel
string WaveRef = "root:DAQ:Classes:Amplifiers:"+channel+"_gains"
WAVE scaling = $WaveRef
variable MohmConv = 1, base, step, errstep
Wave local = $testWaveName
NVAR Ri = root:DAQ:Classes:UtilityPlot:resistance
NVAR Err = root:DAQ:Classes:UtilityPlot:fiterr
switch(testFlag)
case 1:
// measure the Ri of the VC test pulse
base = mean(local,0,50) // units are pA
step = mean(local,350,400)
Ri = abs(testPulse[1000]/scaling[2]) / abs(step-base) / 1000 // units are MOhm
Err = 0
break
case 2:
// measure the Ri and use a short step to guess the series resistance
base = mean(local,0,10)
step = mean(local,59.75,60)
Ri = 1000 * abs(step-base) / abs(testPulse[2000] / scaling[3])
errstep = mean(local,20.2,20.3)
Err = 1000 * (errstep-base)
break
endswitch
ControlUpdate/A /W=UtilityPulsePanel
End