summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEddy Pedroni <eddy@0xf7.com>2022-06-02 21:51:22 +0200
committerEddy Pedroni <eddy@0xf7.com>2022-06-02 21:51:22 +0200
commit038be6aa9a2882db877954c1a57bb23ea70b5ad5 (patch)
tree6cc70fd8be7614ae98b6ab4a335fdf40fb9ca09b
parent7c7d85f9bdc4715500cbf901fcdd8eb605d2668e (diff)
Minor improvements
-rw-r--r--doc/architecture.drawio2
-rw-r--r--lab_control/frequency_response.py14
-rw-r--r--lab_control/measurement.py9
-rw-r--r--lab_control/test/frequency_response_test.py (renamed from lab_control/test/frequency_response_measurement_test.py)37
-rw-r--r--lab_control/test/measurement_test.py53
5 files changed, 92 insertions, 23 deletions
diff --git a/doc/architecture.drawio b/doc/architecture.drawio
index f32a569..d1e47f2 100644
--- a/doc/architecture.drawio
+++ b/doc/architecture.drawio
@@ -1 +1 @@
-<mxfile host="Electron" modified="2022-06-01T15:45:48.554Z" agent="5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) draw.io/18.0.6 Chrome/100.0.4896.143 Electron/18.2.3 Safari/537.36" etag="QFb5ZM_4cWopSkUcfKm_" version="18.0.6" type="device"><diagram id="Aw8Itl_1nmNhQKuLZfUh" name="Page-1">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</diagram></mxfile> \ No newline at end of file
+<mxfile host="Electron" modified="2022-06-02T18:24:10.320Z" agent="5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) draw.io/16.0.2 Chrome/96.0.4664.55 Electron/16.0.5 Safari/537.36" etag="jSyoEUgZMjaeJw8LBDId" version="16.0.2" type="device"><diagram id="Aw8Itl_1nmNhQKuLZfUh" name="Page-1">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</diagram></mxfile> \ No newline at end of file
diff --git a/lab_control/frequency_response.py b/lab_control/frequency_response.py
index af399b1..8d46689 100644
--- a/lab_control/frequency_response.py
+++ b/lab_control/frequency_response.py
@@ -1,6 +1,6 @@
from lab_control.function_generator import FunctionGenerator
from lab_control.oscilloscope import Oscilloscope
-from lab_control.measurement import Measurement
+from lab_control.measurement import Measurement, getLinearRange
class FrequencyResponseMeasurement(Measurement):
def __init__(self):
@@ -13,13 +13,15 @@ class FrequencyResponseMeasurement(Measurement):
self.data = None
def measure(self, osc: Oscilloscope, fg: FunctionGenerator) -> None:
- frequencyRange = self.maxFrequency - self.minFrequency
+ frequencies = getLinearRange(self.minFrequency, self.maxFrequency, self.steps)
self.data = []
- for i in range(0, self.steps):
- frequency = self.minFrequency + i * frequencyRange / (self.steps - 1)
- fg.setFrequency(self.functionGeneratorChannel, frequency)
+ for f in frequencies:
+ fg.setFrequency(self.functionGeneratorChannel, f)
response = osc.measureAmplitude(self.oscilloscopeChannel)
- self.data.append((frequency, response))
+ self.data.append((f, response))
self.measurementDone = True
+
+ def saveToCSV(self, path: str) -> None:
+ pass
diff --git a/lab_control/measurement.py b/lab_control/measurement.py
index 78f393e..eca228d 100644
--- a/lab_control/measurement.py
+++ b/lab_control/measurement.py
@@ -1,6 +1,15 @@
from lab_control.function_generator import FunctionGenerator
from lab_control.oscilloscope import Oscilloscope
+def getLinearRange(first: float, last: float, steps: int) -> list[float]:
+ assert steps > 1, "Linear range requires at least two steps"
+ diff = last - first
+ stepSize = diff / (steps - 1)
+ return [first + i * stepSize for i in range(0, steps)]
+
class Measurement:
def measure(self, osc: Oscilloscope, fg: FunctionGenerator) -> None:
pass
+
+ def saveToCSV(self, path: str) -> None:
+ pass
diff --git a/lab_control/test/frequency_response_measurement_test.py b/lab_control/test/frequency_response_test.py
index 5a73b3e..014b4f6 100644
--- a/lab_control/test/frequency_response_measurement_test.py
+++ b/lab_control/test/frequency_response_test.py
@@ -2,6 +2,7 @@ import pytest
from lab_control.test.mock_lab import MockLab
from lab_control.frequency_response import FrequencyResponseMeasurement
+from lab_control.measurement import getLinearRange
@pytest.fixture
def mockLab():
@@ -11,22 +12,9 @@ def mockLab():
def uut(mockLab):
return FrequencyResponseMeasurement()
-def test_frequencyResponseDefaults(uut):
- assert uut.minFrequency == 20e0
- assert uut.maxFrequency == 16e3
- assert uut.steps == 50
- assert uut.functionGeneratorChannel == 1
- assert uut.oscilloscopeChannel == 1
-
-def test_frequencyResponseRamp(mockLab, uut):
- uut.minFrequency = 100.0
- uut.maxFrequency = 200.0
- uut.steps = 11
- uut.functionGeneratorChannel = 1
- uut.oscilloscopeChannel = 1
-
+def prepareRampResponse(uut, mockLab):
# Expect a ramp response from 0.5 to 1.5 * input amplitude
- inputAmplitude = 1.0
+ inputAmplitude = 2.0
minScale = 0.5
maxScale = 1.5
@@ -40,7 +28,23 @@ def test_frequencyResponseRamp(mockLab, uut):
mockLab.setAmplitude(uut.functionGeneratorChannel, inputAmplitude)
mockLab.setOn(uut.functionGeneratorChannel)
- expectedData = [(f, testFunction(f) * inputAmplitude) for f in [100.0, 110.0, 120.0, 130.0, 140.0, 150.0, 160.0, 170.0, 180.0, 190.0, 200.0]]
+ return [(f, testFunction(f) * inputAmplitude) for f in getLinearRange(uut.minFrequency, uut.maxFrequency, uut.steps)]
+
+def test_frequencyResponseDefaults(uut):
+ assert uut.minFrequency == 20e0
+ assert uut.maxFrequency == 16e3
+ assert uut.steps == 50
+ assert uut.functionGeneratorChannel == 1
+ assert uut.oscilloscopeChannel == 1
+
+def test_frequencyResponseRamp(mockLab, uut):
+ uut.minFrequency = 100.0
+ uut.maxFrequency = 200.0
+ uut.steps = 11
+ uut.functionGeneratorChannel = 1
+ uut.oscilloscopeChannel = 1
+
+ expectedData = prepareRampResponse(uut, mockLab)
assert not uut.measurementDone
assert uut.data == None
@@ -49,3 +53,4 @@ def test_frequencyResponseRamp(mockLab, uut):
assert uut.measurementDone
assert uut.data == expectedData
+
diff --git a/lab_control/test/measurement_test.py b/lab_control/test/measurement_test.py
new file mode 100644
index 0000000..07716a3
--- /dev/null
+++ b/lab_control/test/measurement_test.py
@@ -0,0 +1,53 @@
+import pytest
+
+from lab_control.measurement import *
+
+@pytest.fixture
+def uut():
+ return Measurement()
+
+def test_linearRangeAscending():
+ first = 100.0
+ last = 200.0
+ steps = 11
+
+ expectedRange = [
+ 100.0, 110.0, 120.0, 130.0,
+ 140.0, 150.0, 160.0, 170.0,
+ 180.0, 190.0, 200.0
+ ]
+
+ actualRange = getLinearRange(first, last, steps)
+ assert actualRange == expectedRange
+
+def test_linearRangeDescending():
+ first = 200.0
+ last = 180.0
+ steps = 3
+
+ expectedRange = [
+ 200.0, 190.0, 180.0
+ ]
+
+ actualRange = getLinearRange(first, last, steps)
+ assert actualRange == expectedRange
+
+def test_linearRangeTwoSteps():
+ first = 20.0
+ last = -20.0
+ steps = 2
+
+ expectedRange = [
+ 20.0, -20.0
+ ]
+
+ actualRange = getLinearRange(first, last, steps)
+ assert actualRange == expectedRange
+
+def test_linearRangeOneStep():
+ first = 20.0
+ last = -20.0
+ steps = 1
+
+ with pytest.raises(AssertionError):
+ actualRange = getLinearRange(first, last, steps)