Skip to content

Commit 6d40639

Browse files
author
neil.hamilton
committed
Add advanced trigger examples
1 parent 5904d6d commit 6d40639

File tree

6 files changed

+1123
-0
lines changed

6 files changed

+1123
-0
lines changed
Lines changed: 193 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,193 @@
1+
from ctypes import byref, c_int16, c_int32, sizeof, Structure, c_uint16
2+
from time import sleep
3+
4+
import numpy as np
5+
from picosdk.ps2000 import ps2000
6+
from picosdk.functions import assert_pico2000_ok, adc2mV
7+
from picosdk.PicoDeviceEnums import picoEnum
8+
9+
import matplotlib.pyplot as plt
10+
11+
SAMPLES = 2000
12+
OVERSAMPLING = 1
13+
PRESAMPLE = 80.0
14+
ADC_THRESHOLD = 1000
15+
16+
THRESHOLD_DIRECTION = {
17+
'PS2000_ABOVE': 0,
18+
'PS2000_BELOW': 1,
19+
'PS2000_ADV_RISING': 2,
20+
'PS2000_ADV_FALLING': 3,
21+
'PS2000_ADV_RISING_OR_FALLING': 4,
22+
'PS2000_INSIDE': 0,
23+
'PS2000_OUTSIDE': 1,
24+
'PS2000_ENTER': 2,
25+
'PS2000_EXIT': 3,
26+
'PS2000_ENTER_OR_EXIT': 4,
27+
'PS2000_ADV_NONE': 2,
28+
}
29+
30+
31+
class TriggerConditions(Structure):
32+
_fields_ = [
33+
('channelA', c_int32),
34+
('channelB', c_int32),
35+
('channelC', c_int32),
36+
('channelD', c_int32),
37+
('external', c_int32),
38+
('pulseWidthQualifier', c_int32),
39+
]
40+
41+
42+
class PwqConditions(Structure):
43+
_fields_ = [
44+
('channelA', c_int32),
45+
('channelB', c_int32),
46+
('channelC', c_int32),
47+
('channelD', c_int32),
48+
('external', c_int32),
49+
]
50+
51+
52+
class TriggerChannelProperties(Structure):
53+
_fields_ = [
54+
("thresholdMajor", c_int16),
55+
("thresholdMinor", c_int16),
56+
("hysteresis", c_uint16),
57+
("channel", c_int16),
58+
("thresholdMode", c_int16),
59+
]
60+
61+
62+
def get_timebase(device, wanted_time_interval):
63+
current_timebase = 1
64+
65+
old_time_interval = None
66+
time_interval = c_int32(0)
67+
time_units = c_int16()
68+
max_samples = c_int32()
69+
70+
while ps2000.ps2000_get_timebase(
71+
device.handle,
72+
current_timebase,
73+
SAMPLES,
74+
byref(time_interval),
75+
byref(time_units),
76+
1,
77+
byref(max_samples)) == 0 \
78+
or time_interval.value < wanted_time_interval:
79+
80+
current_timebase += 1
81+
old_time_interval = time_interval.value
82+
83+
if current_timebase.bit_length() > sizeof(c_int16) * 8:
84+
raise Exception('No appropriate timebase was identifiable')
85+
86+
return current_timebase - 1, old_time_interval
87+
88+
89+
with ps2000.open_unit() as device:
90+
print('Device info: {}'.format(device.info))
91+
92+
res = ps2000.ps2000_set_channel(
93+
device.handle,
94+
picoEnum.PICO_CHANNEL['PICO_CHANNEL_A'],
95+
True,
96+
picoEnum.PICO_COUPLING['PICO_DC'],
97+
ps2000.PS2000_VOLTAGE_RANGE['PS2000_500MV']
98+
)
99+
assert_pico2000_ok(res)
100+
101+
trigger_conditions = TriggerConditions(0, 0, 0, 0, 0, 1)
102+
103+
res = ps2000.ps2000SetAdvTriggerChannelConditions(
104+
device.handle,
105+
byref(trigger_conditions),
106+
1
107+
)
108+
assert_pico2000_ok(res)
109+
110+
res = ps2000.ps2000SetAdvTriggerDelay(device.handle, 0, -PRESAMPLE)
111+
assert_pico2000_ok(res)
112+
113+
res = ps2000.ps2000SetAdvTriggerChannelDirections(
114+
device.handle,
115+
THRESHOLD_DIRECTION['PS2000_ADV_RISING_OR_FALLING'],
116+
THRESHOLD_DIRECTION['PS2000_ADV_NONE'],
117+
THRESHOLD_DIRECTION['PS2000_ADV_NONE'],
118+
THRESHOLD_DIRECTION['PS2000_ADV_NONE'],
119+
THRESHOLD_DIRECTION['PS2000_ADV_NONE']
120+
)
121+
assert_pico2000_ok(res)
122+
123+
trigger_properties = TriggerChannelProperties(
124+
ADC_THRESHOLD,
125+
-ADC_THRESHOLD,
126+
0,
127+
ps2000.PS2000_CHANNEL['PS2000_CHANNEL_A'],
128+
picoEnum.PICO_THRESHOLD_MODE['PICO_WINDOW']
129+
)
130+
131+
res = ps2000.ps2000SetAdvTriggerChannelProperties(device.handle, byref(trigger_properties), 1, 0)
132+
assert_pico2000_ok(res)
133+
134+
pwq_conditions = PwqConditions(1, 0, 0, 0, 0)
135+
136+
res = ps2000.ps2000SetPulseWidthQualifier(
137+
device.handle,
138+
byref(pwq_conditions),
139+
1,
140+
THRESHOLD_DIRECTION['PS2000_ENTER'],
141+
200,
142+
0,
143+
picoEnum.PICO_PULSE_WIDTH_TYPE['PICO_PW_TYPE_GREATER_THAN']
144+
)
145+
assert_pico2000_ok(res)
146+
147+
# calculate timebase
148+
timebase_a, interval = get_timebase(device, 20_000)
149+
150+
collection_time = c_int32()
151+
152+
fig, ax = plt.subplots()
153+
ax.set_xlabel('time/ms')
154+
ax.set_ylabel('ADC counts')
155+
156+
res = ps2000.ps2000_run_block(
157+
device.handle,
158+
SAMPLES,
159+
timebase_a,
160+
OVERSAMPLING,
161+
byref(collection_time)
162+
)
163+
assert_pico2000_ok(res)
164+
165+
# wait for ready signal
166+
while ps2000.ps2000_ready(device.handle) == 0:
167+
sleep(0.1)
168+
169+
times = (c_int32 * SAMPLES)()
170+
171+
buffer_a = (c_int16 * SAMPLES)()
172+
173+
res = ps2000.ps2000_get_times_and_values(
174+
device.handle,
175+
byref(times),
176+
byref(buffer_a),
177+
None,
178+
None,
179+
None,
180+
None,
181+
2,
182+
SAMPLES,
183+
)
184+
assert_pico2000_ok(res)
185+
186+
channel_a_mv = adc2mV(buffer_a, ps2000.PS2000_VOLTAGE_RANGE['PS2000_50MV'], c_int16(32767))
187+
188+
ax.plot(list(map(lambda x: x * 1e-6, times[:])), buffer_a[:])
189+
ax.axvline(np.percentile(list(map(lambda x: x * 1e-6, times[:])), PRESAMPLE), color='red', linestyle='dotted')
190+
191+
ps2000.ps2000_stop(device.handle)
192+
193+
plt.show()
Lines changed: 186 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,186 @@
1+
from ctypes import byref, c_int16, c_int32, sizeof, Structure, c_uint16
2+
from time import sleep
3+
4+
import numpy as np
5+
from picosdk.ps2000 import ps2000
6+
from picosdk.functions import assert_pico2000_ok, adc2mV
7+
from picosdk.PicoDeviceEnums import picoEnum
8+
9+
import matplotlib.pyplot as plt
10+
11+
SAMPLES = 2000
12+
OVERSAMPLING = 1
13+
PRESAMPLE = 80.0
14+
15+
THRESHOLD_DIRECTION = {
16+
'PS2000_ABOVE': 0,
17+
'PS2000_BELOW': 1,
18+
'PS2000_ADV_RISING': 2,
19+
'PS2000_ADV_FALLING': 3,
20+
'PS2000_ADV_RISING_OR_FALLING': 4,
21+
'PS2000_INSIDE': 0,
22+
'PS2000_OUTSIDE': 1,
23+
'PS2000_ENTER': 2,
24+
'PS2000_EXIT': 3,
25+
'PS2000_ENTER_OR_EXIT': 4,
26+
'PS2000_ADV_NONE': 2,
27+
}
28+
29+
30+
class TriggerConditions(Structure):
31+
_fields_ = [
32+
('channelA', c_int32),
33+
('channelB', c_int32),
34+
('channelC', c_int32),
35+
('channelD', c_int32),
36+
('external', c_int32),
37+
('pulseWidthQualifier', c_int32),
38+
]
39+
40+
41+
class PwqConditions(Structure):
42+
_fields_ = [
43+
('channelA', c_int32),
44+
('channelB', c_int32),
45+
('channelC', c_int32),
46+
('channelD', c_int32),
47+
('external', c_int32),
48+
]
49+
50+
51+
class TriggerChannelProperties(Structure):
52+
_fields_ = [
53+
("thresholdMajor", c_int16),
54+
("thresholdMinor", c_int16),
55+
("hysteresis", c_uint16),
56+
("channel", c_int16),
57+
("thresholdMode", c_int16),
58+
]
59+
60+
61+
def get_timebase(device, wanted_time_interval):
62+
current_timebase = 1
63+
64+
old_time_interval = None
65+
time_interval = c_int32(0)
66+
time_units = c_int16()
67+
max_samples = c_int32()
68+
69+
while ps2000.ps2000_get_timebase(
70+
device.handle,
71+
current_timebase,
72+
SAMPLES,
73+
byref(time_interval),
74+
byref(time_units),
75+
1,
76+
byref(max_samples)) == 0 \
77+
or time_interval.value < wanted_time_interval:
78+
79+
current_timebase += 1
80+
old_time_interval = time_interval.value
81+
82+
if current_timebase.bit_length() > sizeof(c_int16) * 8:
83+
raise Exception('No appropriate timebase was identifiable')
84+
85+
return current_timebase - 1, old_time_interval
86+
87+
88+
with ps2000.open_unit() as device:
89+
print('Device info: {}'.format(device.info))
90+
91+
res = ps2000.ps2000_set_channel(
92+
device.handle,
93+
picoEnum.PICO_CHANNEL['PICO_CHANNEL_A'],
94+
True,
95+
picoEnum.PICO_COUPLING['PICO_DC'],
96+
ps2000.PS2000_VOLTAGE_RANGE['PS2000_500MV']
97+
)
98+
assert_pico2000_ok(res)
99+
100+
trigger_conditions = TriggerConditions(1, 0, 0, 0, 0, 1)
101+
102+
res = ps2000.ps2000SetAdvTriggerChannelConditions(device.handle, byref(trigger_conditions), 1)
103+
assert_pico2000_ok(res)
104+
105+
res = ps2000.ps2000SetAdvTriggerDelay(device.handle, 0, -PRESAMPLE)
106+
assert_pico2000_ok(res)
107+
108+
res = ps2000.ps2000SetAdvTriggerChannelDirections(
109+
device.handle,
110+
THRESHOLD_DIRECTION['PS2000_ADV_RISING_OR_FALLING'],
111+
THRESHOLD_DIRECTION['PS2000_ADV_NONE'],
112+
THRESHOLD_DIRECTION['PS2000_ADV_NONE'],
113+
THRESHOLD_DIRECTION['PS2000_ADV_NONE'],
114+
THRESHOLD_DIRECTION['PS2000_ADV_NONE']
115+
)
116+
assert_pico2000_ok(res)
117+
118+
trigger_properties = TriggerChannelProperties(
119+
32000,
120+
2048,
121+
328,
122+
ps2000.PS2000_CHANNEL['PS2000_CHANNEL_A'],
123+
picoEnum.PICO_THRESHOLD_MODE['PICO_WINDOW']
124+
)
125+
126+
res = ps2000.ps2000SetAdvTriggerChannelProperties(device.handle, byref(trigger_properties), 1, 0)
127+
assert_pico2000_ok(res)
128+
129+
pwq_conditions = PwqConditions(1, 0, 0, 0, 0)
130+
131+
res = ps2000.ps2000SetPulseWidthQualifier(
132+
device.handle,
133+
byref(pwq_conditions),
134+
1,
135+
THRESHOLD_DIRECTION['PS2000_ENTER_OR_EXIT'],
136+
600,
137+
0,
138+
picoEnum.PICO_PULSE_WIDTH_TYPE['PICO_PW_TYPE_GREATER_THAN']
139+
)
140+
assert_pico2000_ok(res)
141+
142+
timebase_a, interval = get_timebase(device, 4_000)
143+
144+
collection_time = c_int32()
145+
146+
fig, ax = plt.subplots()
147+
ax.set_xlabel('time/ms')
148+
ax.set_ylabel('ADC counts')
149+
150+
res = ps2000.ps2000_run_block(
151+
device.handle,
152+
SAMPLES,
153+
timebase_a,
154+
OVERSAMPLING,
155+
byref(collection_time)
156+
)
157+
assert_pico2000_ok(res)
158+
159+
while ps2000.ps2000_ready(device.handle) == 0:
160+
sleep(0.1)
161+
162+
times = (c_int32 * SAMPLES)()
163+
164+
buffer_a = (c_int16 * SAMPLES)()
165+
166+
res = ps2000.ps2000_get_times_and_values(
167+
device.handle,
168+
byref(times),
169+
byref(buffer_a),
170+
None,
171+
None,
172+
None,
173+
None,
174+
2,
175+
SAMPLES,
176+
)
177+
assert_pico2000_ok(res)
178+
179+
channel_a_mv = adc2mV(buffer_a, ps2000.PS2000_VOLTAGE_RANGE['PS2000_50MV'], c_int16(32767))
180+
181+
ax.plot(list(map(lambda x: x * 1e-6, times[:])), buffer_a[:])
182+
ax.axvline(np.percentile(list(map(lambda x: x * 1e-6, times[:])), PRESAMPLE), color='red', linestyle='dotted')
183+
184+
ps2000.ps2000_stop(device.handle)
185+
186+
plt.show()

0 commit comments

Comments
 (0)