Skip to content

Commit f092641

Browse files
authored
Merge pull request #192 from bmoneke/ps4000-tests
Ps4000a tests improved.
2 parents f0a771a + 489ef75 commit f092641

File tree

2 files changed

+150
-33
lines changed

2 files changed

+150
-33
lines changed

examples/test_ps4000a.py

Lines changed: 137 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,45 +1,153 @@
1-
from picoscope import ps4000a
1+
# -*- coding: utf-8 -*-
2+
"""
3+
Testing the ps4000a Series.
4+
"""
5+
6+
# Imports
27
import matplotlib.pyplot as plt
38
import numpy as np
9+
from picoscope import ps4000a
410
import time
511

6-
ps = ps4000a.PS4000a()
712

8-
# rapid block mode
13+
def test_general_unit_calls(picoscope):
14+
"""Test general unit calls."""
15+
picoscope.flashLed()
16+
print(picoscope.getAllUnitInfo())
17+
assert not picoscope.ping(), "Ping failed."
18+
print("General unit calls test passed.")
19+
20+
21+
def test_timebase(ps):
22+
"""Test the timebase methods."""
23+
# Preparation
24+
ps.memorySegments(1)
25+
# Tests
26+
if ps.model == "4444":
27+
data = ((20e-9, 3),
28+
(40e-9, 4))
29+
else:
30+
data = ((25e-9, 1),
31+
(100e-9, 7))
32+
for (t, timebase) in data:
33+
text = f"time {t} does not fit timebase {timebase}."
34+
assert ps.getTimeBaseNum(t) == timebase, "timebasenum: " + text
35+
assert ps.getTimestepFromTimebase(timebase) == t, "Timestep " + text
36+
timestep, _ = ps._lowLevelGetTimebase(timebase, 10, None, 0)
37+
assert timestep == t, f"lowLevel: {timestep} != {t}"
38+
print("Timebase test passed.")
39+
40+
41+
def test_deviceResolution(ps):
42+
"""Test setting/getting device resolution."""
43+
if ps.model == "4444":
44+
ps.setResolution("12")
45+
assert ps.resolution == "12", "Resolution was not set."
46+
# assert ps.getResolution() == "12" not implemented yet
47+
print("Device resolution test passed.")
48+
else:
49+
print("Model does not support resolution.")
50+
51+
52+
def test_rapid_block_mode(ps,
53+
n_captures=100,
54+
sample_interval=100e-9, # 100 ns
55+
sample_duration=2e-3, # 1 ms
56+
):
57+
"""Test the rapid block mode."""
58+
# Configuration of Picoscope
59+
ps.setChannel(channel="A", coupling="DC", VRange=1)
60+
ps.setChannel(channel="B", enabled=False)
61+
62+
ps.setSamplingInterval(sample_interval, sample_duration)
63+
ps.setSimpleTrigger("A", threshold_V=0.1, timeout_ms=1)
64+
65+
samples_per_segment = ps.memorySegments(n_captures)
66+
ps.setNoOfCaptures(n_captures)
67+
68+
data = np.zeros((n_captures, samples_per_segment), dtype=np.int16)
69+
70+
# Measurement
71+
t1 = time.time()
72+
73+
ps.runBlock()
74+
ps.waitReady()
75+
76+
t2 = time.time()
77+
print("Time to record data to scope: ", str(t2 - t1))
78+
79+
ps.getDataRawBulk(data=data)
80+
81+
t3 = time.time()
82+
print("Time to copy to RAM: ", str(t3 - t2))
983

10-
ps.setChannel(channel="A", coupling="DC", VRange=1)
11-
ps.setChannel(channel="B", enabled=False)
12-
ps.setChannel(channel="C", enabled=False)
13-
ps.setChannel(channel="D", enabled=False)
84+
plt.imshow(data[:, 0:ps.noSamples], aspect='auto', interpolation='none',
85+
cmap=plt.cm.hot)
86+
plt.colorbar()
87+
plt.show()
88+
print("Rapid block mode test passed.")
1489

15-
n_captures = 100
16-
sample_interval = 100e-9 # 100 ns
17-
sample_duration = 2e-3 # 1 ms
18-
ps.setResolution('12') # Resolution can only be set on the PS4444
19-
ps.setSamplingInterval(sample_interval, sample_duration)
20-
ps.setSimpleTrigger("A", threshold_V=0.1, timeout_ms=1)
2190

