Code: Select all
import ctypes
import numpy as np
from picosdk.ps4000a import ps4000a as ps
import matplotlib.pyplot as plt
from picosdk.functions import adc2mV, assert_pico_ok
from datetime import datetime
import csv
# Create chandle and status ready for use
chandle = ctypes.c_int16()
status = {}
# Open 4000 series PicoScope
# Returns handle to chandle for use in future API functions
status["openunit"] = ps.ps4000aOpenUnit(ctypes.byref(chandle), None)
try:
assert_pico_ok(status["openunit"])
except: # PicoNotOkError:
powerStatus = status["openunit"]
if powerStatus == 286:
status["changePowerSource"] = ps.ps4000aChangePowerSource(chandle, powerStatus)
elif powerStatus == 282:
status["changePowerSource"] = ps.ps4000aChangePowerSource(chandle, powerStatus)
else:
raise
assert_pico_ok(status["changePowerSource"])
# Set up channel A
# handle = chandle
# channel = PS4000a_CHANNEL_A = 0
# enabled = 1
# coupling type = PS4000a_DC = 1
# range = 5V (diff probe) = 8
# analogOffset = 0 V
chARange = 8
status["setChA"] = ps.ps4000aSetChannel(chandle, 0, 1, 1, chARange, 0)
assert_pico_ok(status["setChA"])
# Set up channel B
# handle = chandle
# channel = PS4000a_CHANNEL_B = 1
# enabled = 1
# coupling type = PS4000a_DC = 1
# range = 5V (diff probe) = 8
# analogOffset = 0 V
chBRange = 8
status["setChB"] = ps.ps4000aSetChannel(chandle, 1, 1, 1, chBRange, 0)
assert_pico_ok(status["setChB"])
# Set up channel C
# handle = chandle
# channel = PS4000a_CHANNEL_C = 2
# enabled = 1
# coupling type = PS4000a_DC = 1
# range = 50V = 11
# analogOffset = 0 V
chCRange = 11
status["setChC"] = ps.ps4000aSetChannel(chandle, 2, 0, 1, chCRange, 0)
assert_pico_ok(status["setChC"])
# Set up channel D
# handle = chandle
# channel = PS4000a_CHANNEL_D = 3
# enabled = 0
# coupling type = PS4000a_DC = 1
# range = PS4000a_2V = 7
# analogOffset = 0 V
chDRange = 7
status["setChD"] = ps.ps4000aSetChannel(chandle, 3, 0, 1, chDRange, 0)
assert_pico_ok(status["setChD"])
# Set up window pulse width trigger on C
conditions = ps.PS4000A_CONDITION(2, ps.PS4000A_TRIGGER_STATE["PS4000A_TRUE"])
status["setPWQConditions"] = ps.ps4000aSetPulseWidthQualifierConditions(chandle,
ctypes.byref(conditions),
ctypes.c_int16(1),
ps.PS4000A_CONDITIONS_INFO["PS4000A_ADD"])
assert_pico_ok(status["setPWQConditions"])
# threshold is 32767/4, or ~12.5V
upperThreshold = 13107 # Used for falling
upperHyst = 11000
lowerThreshold = 1310 # Used for rising
lowerHyst = 2000
properties = ps.PS4000A_TRIGGER_CHANNEL_PROPERTIES(upperThreshold, upperHyst, lowerThreshold, lowerHyst, 2,
ps.PS4000A_THRESHOLD_MODE["PS4000A_WINDOW"])
status["setTriggerProperties"] = ps.ps4000aSetTriggerChannelProperties(chandle,
ctypes.byref(properties),
ctypes.c_int16(1), ctypes.c_int16(0), ctypes.c_int32(0))
assert_pico_ok(status["setTriggerProperties"])
# microseconds approx. = value/100
maxPW = ctypes.c_uint32(70000)
minPW = ctypes.c_uint32(30000)
status["setPWQProperties"] = ps.ps4000aSetPulseWidthQualifierProperties(chandle,
ps.PS4000A_THRESHOLD_DIRECTION["PS4000A_OUTSIDE"],
minPW, maxPW,
ps.PS4000A_PULSE_WIDTH_TYPE["PW_TYPE_IN_RANGE"])
assert_pico_ok(status["setPWQProperties"])
# Set number of pre and post trigger samples to be collected
# With 3 active channels, available capture time is <0.85 seconds total
# preTriggerSamples + postTriggerSamples < 85333333
# However this is very slow so only ~75 ms are captured here
# microseconds approx. = value/100
preTriggerSamples = 5000000
postTriggerSamples = 2500000
maxSamples = preTriggerSamples + postTriggerSamples
timeIntervalns = ctypes.c_float(10) # true for timebase = 2
numCaptures = 0
partCaptures = 0
try:
while True:
# Run block capture
# handle = chandle
# number of pre-trigger samples = preTriggerSamples
# number of post-trigger samples = PostTriggerSamples
# timebase = 2 = 100 Ms/s (see Programmer's guide for mre information on timebases)
# time indisposed ms = None (not needed in the example)
# segment index = 0
# lpReady = None (using ps4000aIsReady rather than ps4000aBlockReady)
# pParameter = None
status["runBlock"] = ps.ps4000aRunBlock(chandle, preTriggerSamples, postTriggerSamples, 2, None, 0, None, None)
assert_pico_ok(status["runBlock"])
# Check for data collection to finish using ps4000aIsReady
ready = ctypes.c_int16(0)
check = ctypes.c_int16(0)
while ready.value == check.value:
status["isReady"] = ps.ps4000aIsReady(chandle, ctypes.byref(ready))
print("Ready.")
# Create buffers ready for assigning pointers for data collection
bufferAMax = (ctypes.c_int16 * maxSamples)()
bufferAMin = (ctypes.c_int16 * maxSamples)() # used for downsampling which isn't in the scope of this example
bufferBMax = (ctypes.c_int16 * maxSamples)()
bufferBMin = (ctypes.c_int16 * maxSamples)() # used for downsampling which isn't in the scope of this example
bufferCMax = (ctypes.c_int16 * maxSamples)()
bufferCMin = (ctypes.c_int16 * maxSamples)() # used for downsampling which isn't in the scope of this example
# Set data buffer location for data collection from channel A
# handle = chandle
# source = PS4000a_CHANNEL_A = 0
# pointer to buffer max = ctypes.byref(bufferAMax)
# pointer to buffer min = ctypes.byref(bufferAMin)
# buffer length = maxSamples
# segementIndex = 0
# mode = PS4000A_RATIO_MODE_NONE = 0
status["setDataBuffersA"] = ps.ps4000aSetDataBuffers(chandle, 0, ctypes.byref(bufferAMax), ctypes.byref(bufferAMin), maxSamples, 0 , 0)
assert_pico_ok(status["setDataBuffersA"])
# Set data buffer location for data collection from channel B
# handle = chandle
# source = PS4000a_CHANNEL_B = 1
# pointer to buffer max = ctypes.byref(bufferBMax)
# pointer to buffer min = ctypes.byref(bufferBMin)
# buffer length = maxSamples
# segementIndex = 0
# mode = PS4000A_RATIO_MODE_NONE = 0
status["setDataBuffersB"] = ps.ps4000aSetDataBuffers(chandle, 1, ctypes.byref(bufferBMax), ctypes.byref(bufferBMin), maxSamples, 0 , 0)
assert_pico_ok(status["setDataBuffersB"])
# Set data buffer location for data collection from channel C
# handle = chandle
# source = PS4000a_CHANNEL_C = 2
# pointer to buffer max = ctypes.byref(bufferCMax)
# pointer to buffer min = ctypes.byref(bufferCMin)
# buffer length = maxSamples
# segementIndex = 0
# mode = PS4000A_RATIO_MODE_NONE = 0
status["setDataBuffersC"] = ps.ps4000aSetDataBuffers(chandle, 2, ctypes.byref(bufferCMax), ctypes.byref(bufferCMin), maxSamples, 0 , 0)
assert_pico_ok(status["setDataBuffersC"])
# create overflow loaction
overflow = ctypes.c_int16()
# create converted type maxSamples
cmaxSamples = ctypes.c_int32(maxSamples)
# Retrieve data from scope to buffers assigned above
# handle = chandle
# start index = 0
# pointer to number of samples = ctypes.byref(cmaxSamples)
# downsample ratio = 0
# downsample ratio mode = PS4000a_RATIO_MODE_NONE
# pointer to overflow = ctypes.byref(overflow))
status["getValues"] = ps.ps4000aGetValues(chandle, 0, ctypes.byref(cmaxSamples), 0, 0, 0, ctypes.byref(overflow))
assert_pico_ok(status["getValues"])
# find maximum ADC count value
# handle = chandle
# pointer to value = ctypes.byref(maxADC)
maxADC = ctypes.c_int16(32767)
# convert ADC counts data to mV
adc2mVChAMax = adc2mV(bufferAMax, chARange, maxADC)
adc2mVChBMax = adc2mV(bufferBMax, chBRange, maxADC)
adc2mVChCMax = adc2mV(bufferCMax, chCRange, maxADC)
# Create time data
time = np.linspace(0, (cmaxSamples.value - 1) * timeIntervalns.value, cmaxSamples.value)
time = time/1000000
partCaptures += 1
print("Writing to file...")
# save data to text file with unique filename
current_datetime = datetime.now().strftime("%Y-%m-%d %H-%M-%S")
str_current_datetime = str(current_datetime)
file_name = str_current_datetime + ".csv"
allData = zip(time, adc2mVChAMax, adc2mVChBMax, adc2mVChCMax)
with open(file_name, 'w') as f:
writer = csv.writer(f, delimiter=";", lineterminator="\n")
writer.writerow(["T (ms)", "A", "B", "Trigger"])
writer.writerows(allData)
print("File created : "+f.name)
f.close()
numCaptures += 1
partCaptures -= 1
print("Plotting...")
# plot data from all channels
plt.figure(figsize=(25, 10))
ax = plt.gca()
ax.set_ylim([-5000, 5000])
plt.plot(time, adc2mVChAMax[:], label="A")
plt.plot(time, adc2mVChBMax[:], label="B")
plt.plot(time, adc2mVChCMax[:], label="Trig")
plt.legend(loc="upper left")
plt.xlabel('Time (ms)')
plt.ylabel('Voltage (mV)')
file_name = str_current_datetime + ".png"
plt.savefig(file_name)
plt.close()
print("Capture Plot "+str(numCaptures)+" Saved: "+file_name)
except KeyboardInterrupt:
pass
# Stop the scope
# handle = chandle
status["stop"] = ps.ps4000aStop(chandle)
assert_pico_ok(status["stop"])
# Close unitDisconnect the scope
# handle = chandle
status["close"] = ps.ps4000aCloseUnit(chandle)
assert_pico_ok(status["close"])
# display status returns
print("Captures This Session:")
print(numCaptures)
print("Partial Captures:")
print(partCaptures)
print(status)