Skip to content

Commit c6f59d7

Browse files
author
neil.hamilton
committed
merge TSP-471 branch into master
2 parents eeb28ed + f9065b2 commit c6f59d7

File tree

4 files changed

+526
-16
lines changed

4 files changed

+526
-16
lines changed

picosdk/ps5000a.py

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,8 @@ def _define_conditionsInfo():
169169
'PS5000A_RATIO_MODE_AVERAGE': 4,
170170
}
171171

172+
ps5000a.PICO_RATIO_MODE = {k[19:]: v for k, v in ps5000a.PS5000A_RATIO_MODE.items()}
173+
172174
ps5000a.PS5000A_TIME_UNITS = make_enum([
173175
'PS5000A_FS',
174176
'PS5000A_PS',
@@ -179,7 +181,13 @@ def _define_conditionsInfo():
179181
'PS5000A_MAX_TIME_UNITS',
180182
])
181183

182-
ps5000a.PICO_RATIO_MODE = {k[19:]: v for k, v in ps5000a.PS5000A_RATIO_MODE.items()}
184+
ps5000a.PS5000A_PULSE_WIDTH_TYPE = make_enum([
185+
'PS5000A_PW_TYPE_NONE',
186+
'PS5000A_PW_TYPE_LESS_THAN',
187+
'PS5000A_PW_TYPE_GREATER_THAN',
188+
'PS5000A_PW_TYPE_IN_RANGE',
189+
'PS5000A_PW_TYPE_OUT_OF_RANGE',
190+
])
183191

184192

185193

ps5000aExamples/ps5000aBlockExample.py

Lines changed: 61 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -38,22 +38,22 @@
3838

3939
# Set up channel A
4040
# handle = chandle
41-
channel = ps.PS5000A_CHANNEL["PS5000A_CHANNEL_A"]
41+
channelA = ps.PS5000A_CHANNEL["PS5000A_CHANNEL_A"]
4242
# enabled = 1
4343
coupling_type = ps.PS5000A_COUPLING["PS5000A_DC"]
44-
chARange = ps.PS5000A_RANGE["PS5000A_20V"]
44+
chARange = ps.PS5000A_RANGE["PS5000A_2V"]
4545
# analogue offset = 0 V
46-
status["setChA"] = ps.ps5000aSetChannel(chandle, channel, 1, coupling_type, chARange, 0)
46+
status["setChA"] = ps.ps5000aSetChannel(chandle, channelA, 1, coupling_type, chARange, 0)
4747
assert_pico_ok(status["setChA"])
4848

4949
# Set up channel B
5050
# handle = chandle
51-
channel = ps.PS5000A_CHANNEL["PS5000A_CHANNEL_B"]
51+
channelB = ps.PS5000A_CHANNEL["PS5000A_CHANNEL_B"]
5252
# enabled = 1
5353
# coupling_type = ps.PS5000A_COUPLING["PS5000A_DC"]
5454
chBRange = ps.PS5000A_RANGE["PS5000A_2V"]
5555
# analogue offset = 0 V
56-
status["setChB"] = ps.ps5000aSetChannel(chandle, channel, 1, coupling_type, chBRange, 0)
56+
status["setChB"] = ps.ps5000aSetChannel(chandle, channelB, 1, coupling_type, chBRange, 0)
5757
assert_pico_ok(status["setChB"])
5858

5959
# find maximum ADC count value
@@ -63,16 +63,62 @@
6363
status["maximumValue"] = ps.ps5000aMaximumValue(chandle, ctypes.byref(maxADC))
6464
assert_pico_ok(status["maximumValue"])
6565

