1+ #
2+ # Copyright (C) 2024 Pico Technology Ltd. See LICENSE file for terms.
3+ #
4+ # PSOSPA BLOCK MODE EXAMPLE
5+ # This example opens a psospa 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 .psospa import psospa as ps
11+ from picosdk .PicoDeviceEnums import picoEnum as enums
12+ from picosdk .PicoDeviceStructs import picoStruct as structs
13+ # from picosdk.PicoConnectProbes import picoConnectProbes as probes
14+ import matplotlib .pyplot as plt
15+ from picosdk .functions import adc2mVV2 , mV2adcV2 , assert_pico_ok
16+
17+ # Create chandle and status ready for use
18+ chandle = ctypes .c_int16 ()
19+ status = {}
20+
21+ # Open a psospa driver device
22+ # returns handle for future API functions
23+ resolution = enums .PICO_DEVICE_RESOLUTION ["PICO_DR_8BIT" ]
24+ status ["openUnit" ] = ps .psospaOpenUnit (ctypes .byref (chandle ), None , resolution , None )
25+ assert_pico_ok (status ["openUnit" ])
26+
27+ # Set channel A on
28+ # handle = chandle
29+ channelA = enums .PICO_CHANNEL ["PICO_CHANNEL_A" ]
30+ coupling = enums .PICO_COUPLING ["PICO_DC" ]
31+ rangeMax = 2000000000 #nV
32+ rangeMin = - rangeMax #nV
33+ rangeType = 0 #probes.PICO_PROBE_RANGE_INFO["PICO_PROBE_NONE_NV"]
34+ analogueOffset = 0
35+ bandwidth = enums .PICO_BANDWIDTH_LIMITER ["PICO_BW_FULL" ]
36+ status ["setChannelA" ] = ps .psospaSetChannelOn (chandle , channelA , coupling , rangeMin , rangeMax , rangeType , analogueOffset , bandwidth )
37+ assert_pico_ok (status ["setChannelA" ])
38+
39+ # set channel B-D off
40+ for x in range (1 , 3 , 1 ):
41+ channel = x
42+ status ["setChannel" ,x ] = ps .psospaSetChannelOff (chandle ,channel )
43+ assert_pico_ok (status ["setChannel" ,x ])
44+
45+ # get max ADC value
46+ # handle = chandle
47+ minADC = ctypes .c_int16 ()
48+ maxADC = ctypes .c_int16 ()
49+ status ["getAdcLimits" ] = ps .psospaGetAdcLimits (chandle , resolution , ctypes .byref (minADC ), ctypes .byref (maxADC ))
50+ assert_pico_ok (status ["getAdcLimits" ])
51+
52+ # Set simple trigger on channel A, 1 V rising with 1 s autotrigger
53+ # handle = chandle
54+ # enable = 1
55+ source = channelA
56+ # threshold = 100 mV
57+ direction = enums .PICO_THRESHOLD_DIRECTION ["PICO_RISING" ]
58+ # delay = 0 s
59+ # autoTriggerMicroSeconds = 1000000 us
60+ status ["setSimpleTrigger" ] = ps .psospaSetSimpleTrigger (chandle , 1 , source , mV2adcV2 (100 ,rangeMax ,maxADC ), direction , 0 , 1000000 )
61+ assert_pico_ok (status ["setSimpleTrigger" ])
62+
63+ # Get fastest available timebase
64+ # handle = chandle
65+ enabledChannelFlags = enums .PICO_CHANNEL_FLAGS ["PICO_CHANNEL_A_FLAGS" ]
66+ timebase = ctypes .c_uint32 (0 )
67+ timeInterval = ctypes .c_double (0 )
68+ # resolution = resolution
69+ status ["getMinimumTimebaseStateless" ] = ps .psospaGetMinimumTimebaseStateless (chandle , enabledChannelFlags , ctypes .byref (timebase ), ctypes .byref (timeInterval ), resolution )
70+ print ("timebase = " , timebase .value )
71+ print ("sample interval =" , timeInterval .value , "s" )
72+
73+ # Set number of samples to be collected
74+ noOfPreTriggerSamples = 500000
75+ noOfPostTriggerSamples = 1000000
76+ nSamples = noOfPostTriggerSamples + noOfPreTriggerSamples
77+
78+ # Create buffers
79+ bufferAMax = (ctypes .c_int16 * nSamples )()
80+ bufferAMin = (ctypes .c_int16 * nSamples )() # used for downsampling which isn't in the scope of this example
81+
82+ # Set data buffers
83+ # handle = chandle
84+ # channel = channelA
85+ # bufferMax = bufferAMax
86+ # bufferMin = bufferAMin
87+ # nSamples = nSamples
88+ dataType = enums .PICO_DATA_TYPE ["PICO_INT16_T" ]
89+ waveform = 0
90+ downSampleMode = enums .PICO_RATIO_MODE ["PICO_RATIO_MODE_RAW" ]
91+ clear = enums .PICO_ACTION ["PICO_CLEAR_ALL" ]
92+ add = enums .PICO_ACTION ["PICO_ADD" ]
93+ action = clear | add # PICO_ACTION["PICO_CLEAR_WAVEFORM_CLEAR_ALL"] | PICO_ACTION["PICO_ADD"]
94+ status ["setDataBuffers" ] = ps .psospaSetDataBuffers (chandle , channelA , ctypes .byref (bufferAMax ), ctypes .byref (bufferAMin ), nSamples , dataType , waveform , downSampleMode , action )
95+ assert_pico_ok (status ["setDataBuffers" ])
96+
97+ # Run block capture
98+ # handle = chandle
99+ # timebase = timebase
100+ timeIndisposedMs = ctypes .c_double (0 )
101+ # segmentIndex = 0
102+ # lpReady = None Using IsReady rather than a callback
103+ # pParameter = None
104+ status ["runBlock" ] = ps .psospaRunBlock (chandle , noOfPreTriggerSamples , noOfPostTriggerSamples , timebase , ctypes .byref (timeIndisposedMs ), 0 , None , None )
105+ assert_pico_ok (status ["runBlock" ])
106+
107+ # Check for data collection to finish using psospaIsReady
108+ ready = ctypes .c_int16 (0 )
109+ check = ctypes .c_int16 (0 )
110+ while ready .value == check .value :
111+ status ["isReady" ] = ps .psospaIsReady (chandle , ctypes .byref (ready ))
112+
113+ # Get data from scope
114+ # handle = chandle
115+ # startIndex = 0
116+ noOfSamples = ctypes .c_uint64 (nSamples )
117+ # downSampleRatio = 1
118+ # segmentIndex = 0
119+ overflow = ctypes .c_int16 (0 )
120+ status ["getValues" ] = ps .psospaGetValues (chandle , 0 , ctypes .byref (noOfSamples ), 1 , downSampleMode , 0 , ctypes .byref (overflow ))
121+ assert_pico_ok (status ["getValues" ])
122+
123+
124+
125+ # # convert ADC counts data to mV
126+ adc2mVChAMax = adc2mVV2 (bufferAMax , rangeMax , maxADC )
127+
128+ # Create time data
129+ time = np .linspace (0 , (nSamples - 1 ) * timeInterval .value * 1000000000 , nSamples )
130+
131+ # plot data from channel A and B
132+ plt .plot (time , bufferAMax [:])
133+ plt .xlabel ('Time (ns)' )
134+ plt .ylabel ('Voltage (mV)' )
135+ plt .show ()
136+
137+ # Close the psospa driver device
138+ status ["closeUnit" ] = ps .psospaCloseUnit (chandle )
139+ assert_pico_ok (status ["closeUnit" ])
140+
141+ print (status )
0 commit comments