22-
samples_per_segment = ps.memorySegments(n_captures)
23-
ps.setNoOfCaptures(n_captures)
91+
def data_ready(handle, status, noOfSamples, overflow, pParameter=None):
92+
"""Show the asynchronously received data."""
93+
if status == 0:
94+
print(f"{noOfSamples} samples received with overflow: {overflow}")
95+
plt.plot(data)
96+
plt.show()
97+
print("Data reading asynchronously test passed.")
98+
else:
99+
print(f"Data receiving error {status}.")
24100

25-
data = np.zeros((n_captures, samples_per_segment), dtype=np.int16)
26101

27-
t1 = time.time()
102+
def test_read_async(handle=None, status=0, pParameter=None):
103+
"""Test reading data asynchronously."""
104+
if status == 0:
105+
print("Block is ready and can be read.")
106+
channel, numSamples = config
107+
global data
108+
data = np.empty(numSamples, dtype=np.int16)
109+
if not isinstance(channel, int):
110+
channel = ps.CHANNELS[channel]
111+
ps._lowLevelSetDataBuffer(channel, data, 0, 0)
112+
ps._lowLevelGetValuesAsync(numSamples, 0, 1, 0, 0, data_ready, None)
113+
print("Get values async started.")
114+
else:
115+
print("Data is not ready. RunBlock had an error.")
28116

29-
ps.runBlock()
30-
ps.waitReady()
31117

32-
t2 = time.time()
33-
print("Time to record data to scope: ", str(t2 - t1))
118+
def test_runBlock_async(picoscope, channel="A", sample_interval=100e-9,
119+
sample_duration=2e-3):
120+
"""Test running a block asynchronously."""
121+
# Configuration of Picoscope
122+
global ps
123+
ps = picoscope
124+
ps.setChannel(channel=channel, coupling="DC", VRange=1)
125+
ps.memorySegments(1)
126+
ps.setNoOfCaptures(1)
127+
i, samples, m = ps.setSamplingInterval(sample_interval, sample_duration)
128+
ps.setSimpleTrigger("A", threshold_V=0.1, timeout_ms=1)
34129

35-
ps.getDataRawBulk(data=data)
130+
global config
131+
config = channel, samples
132+
# Run the block
133+
ps.runBlock(callback=test_read_async)
134+
print("Run Block started, waiting 2 s.")
135+
time.sleep(2)
136+
print("Run block finished")
36137

37-
t3 = time.time()
38-
print("Time to copy to RAM: ", str(t3 - t2))
39138

40-
plt.imshow(data[:, 0:ps.noSamples], aspect='auto', interpolation='none',
41-
cmap=plt.cm.hot)
42-
plt.colorbar()
43-
plt.show()
139+
if __name__ == "__main__":
140+
"""Run all the tests."""
141+
# Initialize the picoscope
142+
ps = ps4000a.PS4000a()
44143

45-
ps.close()
144+
try:
145+
# Run tests.
146+
test_general_unit_calls(ps)
147+
test_deviceResolution(ps)
148+
test_rapid_block_mode(ps)
149+
test_runBlock_async(ps)
150+
finally:
151+
# Close the connection
152+
ps.close()
153+
print("All tests passed.")

picoscope/ps4000a.py

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -509,6 +509,19 @@ def _lowLevelGetValues(self, numSamples, startIndex, downSampleRatio,
509509
self.checkResult(m)
510510
return (numSamplesReturned.value, overflow.value)
511511

512+
def _lowLevelGetValuesAsync(self, numSamples, startIndex, downSampleRatio,
513+
downSampleMode, segmentIndex, callback, pPar):
514+
self._c_getValues_callback = dataReady(callback)
515+
m = self.lib.ps4000aGetValuesAsync(c_int16(self.handle),
516+
c_uint32(startIndex),
517+
c_uint32(numSamples),
518+
c_uint32(downSampleRatio),
519+
c_enum(downSampleMode),
520+
c_uint32(segmentIndex),
521+
self._c_getValues_callback,
522+
c_void_p())
523+
self.checkResult(m)
524+
512525
def _lowLevelSetDeviceResolution(self, resolution):
513526
self.resolution = resolution
514527
m = self.lib.ps4000aSetDeviceResolution(
@@ -700,10 +713,6 @@ def _lowLevelSetTriggerDelay(self):
700713
pass
701714

702715
# Async functions
703-
# would be nice, but we would have to learn to implement callbacks
704-
def _lowLevelGetValuesAsync(self):
705-
pass
706-
707716
def _lowLevelGetValuesBulkAsync(self):
708717
pass
709718

0 commit comments

Comments
 (0)