66-
# Set up single trigger
67-
# handle = chandle
68-
# enabled = 1
69-
source = ps.PS5000A_CHANNEL["PS5000A_CHANNEL_A"]
70-
threshold = int(mV2adc(500,chARange, maxADC))
71-
# direction = PS5000A_RISING = 2
72-
# delay = 0 s
73-
# auto Trigger = 1000 ms
74-
status["trigger"] = ps.ps5000aSetSimpleTrigger(chandle, 1, source, threshold, 2, 0, 1000)
75-
assert_pico_ok(status["trigger"])
66+
# Parameters
67+
chA=0 # channel A
68+
chB=1 # channel B
69+
maxADC = ctypes.c_int16(32767)
70+
NB=2 #NB=nConditions=nDirections=nChannelProperties
71+
rg=2000 # range of voltage in millivolt
72+
threshold=1000
73+
thresholdLower=0
74+
hyteresis=0
75+
window=False
76+
direction=2 # Rising
77+
78+
#CONDITIONS
79+
conditions = (ps.PS5000A_CONDITION * NB)()
80+
clear=0x00000001
81+
add=0x00000002
82+
cond_info=clear|add
83+
a = ps.PS5000A_TRIGGER_STATE["PS5000A_CONDITION_TRUE"]
84+
conditions[0]= ps.PS5000A_CONDITION(channelA, ps.PS5000A_TRIGGER_STATE["PS5000A_CONDITION_TRUE"])
85+
conditions[1]= ps.PS5000A_CONDITION(channelB, ps.PS5000A_TRIGGER_STATE["PS5000A_CONDITION_TRUE"])
86+
status["maximumValue_"] = ps.ps5000aMaximumValue(chandle, ctypes.byref(maxADC))
87+
assert_pico_ok(status["maximumValue_"])
88+
status["setTriggerChannelConditions_"] = ps.ps5000aSetTriggerChannelConditionsV2(chandle,
89+
ctypes.byref(conditions),
90+
NB,
91+
cond_info)
92+
assert_pico_ok(status["setTriggerChannelConditions_"])
93+
94+
# DIRECTIONS
95+
if window==True:
96+
th_mode=ps.PS5000A_THRESHOLD_MODE["PS5000A_WINDOW"]
97+
else:
98+
th_mode=ps.PS5000A_THRESHOLD_MODE["PS5000A_LEVEL"]
99+
triggerDirections=(ps.PS5000A_DIRECTION * NB)()
100+
triggerDirections[0] = ps.PS5000A_DIRECTION(chA, direction, th_mode)
101+
triggerDirections[1] = ps.PS5000A_DIRECTION(chB, direction, th_mode)
102+
status["setTriggerChannelDirections_"] = ps.ps5000aSetTriggerChannelDirectionsV2(chandle, ctypes.byref(triggerDirections), NB)
103+
assert_pico_ok(status["setTriggerChannelDirections_"])
104+
105+
# PROPERTIES
106+
thUpper = mV2adc(threshold, chARange, maxADC)
107+
thLower = mV2adc(thresholdLower, chARange, maxADC)
108+
hysteresis=0
109+
triggerProperties = (ps.PS5000A_TRIGGER_CHANNEL_PROPERTIES_V2 * NB)()
110+
triggerProperties[0] = ps.PS5000A_TRIGGER_CHANNEL_PROPERTIES_V2(thUpper,
111+
hysteresis,
112+
thLower,
113+
hysteresis,
114+
0)
115+
triggerProperties[1] = ps.PS5000A_TRIGGER_CHANNEL_PROPERTIES_V2(thUpper,
116+
hysteresis,
117+
thLower,
118+
hysteresis,
119+
1)
120+
status["setTriggerChannelProperties_"] = ps.ps5000aSetTriggerChannelPropertiesV2(chandle, ctypes.byref(triggerProperties), NB, 0)
121+
assert_pico_ok(status["setTriggerChannelProperties_"])
76122

