From 148891dee33dc0bfdb0913ccefda1bc28a8516d6 Mon Sep 17 00:00:00 2001 From: Timo Denk Date: Sat, 30 Mar 2019 11:05:10 +0100 Subject: [PATCH] Switch from P-controller to gradual adjustment --- Parameters.h | 7 +++-- PressureControlSoftware.ino | 58 +++++++++++++++++++++++++------------ README.md | 7 +++-- 3 files changed, 49 insertions(+), 23 deletions(-) diff --git a/Parameters.h b/Parameters.h index 12f42c7..13d0bf4 100644 --- a/Parameters.h +++ b/Parameters.h @@ -4,11 +4,12 @@ // motor control const float openingTolerance = 0.1; -// P-controller +// valve controller const float toleratedPsiDelta = 0.1; -const float minOpening = 0.05; -const float maxOpeningAtPsiDelta = 1.5; +const float valveSpeed = 0.01; +const float minOpening = 0.05; // disabled +const float maxOpeningAtPsiDelta = 1.5; // disabled // derived parameters diff --git a/PressureControlSoftware.ino b/PressureControlSoftware.ino index 713698f..6bee79e 100644 --- a/PressureControlSoftware.ino +++ b/PressureControlSoftware.ino @@ -15,26 +15,48 @@ void setup() { } void loop() { - float targetPsi = getTargetPressureDelta(); - float measuredPsi = getPressureMeasuredDelta(); - float offPsi = targetPsi - measuredPsi; - - float valveOpening = Valve::getOpening(); - - float valveOpeningTarget = computeValveOpeningTarget(targetPsi, measuredPsi); - Valve::setOpening(valveOpeningTarget); + float prevValveTarget = Valve::getOpening(); + float valveOpeningTarget = prevValveTarget; + long valveLastUpdatedMillis = millis(); + + while (true) { + long currentMillis = millis(); + float targetPsi = getTargetPressureDelta(); + float measuredPsi = getPressureMeasuredDelta(); + float offPsi = targetPsi - measuredPsi; + + float valveOpening = Valve::getOpening(); - #ifndef SERIAL_DEBUG - Display::showPressureSelection(measuredPsi, targetPsi); - Display::showValveOpening(valveOpening, valveOpeningTarget); - Display::submit(); - #endif + if (currentMillis < valveLastUpdatedMillis) { + // handle millis overflow case + continue; + } + if (currentMillis - valveLastUpdatedMillis >= 100) { + valveLastUpdatedMillis = currentMillis; + + //float valveOpeningTarget = computeValveOpeningTarget(targetPsi, measuredPsi); - #ifdef SERIAL_DEBUG - Serial.print("Off by: "); - Serial.print(offPsi, 2); - Serial.println(" psi"); - #endif + if (abs(offPsi) > toleratedPsiDelta) { + // only update if the tolerated threshold is exceeded + valveOpeningTarget = prevValveTarget - offPsi * valveSpeed; + valveOpeningTarget = min(1., max(0., valveOpeningTarget)); + Valve::setOpening(valveOpeningTarget); + prevValveTarget = valveOpeningTarget; + } + } + + #ifndef SERIAL_DEBUG + Display::showPressureSelection(measuredPsi, targetPsi); + Display::showValveOpening(valveOpening, valveOpeningTarget); + Display::submit(); + #endif + + #ifdef SERIAL_DEBUG + Serial.print("Off by: "); + Serial.print(offPsi, 2); + Serial.println(" psi"); + #endif + } } float computeValveOpeningTarget(float targetPsi, float measuredPsi) { diff --git a/README.md b/README.md index 59f2dd6..568e353 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,7 @@ # Pressure Control Software +**Description**. Software for an airplane cabin pressure control system. The airplane motor constantly pumps air into the cabin and a valve controls the flow of cabin air to the outside. It is desired not to have too much pressure relative to the surrounding air to put less stress on the airplane frame. The software controls the valve depending on user input and measured pressure differences. + ## Hardware This Arduino software was developed by Denk Development in Mar 2019 for the microcontroller Atmega 328P. @@ -32,8 +34,9 @@ Parameters can be adjusted in the header file `Parameters.h`. Not that instead o * **Opening tolerance** `openingTolerance`, _Motor-Positions-Toleranz_, permitted value range [0,1]. Controls which deviation of target motor position and actual motor position is still tolerated until a motion is being triggered. If the motor target is e.g. `0.2`, and the measured position is `0.25`, nothing will happen with an `openingTolerance` greater than or equal to `0.05`. The tolerance for motion is derived from this value through division by 2. So while adjusting the motor position, movement will not stop unless half of the `openingTolerance` is reached. * **Tolerated PSI delta** `toleratedPsiDelta`, _akzeptierte Differenz von Soll- und Ist-PSI_, permitted value range [0,maxPSI]. After which difference in preassure levels (target vs. actual) a motion is being triggered. Note that there is no tolerance for motion because this is already caught by the motor positioning tolerance. -* **Minimum valve opening**, `minOpening`, _geringste Öffnung des Ventils_, permitted value range [0,1]. Once a deviation from the target PSI is exceeding `toleratedPsiDelta` the valve will be opened to `minOpening` the least. May be set to `0` when in doubt. -* **Max opening at PSI delta** `maxOpeningAtPsiDelta`, _Differeny von Soll- und Ist-PSI, bei der das Ventil komplett offen steht_, permitted value range [0,maxPSI). At what PSI difference the valve is openend entirely. +* **Valve adjustment speed** `valveSpeed`, _Geschwindigkeit der Ventilanpassung_, permitted value range [0, inf). How quickly the valve adjusts do divergence of actual and target pressure. Per 100 ms. +* [disabled] ~~**Minimum valve opening**, `minOpening`, _geringste Öffnung des Ventils_, permitted value range [0,1]. Once a deviation from the target PSI is exceeding `toleratedPsiDelta` the valve will be opened to `minOpening` the least. May be set to `0` when in doubt.~~ +* [disabled] ~~**Max opening at PSI delta** `maxOpeningAtPsiDelta`, _Differenz von Soll- und Ist-PSI, bei der das Ventil komplett offen steht_, permitted value range [0,maxPSI). At what PSI difference the valve is openend entirely.~~ ## Warranty