1+ #
2+ # Copyright (C) 2018-2024 Pico Technology Ltd. See LICENSE file for terms.
3+ #
4+ # PS5000 Series STREAMING MODE EXAMPLE
5+ # This example demonstrates how to call the ps5000 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 .ps5000 import ps5000 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 5000 Series device
20+ status ["openunit" ] = ps .ps5000OpenUnit (ctypes .byref (chandle ))
21+
22+ try :
23+ assert_pico_ok (status ["openunit" ])
24+ except : # PicoNotOkError:
25+
26+ powerStatus = status ["openunit" ]
27+
28+ if powerStatus == 286 :
29+ status ["changePowerSource" ] = ps .ps5000ChangePowerSource (chandle , powerStatus )
30+ elif powerStatus == 282 :
31+ status ["changePowerSource" ] = ps .ps5000ChangePowerSource (chandle , powerStatus )
32+ else :
33+ raise
34+
35+ assert_pico_ok (status ["changePowerSource" ])
36+
37+ enabled = 1
38+ disabled = 0
39+ coupling_type = 1
40+
41+ # Set up channel A
42+ # handle = chandle
43+ # channel = PS5000_CHANNEL_A = 0
44+ # enabled = 1
45+ # coupling type = PS5000A_DC = 1
46+ # range = PS5000A_2V = 7
47+ channel_range = ps .PS5000_RANGE ["PS5000_2V" ]
48+ status ["setChA" ] = ps .ps5000SetChannel (chandle ,
49+ ps .PS5000_CHANNEL ['PS5000_CHANNEL_A' ],
50+ enabled ,
51+ coupling_type ,
52+ channel_range )
53+ assert_pico_ok (status ["setChA" ])
54+
55+ # Set up channel B
56+ # handle = chandle
57+ # channel = PS5000_CHANNEL_B = 1
58+ # enabled = 1
59+ # coupling type = PS5000A_DC = 1
60+ # range = PS5000A_2V = 7
61+
62+ status ["setChB" ] = ps .ps5000SetChannel (chandle ,
63+ ps .PS5000_CHANNEL ['PS5000_CHANNEL_B' ],
64+ enabled ,
65+ coupling_type ,
66+ channel_range )
67+ assert_pico_ok (status ["setChB" ])
68+
69+ # Size of capture
70+ sizeOfOneBuffer = 10000
71+ numBuffersToCapture = 10
72+ totalSamples = sizeOfOneBuffer * numBuffersToCapture
73+
74+ # Create buffers ready for assigning pointers for data collection
75+ bufferAMax = np .zeros (shape = sizeOfOneBuffer , dtype = np .int16 )
76+ bufferBMax = np .zeros (shape = sizeOfOneBuffer , dtype = np .int16 )
77+
78+ memory_segment = 0
79+
80+ # Set data buffer location for data collection from channel A
81+ # handle = chandle
82+ # source = PS5000_CHANNEL_A = 0
83+ # pointer to buffer max = ctypes.byref(bufferAMax)
84+ # buffer length = maxSamples
85+ status ["setDataBuffersA" ] = ps .ps5000SetDataBuffers (chandle ,
86+ ps .PS5000_CHANNEL ['PS5000_CHANNEL_A' ],
87+ bufferAMax .ctypes .data_as (ctypes .POINTER (ctypes .c_int16 )),
88+ None ,
89+ sizeOfOneBuffer
90+ )
91+ assert_pico_ok (status ["setDataBuffersA" ])
92+
93+ # Set data buffer location for data collection from channel B
94+ # handle = chandle
95+ # source = PS5000_CHANNEL_B = 1
96+ # pointer to buffer max = ctypes.byref(bufferBMax)
97+ # buffer length = maxSamples
98+ status ["setDataBuffersB" ] = ps .ps5000SetDataBuffers (chandle ,
99+ ps .PS5000_CHANNEL ['PS5000_CHANNEL_B' ],
100+ bufferBMax .ctypes .data_as (ctypes .POINTER (ctypes .c_int16 )),
101+ None ,
102+ sizeOfOneBuffer )
103+ assert_pico_ok (status ["setDataBuffersB" ])
104+
105+ # Begin streaming mode:
106+ sampleInterval = ctypes .c_int32 (200 )
107+ sampleUnits = ps .PS5000_TIME_UNITS ['PS5000_US' ]
108+ # We are not triggering:
109+ maxPreTriggerSamples = 0
110+ autoStopOn = 1
111+ # No downsampling:
112+ downsampleRatio = 1
113+ status ["runStreaming" ] = ps .ps5000RunStreaming (chandle ,
114+ ctypes .byref (sampleInterval ),
115+ sampleUnits ,
116+ maxPreTriggerSamples ,
117+ totalSamples ,
118+ autoStopOn ,
119+ downsampleRatio ,
120+ sizeOfOneBuffer )
121+ assert_pico_ok (status ["runStreaming" ])
122+
123+ actualSampleInterval = sampleInterval .value
124+ actualSampleIntervalNs = actualSampleInterval * 1000
125+
126+ print ("Capturing at sample interval %s ns" % actualSampleIntervalNs )
127+
128+ # We need a big buffer, not registered with the driver, to keep our complete capture in.
129+ bufferCompleteA = np .zeros (shape = totalSamples , dtype = np .int16 )
130+ bufferCompleteB = np .zeros (shape = totalSamples , dtype = np .int16 )
131+ nextSample = 0
132+ autoStopOuter = False
133+ wasCalledBack = False
134+
135+
136+ def streaming_callback (handle , noOfSamples , startIndex , overflow , triggerAt , triggered , autoStop , param ):
137+ global nextSample , autoStopOuter , wasCalledBack
138+ wasCalledBack = True
139+ destEnd = nextSample + noOfSamples
140+ sourceEnd = startIndex + noOfSamples
141+ bufferCompleteA [nextSample :destEnd ] = bufferAMax [startIndex :sourceEnd ]
142+ bufferCompleteB [nextSample :destEnd ] = bufferBMax [startIndex :sourceEnd ]
143+ nextSample += noOfSamples
144+ if autoStop :
145+ autoStopOuter = True
146+
147+
148+ # Convert the python function into a C function pointer.
149+ cFuncPtr = ps .StreamingReadyType (streaming_callback )
150+
151+ # Fetch data from the driver in a loop, copying it out of the registered buffers and into our complete one.
152+ while nextSample < totalSamples and not autoStopOuter :
153+ wasCalledBack = False
154+ status ["getStreamingLastestValues" ] = ps .ps5000GetStreamingLatestValues (chandle , cFuncPtr , None )
155+ if not wasCalledBack :
156+ # If we weren't called back by the driver, this means no data is ready. Sleep for a short while before trying
157+ # again.
158+ time .sleep (0.01 )
159+
160+ print ("Done grabbing values." )
161+
162+ # Find maximum ADC count value
163+ # handle = chandle
164+ # pointer to value = ctypes.byref(maxADC)
165+ maxADC = ctypes .c_int16 (32767 )
166+ #status["maximumValue"] = ps.ps5000MaximumValue(chandle, ctypes.byref(maxADC))
167+ #assert_pico_ok(status["maximumValue"])
168+
169+ # Convert ADC counts data to mV
170+ adc2mVChAMax = adc2mV (bufferCompleteA , channel_range , maxADC )
171+ adc2mVChBMax = adc2mV (bufferCompleteB , channel_range , maxADC )
172+
173+ # Create time data
174+ time = np .linspace (0 , (totalSamples - 1 ) * actualSampleIntervalNs , totalSamples )
175+
176+ # Plot data from channel A and B
177+ plt .plot (time , adc2mVChAMax [:])
178+ plt .plot (time , adc2mVChBMax [:])
179+ plt .xlabel ('Time (ns)' )
180+ plt .ylabel ('Voltage (mV)' )
181+ plt .show ()
182+
183+ # Stop the scope
184+ # handle = chandle
185+ status ["stop" ] = ps .ps5000Stop (chandle )
186+ assert_pico_ok (status ["stop" ])
187+
188+ # Disconnect the scope
189+ # handle = chandle
190+ status ["close" ] = ps .ps5000CloseUnit (chandle )
191+ assert_pico_ok (status ["close" ])
192+
193+ # Display status returns
194+ print (status )
0 commit comments