@@ -117,6 +117,12 @@ class PS4000a(_PicoscopeBase):
117
117
"milliseconds" : 4 ,
118
118
"seconds" : 5 }
119
119
120
+ SIGGEN_TRIGGER_TYPES = {"Rising" : 0 , "Falling" : 1 ,
121
+ "GateHigh" : 2 , "GateLow" : 3 }
122
+
123
+ SIGGEN_TRIGGER_SOURCES = {"None" : 0 , "ScopeTrig" : 1 ,
124
+ "AuxIn" : 2 , "ExtIn" : 3 , "SoftTrig" : 4 }
125
+
120
126
def __init__ (self , serialNumber = None , connect = True ):
121
127
"""Load DLLs."""
122
128
self .handle = None
@@ -140,14 +146,15 @@ def __init__(self, serialNumber=None, connect=True):
140
146
141
147
super (PS4000a , self ).__init__ (serialNumber , connect )
142
148
143
- def _lowLevelOpenUnit (self , sn ):
149
+ def _lowLevelOpenUnit (self , serialNumber ):
144
150
c_handle = c_int16 ()
145
- if sn is not None :
146
- serialNullTermStr = create_string_buffer (str (sn ))
151
+ if serialNumber is not None :
152
+ serialNumberStr = create_string_buffer (bytes (serialNumber ,
153
+ encoding = 'utf-8' ))
147
154
else :
148
- serialNullTermStr = None
155
+ serialNumberStr = None
149
156
# Passing None is the same as passing NULL
150
- m = self .lib .ps4000aOpenUnit (byref (c_handle ), serialNullTermStr )
157
+ m = self .lib .ps4000aOpenUnit (byref (c_handle ), serialNumberStr )
151
158
self .handle = c_handle .value
152
159
153
160
# This will check if the power supply is not connected
@@ -163,17 +170,18 @@ def _lowLevelOpenUnit(self, sn):
163
170
164
171
self .model = self .getUnitInfo ('VariantInfo' )
165
172
166
- def _lowLevelOpenUnitAsync (self , sn ):
173
+ def _lowLevelOpenUnitAsync (self , serialNumber ):
167
174
c_status = c_int16 ()
168
- if sn is not None :
169
- serialNullTermStr = create_string_buffer (sn )
175
+ if serialNumber is not None :
176
+ serialNumberStr = create_string_buffer (bytes (serialNumber ,
177
+ encoding = 'utf-8' ))
170
178
else :
171
- serialNullTermStr = None
172
-
179
+ serialNumberStr = None
173
180
# Passing None is the same as passing NULL
174
- m = self .lib .ps4000aOpenUnitAsync (byref (c_status ), serialNullTermStr )
181
+ m = self .lib .ps4000aOpenUnitAsync (byref (c_status ), serialNumberStr )
175
182
self .checkResult (m )
176
183
184
+ # Set the model after completion in _lowLevelOpenUnitProgress.
177
185
return c_status .value
178
186
179
187
def _lowLevelOpenUnitProgress (self ):
@@ -188,6 +196,7 @@ def _lowLevelOpenUnitProgress(self):
188
196
189
197
if complete .value != 0 :
190
198
self .handle = handle .value
199
+ self .model = self .getUnitInfo ('VariantInfo' )
191
200
192
201
# if we only wanted to return one value, we could do somethign like
193
202
# progressPercent = progressPercent * (1 - 0.1 * complete)
@@ -291,27 +300,51 @@ def _lowLevelIsReady(self):
291
300
else :
292
301
return False
293
302
294
- def _lowLevelGetTimebase (self , tb , noSamples , oversample , segmentIndex ):
295
- """Return (timeIntervalSeconds, maxSamples)."""
303
+ def _lowLevelGetTimebase (self , timebase , noSamples , oversample ,
304
+ segmentIndex ):
305
+ """
306
+ Calculate the sampling interval and maximum number of samples.
307
+
308
+ timebase
309
+ Number of the selected timebase.
310
+ noSamples
311
+ Number of required samples.
312
+ oversample
313
+ Nnot used.
314
+ segmentIndex
315
+ Index of the segment to save samples in
316
+
317
+ Return
318
+ -------
319
+ timeIntervalSeconds : float
320
+ Time interval between two samples in s.
321
+ maxSamples : int
322
+ maximum number of samples available depending on channels
323
+ and timebase chosen.
324
+ """
296
325
maxSamples = c_int32 ()
297
- sampleRate = c_float ()
326
+ timeIntervalSeconds = c_float ()
298
327
299
- m = self .lib .ps4000aGetTimebase2 (c_int16 (self .handle ), c_uint32 (tb ),
300
- c_int32 (noSamples ), byref (sampleRate ),
328
+ m = self .lib .ps4000aGetTimebase2 (c_int16 (self .handle ),
329
+ c_uint32 (timebase ),
330
+ c_int32 (noSamples ),
331
+ byref (timeIntervalSeconds ),
301
332
byref (maxSamples ),
302
333
c_uint32 (segmentIndex ))
303
334
self .checkResult (m )
304
335
305
- return (sampleRate .value / 1.0E9 , maxSamples .value )
336
+ return (timeIntervalSeconds .value / 1.0E9 , maxSamples .value )
306
337
307
338
def getTimeBaseNum (self , sampleTimeS ):
308
- """ Convert the sample interval (float of seconds) to the
309
- corresponding integer timebase value as defined by the API.
310
- See "Timebases" section of the PS4000a programmers guide
339
+ """
340
+ Convert `sampleTimeS` in s to the integer timebase number.
341
+
342
+ See "Timebases" section of the PS4000a programmer's guide
311
343
for more information.
312
344
"""
313
345
314
346
if self .model == '4828' :
347
+ # TODO does a model 4828 exist?
315
348
maxSampleTime = (((2 ** 32 - 1 ) + 1 ) / 8E7 )
316
349
317
350
if sampleTimeS <= 12.5E-9 :
@@ -339,6 +372,14 @@ def getTimeBaseNum(self, sampleTimeS):
339
372
340
373
timebase = math .floor ((sampleTimeS * 5.0E7 ) + 2 )
341
374
375
+ elif self .model .startswith ('4824' ):
376
+ maxSampleTime = (((2 ** 32 - 1 ) + 1 ) / 8E7 )
377
+
378
+ if sampleTimeS > maxSampleTime :
379
+ sampleTimeS = maxSampleTime
380
+ timebase = math .floor (sampleTimeS * 8e7 - 1 )
381
+ timebase = max (0 , timebase )
382
+
342
383
else : # The original case from non "A" series
343
384
warnings .warn ("The model PS4000a you are using may not be "
344
385
"fully supported" , stacklevel = 2 )
@@ -354,13 +395,11 @@ def getTimeBaseNum(self, sampleTimeS):
354
395
355
396
timebase = math .floor ((sampleTimeS * 2e7 ) + 1 )
356
397
357
- # is this cast needed?
358
- timebase = int (timebase )
359
398
return timebase
360
399
361
400
def getTimestepFromTimebase (self , timebase ):
362
- """Return timebase to sampletime as seconds."""
363
- if self .model == '4828' :
401
+ """Convert ` timebase` index to sampletime in seconds."""
402
+ if self .model == '4828' or self . model . startswith ( '4824' ) :
364
403
dt = (timebase + 1 ) / 8.0E7
365
404
elif self .model == '4444' :
366
405
if timebase < 3 :
@@ -385,9 +424,6 @@ def _lowLevelSetDataBuffer(self, channel, data, downSampleMode,
385
424
Be sure to call _lowLevelClearDataBuffer
386
425
when you are done with the data array
387
426
or else subsequent calls to GetValue will still use the same array.
388
-
389
- segmentIndex is unused, but required by other versions of the API
390
- (eg PS5000a)
391
427
"""
392
428
dataPtr = data .ctypes .data_as (POINTER (c_int16 ))
393
429
numSamples = len (data )
0 commit comments