Skip to content

Commit fa7d9cf

Browse files
author
neil.hamilton
committed
add ps5000aExamples/ps5000aStreamingExample.py
1 parent c6a93f2 commit fa7d9cf

File tree

1 file changed

+212
-0
lines changed

1 file changed

+212
-0
lines changed
Lines changed: 212 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,212 @@
1+
#
2+
# Copyright (C) 2018-2019 Pico Technology Ltd. See LICENSE file for terms.
3+
#
4+
# PS2000 Series (A API) STREAMING MODE EXAMPLE
5+
# This example demonstrates how to call the ps5000a driver API functions in order to open a device, setup 2 channels and collects streamed data (1 buffer).
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
13+
import time
14+
15+
# Create chandle and status ready for use
16+
chandle = ctypes.c_int16()
17+
status = {}
18+
19+
# Open PicoScope 2000 Series device
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+
41+
enabled = 1
42+
disabled = 0
43+
analogue_offset = 0.0
44+
45+
# Set up channel A
46+
# handle = chandle
47+
# channel = PS5000A_CHANNEL_A = 0
48+
# enabled = 1
49+
# coupling type = PS5000A_DC = 1
50+
# range = PS5000A_2V = 7
51+
# analogue offset = 0 V
52+
channel_range = ps.PS5000A_RANGE['PS5000A_2V']
53+
status["setChA"] = ps.ps5000aSetChannel(chandle,
54+
ps.PS5000A_CHANNEL['PS5000A_CHANNEL_A'],
55+
enabled,
56+
ps.PS5000A_COUPLING['PS5000A_DC'],
57+
channel_range,
58+
analogue_offset)
59+
assert_pico_ok(status["setChA"])
60+
61+
# Set up channel B
62+
# handle = chandle
63+
# channel = PS5000A_CHANNEL_B = 1
64+
# enabled = 1
65+
# coupling type = PS5000A_DC = 1
66+
# range = PS5000A_2V = 7
67+
# analogue offset = 0 V
68+
status["setChB"] = ps.ps5000aSetChannel(chandle,
69+
ps.PS5000A_CHANNEL['PS5000A_CHANNEL_B'],
70+
enabled,
71+
ps.PS5000A_COUPLING['PS5000A_DC'],
72+
channel_range,
73+
analogue_offset)
74+
assert_pico_ok(status["setChB"])
75+
76+
# Size of capture
77+
sizeOfOneBuffer = 500
78+
numBuffersToCapture = 10
79+
80+
totalSamples = sizeOfOneBuffer * numBuffersToCapture
81+
82+
# Create buffers ready for assigning pointers for data collection
83+
bufferAMax = np.zeros(shape=sizeOfOneBuffer, dtype=np.int16)
84+
bufferBMax = np.zeros(shape=sizeOfOneBuffer, dtype=np.int16)
85+
86+
memory_segment = 0
87+
88+
# Set data buffer location for data collection from channel A
89+
# handle = chandle
90+
# source = PS5000A_CHANNEL_A = 0
91+
# pointer to buffer max = ctypes.byref(bufferAMax)
92+
# pointer to buffer min = ctypes.byref(bufferAMin)
93+
# buffer length = maxSamples
94+
# segment index = 0
95+
# ratio mode = PS5000A_RATIO_MODE_NONE = 0
96+
status["setDataBuffersA"] = ps.ps5000aSetDataBuffers(chandle,
97+
ps.PS5000A_CHANNEL['PS5000A_CHANNEL_A'],
98+
bufferAMax.ctypes.data_as(ctypes.POINTER(ctypes.c_int16)),
99+
None,
100+
sizeOfOneBuffer,
101+
memory_segment,
102+
ps.PS5000A_RATIO_MODE['PS5000A_RATIO_MODE_NONE'])
103+
assert_pico_ok(status["setDataBuffersA"])
104+
105+
# Set data buffer location for data collection from channel B
106+
# handle = chandle
107+
# source = PS5000A_CHANNEL_B = 1
108+
# pointer to buffer max = ctypes.byref(bufferBMax)
109+
# pointer to buffer min = ctypes.byref(bufferBMin)
110+
# buffer length = maxSamples
111+
# segment index = 0
112+
# ratio mode = PS5000A_RATIO_MODE_NONE = 0
113+
status["setDataBuffersB"] = ps.ps5000aSetDataBuffers(chandle,
114+
ps.PS5000A_CHANNEL['PS5000A_CHANNEL_B'],
115+
bufferBMax.ctypes.data_as(ctypes.POINTER(ctypes.c_int16)),
116+
None,
117+
sizeOfOneBuffer,
118+
memory_segment,
119+
ps.PS5000A_RATIO_MODE['PS5000A_RATIO_MODE_NONE'])
120+
assert_pico_ok(status["setDataBuffersB"])
121+
122+
# Begin streaming mode:
123+
sampleInterval = ctypes.c_int32(250)
124+
sampleUnits = ps.PS5000A_TIME_UNITS['PS5000A_US']
125+
# We are not triggering:
126+
maxPreTriggerSamples = 0
127+
autoStopOn = 1
128+
# No downsampling:
129+
downsampleRatio = 1
130+
status["runStreaming"] = ps.ps5000aRunStreaming(chandle,
131+
ctypes.byref(sampleInterval),
132+
sampleUnits,
133+
maxPreTriggerSamples,
134+
totalSamples,
135+
autoStopOn,
136+
downsampleRatio,
137+
ps.PS5000A_RATIO_MODE['PS5000A_RATIO_MODE_NONE'],
138+
sizeOfOneBuffer)
139+
assert_pico_ok(status["runStreaming"])
140+
141+
actualSampleInterval = sampleInterval.value
142+
actualSampleIntervalNs = actualSampleInterval * 1000
143+
144+
print("Capturing at sample interval %s ns" % actualSampleIntervalNs)
145+
146+
# We need a big buffer, not registered with the driver, to keep our complete capture in.
147+
bufferCompleteA = np.zeros(shape=totalSamples, dtype=np.int16)
148+
bufferCompleteB = np.zeros(shape=totalSamples, dtype=np.int16)
149+
nextSample = 0
150+
autoStopOuter = False
151+
wasCalledBack = False
152+
153+
154+
def streaming_callback(handle, noOfSamples, startIndex, overflow, triggerAt, triggered, autoStop, param):
155+
global nextSample, autoStopOuter, wasCalledBack
156+
wasCalledBack = True
157+
destEnd = nextSample + noOfSamples
158+
sourceEnd = startIndex + noOfSamples
159+
bufferCompleteA[nextSample:destEnd] = bufferAMax[startIndex:sourceEnd]
160+
bufferCompleteB[nextSample:destEnd] = bufferBMax[startIndex:sourceEnd]
161+
nextSample += noOfSamples
162+
if autoStop:
163+
autoStopOuter = True
164+
165+
166+
# Convert the python function into a C function pointer.
167+
cFuncPtr = ps.StreamingReadyType(streaming_callback)
168+
169+
# Fetch data from the driver in a loop, copying it out of the registered buffers and into our complete one.
170+
while nextSample < totalSamples and not autoStopOuter:
171+
wasCalledBack = False
172+
status["getStreamingLastestValues"] = ps.ps5000aGetStreamingLatestValues(chandle, cFuncPtr, None)
173+
if not wasCalledBack:
174+
# If we weren't called back by the driver, this means no data is ready. Sleep for a short while before trying
175+
# again.
176+
time.sleep(0.01)
177+
178+
print("Done grabbing values.")
179+
180+
# Find maximum ADC count value
181+
# handle = chandle
182+
# pointer to value = ctypes.byref(maxADC)
183+
maxADC = ctypes.c_int16()
184+
status["maximumValue"] = ps.ps5000aMaximumValue(chandle, ctypes.byref(maxADC))
185+
assert_pico_ok(status["maximumValue"])
186+
187+
# Convert ADC counts data to mV
188+
adc2mVChAMax = adc2mV(bufferCompleteA, channel_range, maxADC)
189+
adc2mVChBMax = adc2mV(bufferCompleteB, channel_range, maxADC)
190+
191+
# Create time data
192+
time = np.linspace(0, (totalSamples) * actualSampleIntervalNs, totalSamples)
193+
194+
# Plot data from channel A and B
195+
plt.plot(time, adc2mVChAMax[:])
196+
plt.plot(time, adc2mVChBMax[:])
197+
plt.xlabel('Time (ns)')
198+
plt.ylabel('Voltage (mV)')
199+
plt.show()
200+
201+
# Stop the scope
202+
# handle = chandle
203+
status["stop"] = ps.ps5000aStop(chandle)
204+
assert_pico_ok(status["stop"])
205+
206+
# Disconnect the scope
207+
# handle = chandle
208+
status["close"] = ps.ps5000aCloseUnit(chandle)
209+
assert_pico_ok(status["close"])
210+
211+
# Display status returns
212+
print(status)

0 commit comments

Comments
 (0)