1+ #
2+ # Copyright (C) 2020 Pico Technology Ltd. See LICENSE file for terms.
3+ #
4+ # PS6000A Demonstrates external clock callback using block mode.
5+ # This example opens a 6000a driver device, sets up the External clock callback, and reports its status during a block capture.
6+ # Data is then plotted as mV against time in ns.
7+
8+ import ctypes
9+ import numpy as np
10+ from picosdk .ps6000a import ps6000a as ps
11+ from picosdk .PicoDeviceEnums import picoEnum as enums
12+ import matplotlib .pyplot as plt
13+ from picosdk .functions import adc2mV , assert_pico_ok
14+ from picosdk .constants import PICO_STATUS
15+ import time
16+
17+ # Create chandle and status ready for use
18+ chandle = ctypes .c_int16 ()
19+ status = {}
20+
21+ # Open 6000 A series PicoScope
22+ # returns handle to chandle for use in future API functions
23+ resolution = enums .PICO_DEVICE_RESOLUTION ["PICO_DR_8BIT" ]
24+ status ["openunit" ] = ps .ps6000aOpenUnit (ctypes .byref (chandle ), None , resolution )
25+ assert_pico_ok (status ["openunit" ])
26+
27+ # setup External clock callback function
28+ wasCalledBack = False
29+ ExtRefClk_PicoStatus = enums .PICO_STATUS ["PICO_OK" ]
30+ ExtRefClkReference = enums .PICO_CLOCK_REFERENCE ["PICO_INTERNAL_REF" ]
31+
32+ def ExternalReferenceInteractions_callback (handle , statusCallback , reference ):
33+ global wasCalledBack , ExtRefClk_PicoStatus , ExtRefClkReference
34+ wasCalledBack = True
35+ ExtRefClkReference = reference
36+ ExtRefClk_PicoStatus = statusCallback
37+
38+ # Convert the python function into a C function pointer.
39+ cFuncPtrExtClkCB = ps .ExternalReferenceInteractionsReadyType (ExternalReferenceInteractions_callback )
40+ # Register the External clock callback
41+ status ["SetExternalReferenceInteractionCallback" ] = ps .ps6000aSetExternalReferenceInteractionCallback (chandle , cFuncPtrExtClkCB )
42+ assert_pico_ok (status ["SetExternalReferenceInteractionCallback" ])
43+
44+ time .sleep (1 )
45+
46+ if wasCalledBack == True :
47+ print ("ExtRefClk_PicoStatus = " , ExtRefClk_PicoStatus )
48+ print ("ExtRefClk_Reference = " , ExtRefClkReference )
49+ wasCalledBack = False
50+
51+ # Set channel A on
52+ # handle = chandle
53+ channelA = enums .PICO_CHANNEL ["PICO_CHANNEL_A" ]
54+ coupling = enums .PICO_COUPLING ["PICO_DC" ]
55+ channelRange = 7
56+
57+ # analogueOffset = 0 V
58+ bandwidth = enums .PICO_BANDWIDTH_LIMITER ["PICO_BW_FULL" ]
59+ status ["setChannelA" ] = ps .ps6000aSetChannelOn (chandle , channelA , coupling , channelRange , 0 , bandwidth )
60+ assert_pico_ok (status ["setChannelA" ])
61+
62+ # set channel B-H off
63+ for x in range (1 , 7 , 1 ):
64+ channel = x
65+ status ["setChannel" ,x ] = ps .ps6000aSetChannelOff (chandle ,channel )
66+ assert_pico_ok (status ["setChannel" ,x ])
67+
68+ # Set simple trigger on channel A, 1 V rising with 1 s autotrigger
69+ # handle = chandle
70+ # enable = 1
71+ source = channelA
72+ # threshold = 1000 mV
73+ direction = enums .PICO_THRESHOLD_DIRECTION ["PICO_RISING" ]
74+ # delay = 0 s
75+ # autoTriggerMicroSeconds = 1000000 us
76+ status ["setSimpleTrigger" ] = ps .ps6000aSetSimpleTrigger (chandle , 1 , source , 1000 , direction , 0 , 1000000 )
77+ assert_pico_ok (status ["setSimpleTrigger" ])
78+
79+ # Get fastest available timebase
80+ # handle = chandle
81+ enabledChannelFlags = enums .PICO_CHANNEL_FLAGS ["PICO_CHANNEL_A_FLAGS" ]
82+ timebase = ctypes .c_uint32 (0 )
83+ timeInterval = ctypes .c_double (0 )
84+
85+ # resolution = resolution
86+ status ["getMinimumTimebaseStateless" ] = ps .ps6000aGetMinimumTimebaseStateless (chandle , enabledChannelFlags , ctypes .byref (timebase ), ctypes .byref (timeInterval ), resolution )
87+ timebase = ctypes .c_uint32 (1000 )
88+ print ("timebase = " , timebase .value )
89+ print ("sample interval =" , timeInterval .value , "s" )
90+
91+ # Set number of samples to be collected
92+ noOfPreTriggerSamples = 500000
93+ noOfPostTriggerSamples = 1000000
94+ nSamples = noOfPostTriggerSamples + noOfPreTriggerSamples
95+
96+ # Create buffers
97+ bufferAMax = (ctypes .c_int16 * nSamples )()
98+ bufferAMin = (ctypes .c_int16 * nSamples )() # used for downsampling which isn't in the scope of this example
99+
100+ # Set data buffers
101+ # handle = chandle
102+ # channel = channelA
103+ # bufferMax = bufferAMax
104+ # bufferMin = bufferAMin
105+ # nSamples = nSamples
106+ dataType = enums .PICO_DATA_TYPE ["PICO_INT16_T" ]
107+ waveform = 0
108+ downSampleMode = enums .PICO_RATIO_MODE ["PICO_RATIO_MODE_RAW" ]
109+ clear = enums .PICO_ACTION ["PICO_CLEAR_ALL" ]
110+ add = enums .PICO_ACTION ["PICO_ADD" ]
111+ action = clear | add # PICO_ACTION["PICO_CLEAR_WAVEFORM_CLEAR_ALL"] | PICO_ACTION["PICO_ADD"]
112+ status ["setDataBuffers" ] = ps .ps6000aSetDataBuffers (chandle , channelA , ctypes .byref (bufferAMax ), ctypes .byref (bufferAMin ), nSamples , dataType , waveform , downSampleMode , action )
113+ assert_pico_ok (status ["setDataBuffers" ])
114+
115+ # Run block capture
116+ # handle = chandle
117+ # timebase = timebase
118+ timeIndisposedMs = ctypes .c_double (0 )
119+ # segmentIndex = 0
120+ # lpReady = None Using IsReady rather than a callback
121+ # pParameter = None
122+ status ["runBlock" ] = ps .ps6000aRunBlock (chandle , noOfPreTriggerSamples , noOfPostTriggerSamples , timebase , ctypes .byref (timeIndisposedMs ), 0 , None , None )
123+ assert_pico_ok (status ["runBlock" ])
124+
125+ # Check for data collection to finish using ps6000aIsReady
126+ # Also print any change to the samaple clock source
127+ ready = ctypes .c_int16 (0 )
128+ check = ctypes .c_int16 (0 )
129+ while ready .value == check .value :
130+ status ["isReady" ] = ps .ps6000aIsReady (chandle , ctypes .byref (ready ))
131+ if wasCalledBack == True :
132+ print ("ExtRefClk_Reference = " , ExtRefClkReference )
133+ wasCalledBack = False
134+
135+ # Get data from scope
136+ # handle = chandle
137+ # startIndex = 0
138+ noOfSamples = ctypes .c_uint64 (nSamples )
139+ # downSampleRatio = 1
140+ # segmentIndex = 0
141+ overflow = ctypes .c_int16 (0 )
142+ status ["getValues" ] = ps .ps6000aGetValues (chandle , 0 , ctypes .byref (noOfSamples ), 1 , downSampleMode , 0 , ctypes .byref (overflow ))
143+ assert_pico_ok (status ["getValues" ])
144+
145+ # get max ADC value
146+ # handle = chandle
147+ minADC = ctypes .c_int16 ()
148+ maxADC = ctypes .c_int16 ()
149+ status ["getAdcLimits" ] = ps .ps6000aGetAdcLimits (chandle , resolution , ctypes .byref (minADC ), ctypes .byref (maxADC ))
150+ assert_pico_ok (status ["getAdcLimits" ])
151+
152+ # convert ADC counts data to mV
153+ adc2mVChAMax = adc2mV (bufferAMax , channelRange , maxADC )
154+
155+ # Create time data
156+ time = np .linspace (0 , (nSamples - 1 ) * timeInterval .value * 1000000000 , nSamples )
157+
158+ # plot data from channel A and B
159+ plt .plot (time , adc2mVChAMax [:])
160+ plt .xlabel ('Time (ns)' )
161+ plt .ylabel ('Voltage (mV)' )
162+ plt .show ()
163+
164+ # Close the scope
165+ status ["closeunit" ] = ps .ps6000aCloseUnit (chandle )
166+ assert_pico_ok (status ["closeunit" ])
167+
168+ print (status )
0 commit comments