Skip to content

Commit c888938

Browse files
author
neil.hamilton
committed
Create streaming example for psospa devices
1 parent 6af6b5f commit c888938

File tree

1 file changed

+180
-0
lines changed

1 file changed

+180
-0
lines changed
Lines changed: 180 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,180 @@
1+
#
2+
# Copyright (C) 2024 Pico Technology Ltd. See LICENSE file for terms.
3+
#
4+
# PSOSPA STREAMING MODE EXAMPLE
5+
# This example opens a psospa driver device, sets up two channels then collects a streamed set of data.
6+
# The data from channel A is then plotted as mV against time in ns.
7+
8+
import ctypes
9+
import numpy as np
10+
from picosdk.psospa import psospa as ps
11+
from picosdk.PicoDeviceEnums import picoEnum as enums
12+
from picosdk.PicoDeviceStructs import picoStruct as structs
13+
import matplotlib.pyplot as plt
14+
from picosdk.functions import adc2mVV2, assert_pico_ok, mV2adcV2
15+
from picosdk.constants import PICO_STATUS
16+
import time
17+
18+
# Create chandle and status ready for use
19+
chandle = ctypes.c_int16()
20+
status = {}
21+
22+
# Open a psospa driver device
23+
# returns handle for future API functions
24+
resolution = enums.PICO_DEVICE_RESOLUTION["PICO_DR_8BIT"]
25+
status["openUnit"] = ps.psospaOpenUnit(ctypes.byref(chandle), None, resolution, None)
26+
assert_pico_ok(status["openUnit"])
27+
28+
# Set channel A on
29+
# handle = chandle
30+
channelA = enums.PICO_CHANNEL["PICO_CHANNEL_A"]
31+
coupling = enums.PICO_COUPLING["PICO_DC"]
32+
rangeMax = 2000000000 #nV
33+
rangeMin = -rangeMax #nV
34+
rangeType = 0 #probes.PICO_PROBE_RANGE_INFO["PICO_PROBE_NONE_NV"]
35+
analogueOffset = 0
36+
bandwidth = enums.PICO_BANDWIDTH_LIMITER["PICO_BW_FULL"]
37+
status["setChannelA"] = ps.psospaSetChannelOn(chandle, channelA, coupling, rangeMin, rangeMax, rangeType, analogueOffset, bandwidth)
38+
assert_pico_ok(status["setChannelA"])
39+
40+
channelB = enums.PICO_CHANNEL["PICO_CHANNEL_B"]
41+
status["setChannelB"] = ps.psospaSetChannelOn(chandle, channelB, coupling, rangeMin, rangeMax, rangeType, analogueOffset, bandwidth)
42+
assert_pico_ok(status["setChannelB"])
43+
44+
# set channel C-D off
45+
for x in range(2, 3, 1):
46+
channel = x
47+
status["setChannel", x] = ps.psospaSetChannelOff(chandle, channel)
48+
assert_pico_ok(status["setChannel", x])
49+
50+
# Set number of samples to be collected
51+
noOfPreTriggerSamples = 100000
52+
noOfPostTriggerSamples = 900000
53+
nSamples = noOfPostTriggerSamples + noOfPreTriggerSamples
54+
55+
# get max ADC value
56+
# handle = chandle
57+
minADC = ctypes.c_int16()
58+
maxADC = ctypes.c_int16()
59+
status["getAdcLimits"] = ps.psospaGetAdcLimits(chandle, resolution, ctypes.byref(minADC), ctypes.byref(maxADC))
60+
assert_pico_ok(status["getAdcLimits"])
61+
62+
# Set simple trigger on channel A, 1 V rising with 1 s autotrigger
63+
# handle = chandle
64+
# enable = 1
65+
source = channelA
66+
# threshold = 100 mV
67+
direction = enums.PICO_THRESHOLD_DIRECTION["PICO_RISING"]
68+
# delay = 0 s
69+
# autoTriggerMicroSeconds = 1000000 us
70+
status["setSimpleTrigger"] = ps.psospaSetSimpleTrigger(chandle, 1, source, (mV2adcV2(100,rangeMax,maxADC)), direction, 0, 1000000)
71+
assert_pico_ok(status["setSimpleTrigger"])
72+
73+
# create buffers
74+
maxBuffers = 10
75+
76+
bufferA = ((ctypes.c_int16 * nSamples) * 10)()
77+
bufferB = ((ctypes.c_int16 * nSamples) * 10)()
78+
79+
# Set data buffers
80+
# handle = chandle
81+
# channel = channelA
82+
# bufferMax = bufferAMax
83+
# bufferMin = bufferAMin
84+
# nSamples = nSamples
85+
dataType = enums.PICO_DATA_TYPE["PICO_INT16_T"]
86+
waveform = 0
87+
downSampleMode = enums.PICO_RATIO_MODE["PICO_RATIO_MODE_RAW"]
88+
clear = enums.PICO_ACTION["PICO_CLEAR_ALL"]
89+
add = enums.PICO_ACTION["PICO_ADD"]
90+
action = clear | add # PICO_ACTION["PICO_CLEAR_WAVEFORM_CLEAR_ALL"] | PICO_ACTION["PICO_ADD"]
91+
actionAdd = add
92+
status["setDataBuffersA"] = ps.psospaSetDataBuffer(chandle, channelA, ctypes.byref(bufferA[0]), nSamples, dataType,
93+
waveform, downSampleMode, action)
94+
assert_pico_ok(status["setDataBuffersA"])
95+
status["setDataBuffersB"] = ps.psospaSetDataBuffer(chandle, channelB, ctypes.byref(bufferB[0]), nSamples, dataType,
96+
waveform, downSampleMode, actionAdd)
97+
assert_pico_ok(status["setDataBuffersB"])
98+
99+
# Run streaming
100+
sampleInterval = ctypes.c_double(1)
101+
sampleIntervalTimeUnits = enums.PICO_TIME_UNITS["PICO_US"]
102+
autoStop = 0
103+
downSampleRatio = 1
104+
105+
status["runStreaming"] = ps.psospaRunStreaming(chandle, ctypes.byref(sampleInterval), sampleIntervalTimeUnits,
106+
noOfPreTriggerSamples, noOfPostTriggerSamples, autoStop,
107+
downSampleRatio, downSampleMode)
108+
assert_pico_ok(status["runStreaming"])
109+
110+
streamData = (structs.PICO_STREAMING_DATA_INFO * 2)()
111+
streamData[0] = structs.PICO_STREAMING_DATA_INFO(channelA, downSampleMode, dataType, 0, 0, 0, 0)
112+
streamData[1] = structs.PICO_STREAMING_DATA_INFO(channelB, downSampleMode, dataType, 0, 0, 0, 0)
113+
114+
streamTrigger = structs.PICO_STREAMING_DATA_TRIGGER_INFO(0, 0, 0)
115+
116+
count = 0
117+
118+
picoOk = PICO_STATUS["PICO_OK"]
119+
120+
collectedSamples = 0
121+
122+
while collectedSamples < (maxBuffers*nSamples):
123+
124+
status["getStreamingLatestValues"] = ps.psospaGetStreamingLatestValues(chandle, ctypes.byref(streamData), 1,
125+
ctypes.byref(streamTrigger))
126+
127+
if status["getStreamingLatestValues"] == picoOk:
128+
# do nothing
129+
time.sleep(0.01)
130+
else:
131+
count = count + 1
132+
if count < maxBuffers:
133+
status["setDataBufferA"] = ps.psospaSetDataBuffer(chandle, channelA, ctypes.byref(bufferA[count]),
134+
nSamples, dataType, waveform, downSampleMode, actionAdd)
135+
assert_pico_ok(status["setDataBufferA"])
136+
status["setDataBufferB"] = ps.psospaSetDataBuffer(chandle, channelB, ctypes.byref(bufferB[count]),
137+
nSamples, dataType, waveform, downSampleMode, actionAdd)
138+
assert_pico_ok(status["setDataBufferB"])
139+
print(count)
140+
141+
collectedSamples = collectedSamples + streamData[0].noOfSamples
142+
143+
# stop scope streaming
144+
status["stop"] = ps.psospaStop(chandle)
145+
assert_pico_ok(status["stop"])
146+
147+
# get total number of streamed data points
148+
noOfStreamedSamples=ctypes.c_uint64()
149+
status["noOfStreamedSamples"] = ps.psospaNoOfStreamingValues(chandle, ctypes.byref(noOfStreamedSamples))
150+
assert_pico_ok(status["noOfStreamedSamples"])
151+
152+
print("streaming finished")
153+
print("Number of samples collected during streaming")
154+
print(noOfStreamedSamples.value)
155+
156+
157+
# convert ADC counts data to mV
158+
bufferAmV = []
159+
for k in range (0, maxBuffers, 1):
160+
mvValues = adc2mVV2(bufferA[k], rangeMax, maxADC)
161+
bufferAmV.append(mvValues)
162+
163+
time = np.linspace(0, ((nSamples -1)*maxBuffers) * sampleInterval.value * 1000000, (nSamples*maxBuffers))
164+
startTime = 0
165+
endTime = nSamples
166+
# plot data
167+
for h in range (0, maxBuffers, 1):
168+
plt.plot(time[startTime:endTime],bufferAmV[h])
169+
startTime += nSamples
170+
endTime += nSamples
171+
plt.xlabel('Time (us)')
172+
plt.ylabel('Voltage (mV)')
173+
plt.show()
174+
175+
176+
# Close the scope
177+
status["closeunit"] = ps.psospaCloseUnit(chandle)
178+
assert_pico_ok(status["closeunit"])
179+
180+
print(status)

0 commit comments

Comments
 (0)