1+ #
2+ # Copyright (C) 2018-2022 Pico Technology Ltd. See LICENSE file for terms.
3+ #
4+ # PicoScope 3000 Series (A API) MSO Block Mode Triggered Example
5+ # This example demonstrates how to use the PicoScope 3000 Series (ps5000a) driver API functions in order to do the
6+ # following:
7+ #
8+ # Open a connection to a PicoScope 3000 Series MSO device
9+ # Setup a digital port
10+ # Set up a digital trigger
11+ # Collect a block of data
12+ # Plot data
13+
14+ import ctypes
15+ from picosdk .ps5000a import ps5000a as ps
16+ from picosdk .functions import splitMSODataFast , assert_pico_ok
17+ import numpy as np
18+ import matplotlib .pyplot as plt
19+
20+ # Gives the device a handle
21+ status = {}
22+ chandle = ctypes .c_int16 ()
23+
24+ # Opens the device/s
25+ status ["openunit" ] = ps .ps5000aOpenUnit (ctypes .byref (chandle ), None , ps .PS5000A_DEVICE_RESOLUTION ["PS5000A_DR_8BIT" ])
26+
27+ try :
28+ assert_pico_ok (status ["openunit" ])
29+ except :
30+ # powerstate becomes the status number of openunit
31+ powerstate = status ["openunit" ]
32+
33+ # If powerstate is the same as 282 then it will run this if statement
34+ if powerstate == 282 :
35+ # Changes the power input to "PICO_POWER_SUPPLY_NOT_CONNECTED"
36+ status ["ChangePowerSource" ] = ps .ps5000aChangePowerSource (chandle , 282 )
37+ # If the powerstate is the same as 286 then it will run this if statement
38+ elif powerstate == 286 :
39+ # Changes the power input to "PICO_USB3_0_DEVICE_NON_USB3_0_PORT"
40+ status ["ChangePowerSource" ] = ps .ps5000aChangePowerSource (chandle , 286 )
41+ else :
42+ raise
43+
44+ assert_pico_ok (status ["ChangePowerSource" ])
45+
46+
47+ digital_port0 = ps .PS5000A_CHANNEL ["PS5000A_DIGITAL_PORT0" ]
48+ # Set up digital port
49+ # handle = chandle
50+ # channel = ps5000a_DIGITAL_PORT0 = 0x80
51+ # enabled = 1
52+ # logicLevel = 10000
53+ status ["SetDigitalPort" ] = ps .ps5000aSetDigitalPort ( chandle , digital_port0 , 1 , 10000 )
54+ assert_pico_ok (status ["SetDigitalPort" ])
55+
56+ #Set a trigger on digital channel
57+
58+
59+ # Set the number of sample to be collected
60+ preTriggerSamples = 2500
61+ postTriggerSamples = 2500
62+ totalSamples = preTriggerSamples + postTriggerSamples
63+
64+ # Gets timebase information
65+ # handle = chandle
66+ # timebase = 1252
67+ # Nosample = totalSamples
68+ # TimeIntervalNanoseconds = ctypes.byref(timeIntervalNs)
69+ # MaxSamples = ctypes.byref(returnedMaxSamples)
70+ # Segement index = 0
71+ timebase = 1252
72+ timeIntervalNs = ctypes .c_float ()
73+ returnedMaxSamples = ctypes .c_int16 ()
74+ status ["GetTimebase" ] = ps .ps5000aGetTimebase2 (chandle ,
75+ timebase ,
76+ totalSamples ,
77+ ctypes .byref (timeIntervalNs ),
78+ ctypes .byref (returnedMaxSamples ),
79+ 0 )
80+ assert_pico_ok (status ["GetTimebase" ])
81+
82+ # Create buffers ready for assigning pointers for data collection
83+ bufferDPort0Max = (ctypes .c_int16 * totalSamples )()
84+ bufferDPort0Min = (ctypes .c_int16 * totalSamples )()
85+
86+ # Set the data buffer location for data collection from ps5000a_DIGITAL_PORT0
87+ # handle = chandle
88+ # source = ps5000a_DIGITAL_PORT0 = 0x80
89+ # Buffer max = ctypes.byref(bufferDPort0Max)
90+ # Buffer min = ctypes.byref(bufferDPort0Min)
91+ # Buffer length = totalSamples
92+ # Segment index = 0
93+ # Ratio mode = ps5000a_RATIO_MODE_NONE = 0
94+ status ["SetDataBuffers" ] = ps .ps5000aSetDataBuffers (chandle ,
95+ 0x80 ,
96+ ctypes .byref (bufferDPort0Max ),
97+ ctypes .byref (bufferDPort0Min ),
98+ totalSamples ,
99+ 0 ,
100+ 0 )
101+ assert_pico_ok (status ["SetDataBuffers" ])
102+
103+ # set the digital trigger for a high bit on digital channel 0
104+ conditions = ps .PS5000A_CONDITIONS (ps .PS5000A_CHANNEL ["PS5000A_DIGITAL_PORT0" ], ps .PS5000A_TRIGGER_STATE ["PS5000A_CONDITION_TRUE" ])
105+ nConditions = 1
106+ clear = 1
107+ add = 2
108+ info = clear + add
109+ status ["setTriggerChannelConditionsV2" ] = ps .ps5000aSetTriggerChannelConditionsV2 (chandle ,
110+ ctypes .byref (conditions ),
111+ nConditions ,
112+ info )
113+ assert_pico_ok (status ["setTriggerChannelConditionsV2" ])
114+
115+ directions = ps .PS5000A_DIGITAL_CHANNEL_DIRECTIONS (ps .PS5000A_DIGITAL_CHANNEL ["PS5000A_DIGITAL_CHANNEL_0" ], ps .PS5000A_DIGITAL_DIRECTION ["PS5000A_DIGITAL_DIRECTION_HIGH" ])
116+ nDirections = 1
117+ status ["setTriggerDigitalPortProperties" ] = ps .ps5000aSetTriggerDigitalPortProperties (chandle ,
118+ ctypes .byref (directions ),
119+ nDirections )
120+ assert_pico_ok (status ["setTriggerDigitalPortProperties" ])
121+
122+ print ("Starting data collection..." )
123+
124+ # Starts the block capture
125+ # handle = chandle
126+ # Number of preTriggerSamples
127+ # Number of postTriggerSamples
128+ # Timebase = 1252 = 10000 ns (see Programmer's guide for more information on timebases)
129+ # time indisposed ms = None (This is not needed within the example)
130+ # Segment index = 0
131+ # LpRead = None
132+ # pParameter = None
133+ status ["runblock" ] = ps .ps5000aRunBlock (chandle ,
134+ preTriggerSamples ,
135+ postTriggerSamples ,
136+ timebase ,
137+ None ,
138+ 0 ,
139+ None ,
140+ None )
141+ assert_pico_ok (status ["runblock" ])
142+
143+ # Creates a overflow location for data
144+ overflow = (ctypes .c_int16 * 10 )()
145+ # Creates converted types totalSamples
146+ cTotalSamples = ctypes .c_int32 (totalSamples )
147+
148+ # Checks data collection to finish the capture
149+ ready = ctypes .c_int16 (0 )
150+ check = ctypes .c_int16 (0 )
151+
152+ while ready .value == check .value :
153+ status ["isReady" ] = ps .ps5000aIsReady (chandle , ctypes .byref (ready ))
154+
155+ # Handle = chandle
156+ # start index = 0
157+ # noOfSamples = ctypes.byref(cTotalSamples)
158+ # DownSampleRatio = 1
159+ # DownSampleRatioMode = 0
160+ # SegmentIndex = 0
161+ # Overflow = ctypes.byref(overflow)
162+
163+ status ["GetValues" ] = ps .ps5000aGetValues (chandle , 0 , ctypes .byref (cTotalSamples ), 1 , 0 , 0 , ctypes .byref (overflow ))
164+ assert_pico_ok (status ["GetValues" ])
165+
166+ print ("Data collection complete." )
167+
168+ # Obtain binary for Digital Port 0
169+ # The tuple returned contains the channels in order (D7, D6, D5, ... D0).
170+ bufferDPort0 = splitMSODataFast (cTotalSamples , bufferDPort0Max )
171+
172+ # Creates the time data
173+ time = np .linspace (0 , (cTotalSamples .value - 1 ) * timeIntervalNs .value , cTotalSamples .value )
174+
175+ print ("Plotting data..." )
176+
177+ # Plot the data from digital channels onto a graph
178+
179+ plt .figure (num = 'PicoScope 3000 Series (A API) MSO Block Capture Example' )
180+ plt .title ('Plot of Digital Port 0 digital channels vs. time' )
181+ plt .plot (time , bufferDPort0 [0 ], label = 'D7' ) # D7 is the first array in the tuple.
182+ plt .plot (time , bufferDPort0 [1 ], label = 'D6' )
183+ plt .plot (time , bufferDPort0 [2 ], label = 'D5' )
184+ plt .plot (time , bufferDPort0 [3 ], label = 'D4' )
185+ plt .plot (time , bufferDPort0 [4 ], label = 'D3' )
186+ plt .plot (time , bufferDPort0 [5 ], label = 'D2' )
187+ plt .plot (time , bufferDPort0 [6 ], label = 'D1' )
188+ plt .plot (time , bufferDPort0 [7 ], label = 'D0' ) # D0 is the last array in the tuple.
189+ plt .xlabel ('Time (ns)' )
190+ plt .ylabel ('Logic Level' )
191+ plt .legend (loc = "upper right" )
192+ plt .show ()
193+
194+ print ("Close figure to stop the device and close the connection." )
195+
196+ # Stops the scope
197+ # handle = chandle
198+ status ["stop" ] = ps .ps5000aStop (chandle )
199+ assert_pico_ok (status ["stop" ])
200+
201+ # Closes the unit
202+ # handle = chandle
203+ status ["closeUnit" ] = ps .ps5000aCloseUnit (chandle )
204+ assert_pico_ok (status ["closeUnit" ])
205+
206+ # Displays the status returns
207+ print (status )
0 commit comments