Inconsistent results from constant voltage source when using Picoscope 5000A

Having problems ? let us know the details here
Post Reply
Vini
Newbie
Posts: 1
Joined: Wed Jun 29, 2022 3:33 pm

Inconsistent results from constant voltage source when using Picoscope 5000A

Post by Vini »

I am currently experimenting with the Picoscope 5000A and observed a behavior when measuring a constant voltage source that seems inconsistent to me.
I now noted this behavior only occurs when using the Picoscope 5000A - the picoscope 2000A gives the expected results. See below for the details:

I have the following setup: I am measuring a constant 0.4V source via the picoscope python interface. Because I expect some noise and fluctations, I average out the results that I get from the scope. My expectation was that the average should be stable across measurements. In particular, I measure with the following parameters:
- 15 Bit resolution
- 2V Range
- 1x Probes
- Then I take measurements using the function `ps5000aRunBlock` like so:

Code: Select all

timebase = 3
preTriggerSamples = 650
postTriggerSamples = 650
maxSamples = preTriggerSamples + postTriggerSamples
status["getTimebase2"] = ps.ps5000aGetTimebase2(chandle, timebase, maxSamples, ctypes.byref(timeIntervalns), ctypes.byref(returnedMaxSamples), 0)
ps.ps5000aRunBlock(chandle, preTriggerSamples, postTriggerSamples, timebase, None, 0, None, None)
I average over all samples and then store this as one datapoint. If I repeat this procedure (measure using aRunBlock and take the average of the samples) mulitple times, the average evolves like below.
Image
This is somewhat suprising to me - should the average not be constant? What is the reason for this "drop" in the voltage average?

For the sake of completeness, here is the full python code.

Code: Select all

import ctypes
import numpy as np
from picosdk.ps5000a import ps5000a as ps
from picosdk.functions import adc2mV, assert_pico_ok, mV2adc
import pickle
import matplotlib.pyplot as plt

# Create chandle and status ready for use
chandle = ctypes.c_int16()
status = {}
# Open 5000 series PicoScope
# Resolution set to 15 Bit
resolution =ps.PS5000A_DEVICE_RESOLUTION["PS5000A_DR_15BIT"]

# Returns handle to chandle for use in future API functions

status["openunit"] = ps.ps5000aOpenUnit(ctypes.byref(chandle), None, resolution)
try:
 assert_pico_ok(status["openunit"])
except: # PicoNotOkError:
    powerStatus = status["openunit"]
    if powerStatus == 286:
        status["changePowerSource"] = ps.ps5000aChangePowerSource(chandle, powerStatus)
    elif powerStatus == 282:
        status["changePowerSource"] = ps.ps5000aChangePowerSource(chandle, powerStatus)
    else:
        raise
    assert_pico_ok(status["changePowerSource"])
# Set up channel A
channel = ps.PS5000A_CHANNEL["PS5000A_CHANNEL_A"]
coupling_type = ps.PS5000A_COUPLING["PS5000A_DC"]
#Range: 2V
chARange = ps.PS5000A_RANGE["PS5000A_2V"]
# analogue offset = 0 V
status["setChA"] = ps.ps5000aSetChannel(chandle, channel, 1, coupling_type, chARange, 0)
assert_pico_ok(status["setChA"])
# find maximum ADC count value
maxADC = ctypes.c_int16()
status["maximumValue"] = ps.ps5000aMaximumValue(chandle, ctypes.byref(maxADC))
assert_pico_ok(status["maximumValue"])
# Set number of pre and post trigger samples to be collected
preTriggerSamples = 650
postTriggerSamples = 650
maxSamples = preTriggerSamples + postTriggerSamples
# Get timebase information
timebase = 3
timeIntervalns = ctypes.c_float()
returnedMaxSamples = ctypes.c_int32()
status["getTimebase2"] = ps.ps5000aGetTimebase2(chandle, timebase, maxSamples, ctypes.byref(timeIntervalns), ctypes.byref(returnedMaxSamples), 0)
assert_pico_ok(status["getTimebase2"])
NUM_SAMPLES = 10_000
OUT_FILENAME = "voltage_average.pickle"
collected_samples = np.zeros((NUM_SAMPLES, maxSamples))
with open(OUT_FILENAME, "ab+") as fp:
    for i in range(NUM_SAMPLES):
        status["runBlock"] = ps.ps5000aRunBlock(chandle, preTriggerSamples, postTriggerSamples, timebase, None, 0, None, None)
        assert_pico_ok(status["runBlock"])
        # Check for data collection to finish using ps5000aIsReady
        ready = ctypes.c_int16(0)
        check = ctypes.c_int16(0)
        while ready.value == check.value:
            status["isReady"] = ps.ps5000aIsReady(chandle, ctypes.byref(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
        source = ps.PS5000A_CHANNEL["PS5000A_CHANNEL_A"]
        status["setDataBuffersA"] = ps.ps5000aSetDataBuffers(chandle, source, ctypes.byref(bufferAMax), ctypes.byref(bufferAMin), maxSamples, 0, 0)
        assert_pico_ok(status["setDataBuffersA"])
        overflow = ctypes.c_int16() 
        cmaxSamples = ctypes.c_int32(maxSamples)
        status["getValues"] = ps.ps5000aGetValues(chandle, 0, ctypes.byref(cmaxSamples), 0, 0, 0, ctypes.byref(overflow))
        assert_pico_ok(status["getValues"])
        adc2mVChAMax = adc2mV(bufferAMax, chARange, maxADC)
        print("Current mean", np.mean(adc2mVChAMax[:]))
        collected_samples[i] = np.mean(adc2mVChAMax[:]) 
        pickle.dump(collected_samples[i], fp)
  

# Create time data

#time = np.linspace(0, (cmaxSamples.value - 1) * timeIntervalns.value, cmaxSamples.value)
time = list(range(0,len(collected_samples)))

  

# plot data 
plt.plot(time, collected_samples, "b")

plt.xlabel('Time (ns)')

plt.ylabel('Voltage (mV)')

plt.show()

  

# Stop the scope

# handle = chandle

status["stop"] = ps.ps5000aStop(chandle)

assert_pico_ok(status["stop"])

Martyn
Site Admin
Site Admin
Posts: 4499
Joined: Fri Jun 10, 2011 8:15 am
Location: St. Neots

Re: Inconsistent results from constant voltage source when using Picoscope 5000A

Post by Martyn »

What happens if you run the 5000A series scope in 8 bit mode?
Martyn
Technical Support Manager

Post Reply