77123
# Set number of pre and post trigger samples to be collected
78124
preTriggerSamples = 2500
Lines changed: 228 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,228 @@
1+
#
2+
# Copyright (C) 2018-2022 Pico Technology Ltd. See LICENSE file for terms.
3+
#
4+
# PS5000A BLOCK MODE EXAMPLE
5+
# This example opens a 5000a driver device, sets up two channels and a trigger then collects a block of data.
6+
# This data is then plotted as mV against time in ns.
7+
8+
import ctypes
9+
import numpy as np
10+
from picosdk.ps5000a import ps5000a as ps
11+
import matplotlib.pyplot as plt
12+
from picosdk.functions import adc2mV, assert_pico_ok, mV2adc
13+
import math
14+
15+
# Create chandle and status ready for use
16+
chandle = ctypes.c_int16()
17+
status = {}
18+
19+
# Open 5000 series PicoScope
20+
# Resolution set to 12 Bit
21+
resolution =ps.PS5000A_DEVICE_RESOLUTION["PS5000A_DR_12BIT"]
22+
# Returns handle to chandle for use in future API functions
23+
status["openunit"] = ps.ps5000aOpenUnit(ctypes.byref(chandle), None, resolution)
24+
25+
try:
26+
assert_pico_ok(status["openunit"])
27+
except: # PicoNotOkError:
28+
29+
powerStatus = status["openunit"]
30+
31+
if powerStatus == 286:
32+
status["changePowerSource"] = ps.ps5000aChangePowerSource(chandle, powerStatus)
33+
elif powerStatus == 282:
34+
status["changePowerSource"] = ps.ps5000aChangePowerSource(chandle, powerStatus)
35+
else:
36+
raise
37+
38+
assert_pico_ok(status["changePowerSource"])
39+
40+
# Set up channel A
41+
# handle = chandle
42+
channel = ps.PS5000A_CHANNEL["PS5000A_CHANNEL_A"]
43+
# enabled = 1
44+
coupling_type = ps.PS5000A_COUPLING["PS5000A_DC"]
45+
chARange = ps.PS5000A_RANGE["PS5000A_20V"]
46+
# analogue offset = 0 V
47+
status["setChA"] = ps.ps5000aSetChannel(chandle, channel, 1, coupling_type, chARange, 0)
48+
assert_pico_ok(status["setChA"])
49+
50+
# Set up channel B
51+
# handle = chandle
52+
channel = ps.PS5000A_CHANNEL["PS5000A_CHANNEL_B"]
53+
# enabled = 1
54+
# coupling_type = ps.PS5000A_COUPLING["PS5000A_DC"]
55+
chBRange = ps.PS5000A_RANGE["PS5000A_2V"]
56+
# analogue offset = 0 V
57+
status["setChB"] = ps.ps5000aSetChannel(chandle, channel, 1, coupling_type, chBRange, 0)
58+
assert_pico_ok(status["setChB"])
59+
60+
# find maximum ADC count value
61+
# handle = chandle
62+
# pointer to value = ctypes.byref(maxADC)
63+
maxADC = ctypes.c_int16()
64+
status["maximumValue"] = ps.ps5000aMaximumValue(chandle, ctypes.byref(maxADC))
65+
assert_pico_ok(status["maximumValue"])
66+
67+
# Set number of pre and post trigger samples to be collected
68+
preTriggerSamples = 2500
69+
postTriggerSamples = 2500
70+
maxSamples = preTriggerSamples + postTriggerSamples
71+
72+
# Get timebase information
73+
# Warning: When using this example it may not be possible to access all Timebases as all channels are enabled by default when opening the scope.
74+
# To access these Timebases, set any unused analogue channels to off.
75+
# handle = chandle
76+
timebase = 8
77+
# noSamples = maxSamples
78+
# pointer to timeIntervalNanoseconds = ctypes.byref(timeIntervalns)
79+
# pointer to maxSamples = ctypes.byref(returnedMaxSamples)
80+
# segment index = 0
81+
82+
timeIntervalns = ctypes.c_float()
83+
returnedMaxSamples = ctypes.c_int32()
84+
status["getTimebase2"] = ps.ps5000aGetTimebase2(chandle, timebase, maxSamples, ctypes.byref(timeIntervalns), ctypes.byref(returnedMaxSamples), 0)
85+
assert_pico_ok(status["getTimebase2"])
86+
87+
# Set up an advanced trigger
88+
adcTriggerLevel = mV2adc(500, chARange, maxADC)
89+
90+
triggerProperties = ps.PS5000A_TRIGGER_CHANNEL_PROPERTIES_V2(adcTriggerLevel,
91+
10,
92+
0,
93+
10,
94+
ps.PS5000A_CHANNEL["PS5000A_CHANNEL_A"])
95+
96+
status["setTriggerChannelPropertiesV2"] = ps.ps5000aSetTriggerChannelPropertiesV2(chandle, ctypes.byref(triggerProperties), 1, 0)
97+
assert_pico_ok(status["setTriggerChannelPropertiesV2"])
98+
99+
triggerConditions = (ps.PS5000A_CONDITION * 2)()
100+
# triggerConditions[0] = ps.PS5000A_CONDITION(ps.PS5000A_CHANNEL["PS5000A_CHANNEL_A"],
101+
# ps.PS5000A_TRIGGER_STATE["PS5000A_CONDITION_TRUE"])
102+
triggerConditions = ps.PS5000A_CONDITION(ps.PS5000A_CHANNEL["PS5000A_PULSE_WIDTH_SOURCE"],
103+
ps.PS5000A_TRIGGER_STATE["PS5000A_CONDITION_TRUE"])
104+
105+
clear = 1
106+
add = 2
107+
108+
status["setTriggerChannelConditionsV2"] = ps.ps5000aSetTriggerChannelConditionsV2(chandle, ctypes.byref(triggerConditions), 1, (clear|add))
109+
assert_pico_ok(status["setTriggerChannelConditionsV2"])
110+
111+
triggerDirections = ps.PS5000A_DIRECTION(ps.PS5000A_CHANNEL["PS5000A_CHANNEL_A"],
112+
ps.PS5000A_THRESHOLD_DIRECTION["PS5000A_RISING"],
113+
ps.PS5000A_THRESHOLD_MODE["PS5000A_LEVEL"])
114+
115+
status["setTriggerChannelDirections"] = ps.ps5000aSetTriggerChannelDirectionsV2(chandle, ctypes.byref(triggerDirections), 1)
116+
assert_pico_ok(status["setTriggerChannelDirections"])
117+
118+
# pulse width setup
119+
# pulse width conditions
120+
PWQConditions = ps.PS5000A_CONDITION(ps.PS5000A_CHANNEL["PS5000A_CHANNEL_A"], ps.PS5000A_TRIGGER_STATE["PS5000A_CONDITION_TRUE"])
121+
122+
status["setPWQualifierConditions"] = ps.ps5000aSetPulseWidthQualifierConditions(chandle, ctypes.byref(PWQConditions), 1, add)
123+
assert_pico_ok(status["setPWQualifierConditions"])
124+
125+
126+
#set pulse width counter
127+
timeWidthNs = 3000
128+
counterSamples = math.ceil(timeWidthNs / timeIntervalns.value)
129+
130+
# pulse width properties
131+
PWtype = 2 #ps.PS5000A_PULSE_WIDTH_TYPE["PS5000A_PW_TYPE_GREATER_THAN"]
132+
status["setPWQualifierProperties"] = ps.ps5000aSetPulseWidthQualifierProperties(chandle, counterSamples, counterSamples, PWtype)
133+
assert_pico_ok(status["setPWQualifierProperties"])
134+
135+
#pulse width directions
136+
PWQDirections = ps.PS5000A_DIRECTION(ps.PS5000A_CHANNEL["PS5000A_CHANNEL_A"], ps.PS5000A_THRESHOLD_DIRECTION["PS5000A_FALLING"], ps.PS5000A_THRESHOLD_MODE["PS5000A_LEVEL"])
137+
status["setPWQualifierDirections"] = ps.ps5000aSetPulseWidthQualifierDirections(chandle, ctypes.byref(PWQDirections), 1)
138+
assert_pico_ok(status["setPWQualifierDirections"])
139+
140+
# Run block capture
141+
# handle = chandle
142+
# number of pre-trigger samples = preTriggerSamples
143+
# number of post-trigger samples = PostTriggerSamples
144+
# timebase = 8 = 80 ns (see Programmer's guide for mre information on timebases)
145+
# time indisposed ms = None (not needed in the example)
146+
# segment index = 0
147+
# lpReady = None (using ps5000aIsReady rather than ps5000aBlockReady)
148+
# pParameter = None
149+
status["runBlock"] = ps.ps5000aRunBlock(chandle, preTriggerSamples, postTriggerSamples, timebase, None, 0, None, None)
150+
assert_pico_ok(status["runBlock"])
151+
152+
# Check for data collection to finish using ps5000aIsReady
153+
ready = ctypes.c_int16(0)
154+
check = ctypes.c_int16(0)
155+
while ready.value == check.value:
156+
status["isReady"] = ps.ps5000aIsReady(chandle, ctypes.byref(ready))
157+
158+
159+
# Create buffers ready for assigning pointers for data collection
160+
bufferAMax = (ctypes.c_int16 * maxSamples)()
161+
bufferAMin = (ctypes.c_int16 * maxSamples)() # used for downsampling which isn't in the scope of this example
162+
bufferBMax = (ctypes.c_int16 * maxSamples)()
163+
bufferBMin = (ctypes.c_int16 * maxSamples)() # used for downsampling which isn't in the scope of this example
164+
165+
# Set data buffer location for data collection from channel A
166+
# handle = chandle
167+
source = ps.PS5000A_CHANNEL["PS5000A_CHANNEL_A"]
168+
# pointer to buffer max = ctypes.byref(bufferAMax)
169+
# pointer to buffer min = ctypes.byref(bufferAMin)
170+
# buffer length = maxSamples
171+
# segment index = 0
172+
# ratio mode = PS5000A_RATIO_MODE_NONE = 0
173+
status["setDataBuffersA"] = ps.ps5000aSetDataBuffers(chandle, source, ctypes.byref(bufferAMax), ctypes.byref(bufferAMin), maxSamples, 0, 0)
174+
assert_pico_ok(status["setDataBuffersA"])
175+
176+
# Set data buffer location for data collection from channel B
177+
# handle = chandle
178+
source = ps.PS5000A_CHANNEL["PS5000A_CHANNEL_B"]
179+
# pointer to buffer max = ctypes.byref(bufferBMax)
180+
# pointer to buffer min = ctypes.byref(bufferBMin)
181+
# buffer length = maxSamples
182+
# segment index = 0
183+
# ratio mode = PS5000A_RATIO_MODE_NONE = 0
184+
status["setDataBuffersB"] = ps.ps5000aSetDataBuffers(chandle, source, ctypes.byref(bufferBMax), ctypes.byref(bufferBMin), maxSamples, 0, 0)
185+
assert_pico_ok(status["setDataBuffersB"])
186+
187+
# create overflow loaction
188+
overflow = ctypes.c_int16()
189+
# create converted type maxSamples
190+
cmaxSamples = ctypes.c_int32(maxSamples)
191+
192+
# Retried data from scope to buffers assigned above
193+
# handle = chandle
194+
# start index = 0
195+
# pointer to number of samples = ctypes.byref(cmaxSamples)
196+
# downsample ratio = 0
197+
# downsample ratio mode = PS5000A_RATIO_MODE_NONE
198+
# pointer to overflow = ctypes.byref(overflow))
199+
status["getValues"] = ps.ps5000aGetValues(chandle, 0, ctypes.byref(cmaxSamples), 0, 0, 0, ctypes.byref(overflow))
200+
assert_pico_ok(status["getValues"])
201+
202+
203+
# convert ADC counts data to mV
204+
adc2mVChAMax = adc2mV(bufferAMax, chARange, maxADC)
205+
adc2mVChBMax = adc2mV(bufferBMax, chBRange, maxADC)
206+
207+
# Create time data
208+
time = np.linspace(0, (cmaxSamples.value - 1) * timeIntervalns.value, cmaxSamples.value)
209+
210+
# plot data from channel A and B
211+
plt.plot(time, adc2mVChAMax[:])
212+
plt.plot(time, adc2mVChBMax[:])
213+
plt.xlabel('Time (ns)')
214+
plt.ylabel('Voltage (mV)')
215+
plt.show()
216+
217+
# Stop the scope
218+
# handle = chandle
219+
status["stop"] = ps.ps5000aStop(chandle)
220+
assert_pico_ok(status["stop"])
221+
222+
# Close unit Disconnect the scope
223+
# handle = chandle
224+
status["close"]=ps.ps5000aCloseUnit(chandle)
225+
assert_pico_ok(status["close"])
226+
227+
# display status returns
228+
print(status)

0 commit comments

Comments
 (0)