|
| 1 | +# |
| 2 | +# Copyright (C) 2018 Pico Technology Ltd. See LICENSE file for terms. |
| 3 | +# |
| 4 | +# PS4824 BLOCK MODE EXAMPLE |
| 5 | +# This example opens a 4000a 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.ps4000a import ps4000a as ps |
| 11 | +import matplotlib.pyplot as plt |
| 12 | +from picosdk.functions import adc2mV, assert_pico_ok, mV2adc |
| 13 | + |
| 14 | +# Create chandle and status ready for use |
| 15 | +chandle = ctypes.c_int16() |
| 16 | +status = {} |
| 17 | + |
| 18 | +# Open 4000 series PicoScope |
| 19 | +# Returns handle to chandle for use in future API functions |
| 20 | +status["openunit"] = ps.ps4000aOpenUnit(ctypes.byref(chandle), None) |
| 21 | + |
| 22 | +try: |
| 23 | + assert_pico_ok(status["openunit"]) |
| 24 | +except: |
| 25 | + |
| 26 | + powerStatus = status["openunit"] |
| 27 | + |
| 28 | + if powerStatus == 286: |
| 29 | + status["changePowerSource"] = ps.ps4000aChangePowerSource(chandle, powerStatus) |
| 30 | + else: |
| 31 | + raise |
| 32 | + |
| 33 | + assert_pico_ok(status["changePowerSource"]) |
| 34 | + |
| 35 | +# Set up channel A |
| 36 | +# handle = chandle |
| 37 | +# channel = PS4000a_CHANNEL_A = 0 |
| 38 | +# enabled = 1 |
| 39 | +# coupling type = PS4000a_DC = 1 |
| 40 | +# range = PS4000a_2V = 7 |
| 41 | +# analogOffset = 0 V |
| 42 | +chARange = 7 |
| 43 | +status["setChA"] = ps.ps4000aSetChannel(chandle, 0, 1, 1, chARange, 0) |
| 44 | +assert_pico_ok(status["setChA"]) |
| 45 | + |
| 46 | +# Set up channel B |
| 47 | +# handle = chandle |
| 48 | +# channel = PS4000a_CHANNEL_B = 1 |
| 49 | +# enabled = 1 |
| 50 | +# coupling type = PS4000a_DC = 1 |
| 51 | +# range = PS4000a_2V = 7 |
| 52 | +# analogOffset = 0 V |
| 53 | +chBRange = 7 |
| 54 | +status["setChB"] = ps.ps4000aSetChannel(chandle, 1, 1, 1, chBRange, 0) |
| 55 | +assert_pico_ok(status["setChB"]) |
| 56 | + |
| 57 | +# Set up dropout trigger |
| 58 | +# set trigger condtions for channel A and pulse width qualifier |
| 59 | +conditions[1] = ps.PS4000A_CONDITION(ps.PS4000A_CHANNEL["PS4000A_CHANNEL_A"], ps.PS4000A_TRIGGER_STATE["PS4000A_TRUE"]) |
| 60 | +conditions[2] = ps.PS4000A_CONDITION(ps.PS4000A_CHANNEL["PS4000A__PULSE_WIDTH_SOURCE"],ps.PS4000A_TRIGGER_STATE["PS4000A_TRUE"]) |
| 61 | +nConditions = 2 |
| 62 | +info = ps.PS4000A_CONDITIONS_INFO["PS4000A_ADD"] |
| 63 | +status["setTriggerChannelConditions"] = ps.ps4000aSetTriggerChannelConditions(chandle, ctypes.byref(conditions), nConditions, info) |
| 64 | +assert_pico_ok(status["setTriggerChannelConditions"]) |
| 65 | + |
| 66 | +#set trigger directions for channel A |
| 67 | +directions = ps.PS4000A_DIRECTION(ps.PS4000A_CHANNEL["PS4000A_CHANNEL_A"], ps.PS4000A_THRESHOLD_DIRECTION["PS4000A_ENTER"]) |
| 68 | +nDirections = 1 |
| 69 | +status["setTriggerChannelDirections"] = ps.ps4000aSetTriggerChannelDirections(chandle, ctypes.byref(directions), nDirections) |
| 70 | + |
| 71 | +# find maximum ADC count value |
| 72 | +# handle = chandle |
| 73 | +# pointer to value = ctypes.byref(maxADC) |
| 74 | +maxADC = ctypes.c_int16(32767) |
| 75 | + |
| 76 | +# set trigger properties for channel ADC |
| 77 | +thresholdUpper = mV2adc(500, c, maxADC) |
| 78 | +channelProperties = ps.PS4000A_TRIGGER_CHANNEL_PROPERTIES(thresholdUpper, (thresholdUpper * 0.05), (thresholdUpper * -1), (thresholdUpper * 0.05), ps.PS4000A_CHANNEL["PS4000A_CHANNEL_A"], ps.PS4000A_THRESHOLD_MODE["PS4000A_WINDOW"]) |
| 79 | +nChannelProperties = 1 |
| 80 | +autoTriggerms = 10000 |
| 81 | +status["setTriggerChannelProperties"] = ps.ps4000aSetTriggerChannelProperties(chandle, ctypes.byref(channelProperties), nChannelProperties, 0, autoTriggerms) |
| 82 | + |
| 83 | +# Set number of pre and post trigger samples to be collected |
| 84 | +preTriggerSamples = 2500 |
| 85 | +postTriggerSamples = 2500 |
| 86 | +maxSamples = preTriggerSamples + postTriggerSamples |
| 87 | + |
| 88 | +# Get timebase information |
| 89 | +# handle = chandle |
| 90 | +# timebase = 8 = timebase |
| 91 | +# noSamples = maxSamples |
| 92 | +# pointer to timeIntervalNanoseconds = ctypes.byref(timeIntervalns) |
| 93 | +# pointer to maxSamples = ctypes.byref(returnedMaxSamples) |
| 94 | +# segment index = 0 |
| 95 | +timebase = 8 |
| 96 | +timeIntervalns = ctypes.c_float() |
| 97 | +returnedMaxSamples = ctypes.c_int32() |
| 98 | +oversample = ctypes.c_int16(1) |
| 99 | +status["getTimebase2"] = ps.ps4000aGetTimebase2(chandle, timebase, maxSamples, ctypes.byref(timeIntervalns), ctypes.byref(returnedMaxSamples), 0) |
| 100 | +assert_pico_ok(status["getTimebase2"]) |
| 101 | + |
| 102 | +# Run block capture |
| 103 | +# handle = chandle |
| 104 | +# number of pre-trigger samples = preTriggerSamples |
| 105 | +# number of post-trigger samples = PostTriggerSamples |
| 106 | +# timebase = 3 = 80 ns = timebase (see Programmer's guide for mre information on timebases) |
| 107 | +# time indisposed ms = None (not needed in the example) |
| 108 | +# segment index = 0 |
| 109 | +# lpReady = None (using ps4000aIsReady rather than ps4000aBlockReady) |
| 110 | +# pParameter = None |
| 111 | +status["runBlock"] = ps.ps4000aRunBlock(chandle, preTriggerSamples, postTriggerSamples, timebase, None, 0, None, None) |
| 112 | +assert_pico_ok(status["runBlock"]) |
| 113 | + |
| 114 | +# Check for data collection to finish using ps4000aIsReady |
| 115 | +ready = ctypes.c_int16(0) |
| 116 | +check = ctypes.c_int16(0) |
| 117 | +while ready.value == check.value: |
| 118 | + status["isReady"] = ps.ps4000aIsReady(chandle, ctypes.byref(ready)) |
| 119 | + |
| 120 | +# Create buffers ready for assigning pointers for data collection |
| 121 | +bufferAMax = (ctypes.c_int16 * maxSamples)() |
| 122 | +bufferAMin = (ctypes.c_int16 * maxSamples)() # used for downsampling which isn't in the scope of this example |
| 123 | +bufferBMax = (ctypes.c_int16 * maxSamples)() |
| 124 | +bufferBMin = (ctypes.c_int16 * maxSamples)() # used for downsampling which isn't in the scope of this example |
| 125 | + |
| 126 | +# Set data buffer location for data collection from channel A |
| 127 | +# handle = chandle |
| 128 | +# source = PS4000a_CHANNEL_A = 0 |
| 129 | +# pointer to buffer max = ctypes.byref(bufferAMax) |
| 130 | +# pointer to buffer min = ctypes.byref(bufferAMin) |
| 131 | +# buffer length = maxSamples |
| 132 | +# segementIndex = 0 |
| 133 | +# mode = PS4000A_RATIO_MODE_NONE = 0 |
| 134 | +status["setDataBuffersA"] = ps.ps4000aSetDataBuffers(chandle, 0, ctypes.byref(bufferAMax), ctypes.byref(bufferAMin), maxSamples, 0 , 0) |
| 135 | +assert_pico_ok(status["setDataBuffersA"]) |
| 136 | + |
| 137 | +# Set data buffer location for data collection from channel B |
| 138 | +# handle = chandle |
| 139 | +# source = PS4000a_CHANNEL_B = 1 |
| 140 | +# pointer to buffer max = ctypes.byref(bufferBMax) |
| 141 | +# pointer to buffer min = ctypes.byref(bufferBMin) |
| 142 | +# buffer length = maxSamples |
| 143 | +# segementIndex = 0 |
| 144 | +# mode = PS4000A_RATIO_MODE_NONE = 0 |
| 145 | +status["setDataBuffersB"] = ps.ps4000aSetDataBuffers(chandle, 1, ctypes.byref(bufferBMax), ctypes.byref(bufferBMin), maxSamples, 0 , 0) |
| 146 | +assert_pico_ok(status["setDataBuffersB"]) |
| 147 | + |
| 148 | +# create overflow loaction |
| 149 | +overflow = ctypes.c_int16() |
| 150 | +# create converted type maxSamples |
| 151 | +cmaxSamples = ctypes.c_int32(maxSamples) |
| 152 | + |
| 153 | +# Retried data from scope to buffers assigned above |
| 154 | +# handle = chandle |
| 155 | +# start index = 0 |
| 156 | +# pointer to number of samples = ctypes.byref(cmaxSamples) |
| 157 | +# downsample ratio = 0 |
| 158 | +# downsample ratio mode = PS4000a_RATIO_MODE_NONE |
| 159 | +# pointer to overflow = ctypes.byref(overflow)) |
| 160 | +status["getValues"] = ps.ps4000aGetValues(chandle, 0, ctypes.byref(cmaxSamples), 0, 0, 0, ctypes.byref(overflow)) |
| 161 | +assert_pico_ok(status["getValues"]) |
| 162 | + |
| 163 | +# convert ADC counts data to mV |
| 164 | +adc2mVChAMax = adc2mV(bufferAMax, chARange, maxADC) |
| 165 | +adc2mVChBMax = adc2mV(bufferBMax, chBRange, maxADC) |
| 166 | + |
| 167 | +# Create time data |
| 168 | +time = np.linspace(0, (cmaxSamples.value - 1) * timeIntervalns.value, cmaxSamples.value) |
| 169 | + |
| 170 | +# plot data from channel A and B |
| 171 | +plt.plot(time, adc2mVChAMax[:]) |
| 172 | +plt.plot(time, adc2mVChBMax[:]) |
| 173 | +plt.xlabel('Time (ns)') |
| 174 | +plt.ylabel('Voltage (mV)') |
| 175 | +plt.show() |
| 176 | + |
| 177 | +# Stop the scope |
| 178 | +# handle = chandle |
| 179 | +status["stop"] = ps.ps4000aStop(chandle) |
| 180 | +assert_pico_ok(status["stop"]) |
| 181 | + |
| 182 | +# Close unitDisconnect the scope |
| 183 | +# handle = chandle |
| 184 | +status["close"] = ps.ps4000aCloseUnit(chandle) |
| 185 | +assert_pico_ok(status["close"]) |
| 186 | + |
| 187 | +# display status returns |
| 188 | +print(status) |
0 commit comments