[Modul] PID Controller - Beta, try out

Hallo zusammen
hab ein kleines Modul gebaut um einen universellen PID Regler umzusetzen. Vorerst nur für den Eigengebrauch, bei Interesse würde ichs ggfl. auch schauen wie ich es in den Store bekomme.
Ich möchte es vorwiegend als Heizungsregler einsetzen, wobei natürlich auch Anwendungen denkbar sind.
Weil universell ist nur der nackte PID Regelalgorythmus umgesetzt. Keine Funktionen hinsichtlich Heizungsregelung.
Es wird also nur Sollwert und Istwert verglichen und danach je nach gewählter Arbeitsweise per P-I-D eine neue Stellgröße im Bereich 0-100 gebildet.
Funktional ist IMHO alles in Ordnung, allerdings hab ich so meine Schwierigkeiten mit der Parametrierung.
Wäre nett wenn jemand mit Regeltechnikerfahrung insbesondere mit Erfahrung in der Einstellung solcher Regler das mal ein wenig ausprobieren könnte.
Als reiner P Regler (I und D Anteil auf 0) läuft er gut sobald ich aber I Anteil dazu nehme wird es etwas spooky. Hab da aber leider keine Erfahrung wie/ob so etwas mit den recht trägen Raumheizung überhaupt gut funktioniert.
evtl. ist auch meine Berechnung noch net ganz clean …
Falls jemand Lust zum probieren hat und mir Feedback geben kann:

Doku usw. gibts noch keine. Das Einstellungsformular sollte eigentlich selbsterkläend sein.

schönen Dank fürs Feedback oder Hilfe zur Algorythmusverbesserung
Bernhard

Update:
Das Modul sollte nun auch im Module Store im Beta Kanal verfügbar sein. Suche nach „PID_Controller“

1 „Gefällt mir“

Hallo Bernhard,

diese Idee hatte ich auch schon länger.
Ich habe mir das PHP-Modul angesehen und finde die Lösung einfach aber gut!

Das kann man jetzt noch in epischer Breite ausrollen. Ich würde aber jetzt erst mal auf Feedback warten.

Super gemacht!!

PS: Bei I und D Anteil kann ich dir helfen.

Servus

Ja danke das du es dir mal ansiehst.
Hab es in mehreren Räumen als Heizungsregler laufen, als reiner P-Regler tut er was er soll.
Wenn ich allerdings mit der internen Regelcharakteristik der Spirit Heizörperventile vergleiche so muß ich sagen das die es deutlich besser können.
Da wäre eben mein Ziel es per I und D entsprechend hinzubekommen. Naja, der Winter ist noch lang…

Und ja, Schnickschnack könnte man noch einigen mehr einbauen (zb. Engangswerte averagen, oder verschiedene Skalierungen für den Ausgang, Doku natürlich). Erst muß aber die Basis passen.
Ich möchte es aber immer als reinen Regler belassen und applikationsspezifische Funktionen extern abdecken.

schöne Grüße
Bernhard

Hallo Bernhard,

auch wenn ich keine konkrete Anwendung habe so wollte ich doch gerne mit deinem Modul „spielen“.

Allerdings habe ich Verständnisprobleme mit den Parametern bzw. deren Wirksinn und Wertebereich.

Bei meinen KNX-Heizungsaktoren (PI-Regler) wird der P-Anteil so parametriert: xx K Regelabweichung entsprechen 100% Stellwert. Soweit einfach: P-Parameter auf 5K => Temperaturdifferenz 1K erzeugt 20% Stellwert über den P-Anteil.

Für einen ersten Test deines Moduls habe ich also den P-Gain auf 10 eingestellt und erwarte bei Tist=18, Tsoll=20 einen Wert von 2*10 = 20%. Den Scalingfactor habe ich auf 1 eingestellt, I- und D-Anteil auf 0.

Ist das soweit richtig oder ist deine Berechnung im Modul anders? Irgendwie bekomme ich noch keine sinnvollen Stellwerte.

Viele Grüße
Volker

edit: Gerade entdeckt dass unten im Modul die Werte angezeigt werden und in meinem Beispiel der P-Gain nicht 10 sondern 0.10 betragen muss. Dann also die Zusatzfrage, wie die Zeiteinheit beim I-Anteil gerechnet wird? Sind das Sekunden?

Servus Volker
Die Faktoren für P-I-D stellen den mathematischen Anteil am Endergebnis für Vollauschlag dar. Der typische Wertebereich ist 0-1.
Wenn die Summe aller drei Faktoren 1 ist, dann entspricht Fullscale genau dem und Scaling eingestelltem Wert.
Denkst du es wäre besser es als 0-100 also als % einzugeben ?

Für I bewerte ich kein Zeitintervall. Weiß nicht recht wie ich das mitverrechnen soll. Irgendwie müßte man dazu wohl eine art Basistakt vorgeben. Normalerweise werden die Istwerte ja periodisch in gleichen Zeitintervallen upgedated, von da her dachte ich das ich es weglassen kann.
evtl. liegt aber auch genau da mein Denkfehler drin ?

schöne Grüße
Bernhard

Hallo Bernhard,

vielen Dank, mein Denkfehler. Ich hatte die Faktoren so erwartet, dass man auf Wertebereich 0-100 kommt. Mit Wertebereich 0 bis 1 passt der P-Anteil.

Der I-Anteil sollte mit der Zeit ansteigen, eben die aktuelle Abweichung integrieren. Da verhält sich dein Modul unerwartet: in meinem Test mit 2K Temperaturdifferenz und I-Faktor 0.1 springt der I-Anteil auf 20% und bleibt dort offenbar konstant. Man würde aber eine Rampe erwarten, wo der I-Anteil von 0 beginnen langsam hochläuft. Der I-Faktor würde die Steilheit dieser Rampe festlegen.

ABER: Bei meinem Test habe ich feste Ist- und Sollwerte vorgegeben, die werden von mir nicht aktualisiert. Ich warte einfach was passiert - und es passiert eben nix. Der der I-Anteil startet bei 20% anstatt 0% und verbleibt dort. Müsste der Ist-Wert in einem bestimmten Zeitraster aktualisiert werden damit sich beim I-Wert was tut?

Viele Grüße
Volker

Für den I Anteil summiere ich die Fehler auf, allerdings nur wenn:

  • der Regler nicht bereits auf Endanschlag steht also nicht >0 und <100 ist
  • der I Anteil < 100 * Faktor ist
    Das hab ich so gemacht damit mir der I Anteil nicht ins unendliche läuft.

Aber du hast recht, die Steigung müßte irgendwie mit rein, wenn ich richtig nachdenke würde ja das angesprochene Verhältnis von „Basistakt“ zu „Zeitabstand zur letzten Messung“ sowas bewirken.

Mein beruflicher Schwerpunkt liegt mehr in die Messtechnik und weniger in die Regeltechnik, von da her ist mir das nicht so geläufig.
Vielen Dank für den Denkanstoss ! :slight_smile:

gruß
Bernhard

Also bei jedem neu eintreffenden Ist-Wert, oder was gibt den Takt?

Ja, (ReCalcInterval = 0)
oder man stellt den Takt für Neuberechnung fix ein (ReCalcInterval < 0) . Das ist gedacht für Sensoren welche in sehr kurzen Intervallen neue Werte liefern.

bb

Seltsam, irgendwas funktioniert bei mir nicht.

Ich hatte einen festen Ist-Wert eingetragen und ReCalcInterval auf 5 Sekunden. Da ist der I-Anteil beim Reset des Reglers sofort auf 20% gesprungen und bleibt seit einer Stunde unverändert.

OK, ich schau mal.
bb

Vielleicht ein kleiner Hinweis aus der Regelungstechnik, der I-Anteil ergiebt sich aus einer Sprungfunktion auf den Vorlauf-Sollwert z.B 10° und der daraus ermittelten Zeit bis zum Erreichen des Istwertes des Vorlaufes. Daraus hast du die Zeitkonstante für den Integralanteil deines Reglers. Auf keinen Fall die Zeitkonstante zwischen Vorlauf und Rücklauf bilden. denn die ist variabel je nach Reglerstellung und würde somit das gesamte System unstabil machen. Aufgrund der Trägheit eines Heizsystems sollte man auf die D-Funktion bei einer Heizung verzichten, die D-Funktion bringt das ganze System nur zum Schwingen.

Lutz
Gruß aus dem Norden

Ich habe einen PID in SCL in der Firma.
Ich stelle das hier am Montag ein.

Hi,

coole Sache sowas such ich gerade. Du willst damit nicht zufällig deine Eurotronic Spirit über IPS im Stellwertmodus steuern oder?

Grüße
Rolf

  • doch, um die geht es erstmal :slight_smile:
    Hab aber noch mehr Anwendungen wo sich ein PID gut machen würde.

Im reinen P Modus läuft es eh ganz ordentlich. Aber wie du oben lesen kannst muß ich beim I noch nachbessern.
Hier ein Plot mit reinem P:

Viel schöner wäre ja wenn wir den Spirits die Temperatur senden könnten und die würden dann ihr Ding selbst machen - wie schon im anderen Thread diskutiert …

Nur mal interessehalber, was Ihr da gerade macht ist nur für träge Systeme sinnvoll bzw. nutzbringend richtig ? Ihr wollt glaube ich verhindern das die Raum Temperatur übersteuert richtig ?

Hmm, nein eigentlich nicht.
Bei einem PID Regler kann man die Regelcharakteristik ja nach Anwendungsfall dediziert einstellen.

Ein PI-Regler hat für Raumtemperaturregelung schon Vorteile gegenüber einem reinen P-Regler.

Überlegung dazu:
Im Idealfall soll der Regler die Solltemperatur genau einhalten, ohne Abweichungen nach oben oder unten. Bei einem reinen P-Regler (=Stellwert proportional zur Temperaturdifferenz) geht der Stellwert beim Erreichen der Soll-Temperatur aber auf 0, der Raum würde also nicht mehr beheizt sobald die Zieltemperatur erreicht ist und kühlt langsam aus. Erst diese Temperaturabweichung beim Abkühlen führt dann dazu, dass der Stellwert wieder ansteigt. Ergebnis: die Raumtemperatur würde um den Sollwert pendeln.

Was benötigt wird ist eine Regelung, die bei Erreichen der Solltemperatur die richtige Heizleistung beibehält, um den Raum auf dieser Temperatur zu halten. Das leistet beim PI-Regler der I-Anteil.

Ich habe ein Beispiel angehängt vom PI-Regler in unserem Bad, interessant ist dort der mit Pfeil markierte Zeitraum. Die Ist-Temperatur (gelb) entspricht der Soll-Temperatur (orange) und diese Temperatur wird über einen Stellwert (grün, rechte Skala) von ca. 20% gehalten, der aus dem I-Anteil stammt. Der P-Anteil ist hier nahe Null weil die Soll-Temperatur bereits erreicht ist und regelt nur minimale Schwankungen aus.

Reglerparameter des zugehörigen PI-Reglers im KNX Heizungsaktor:
P-Anteil 2K, also 2K Temperaturabweichung führen zu 100% Stellwert durch P-Anteil
I-Anteil Nachstellzeit: 90 Minuten

Im Beispiel von Bernhard gibt es ebenfalls einen Stellwert der durchgehend größer Null ist und eine gewisse Wärmezufuhr auch beim Erreichen der Solltemperatur bringt. Bei meinen Tests mit dem PID-Modul wird der vermeintliche I-Anteil aber nur einmalig beim Start des Moduls berechnet und ändert sich danach gar nicht mehr.

Hallo Bernhard,

bin etwas spät sorry.

Der Code ist noch in SCL.


D-Anteil:

Der Ausgangswert ändert sich als Funktion der Änderungsrate des Werts am Eingang
multipliziert mit der Differenzierungszeitkonstante diffTime.
Mit dem folgenden Algorithmus werden diskrete Werte berechnet:

differential = (value_n - value_n-1) * diffTime / Scan time

Scan time ist die Abtastzeit des Programms.

Das ist der Code in SCL:

//Berechnung des Ausgangswertes
#differential := (#value - #statOldValue) * #diffTime / #scanTime;

//Sichern des Wertes als Altwert
#statOldValue := #value;

„statOldValue“ muss in PHP natürlich eine speichernde externe Variable sein.


I-Anteil:

Die Integralberechnung beinhaltet die Aufsummierung jener Trapezflächen,
die sich zwischen den letzten beiden Funktionswerten am Eingang „value“ und der Zeit aufspannen.
Die Abtastzeit wird am Bezeichner scanTime fest eingestellt. Diese Trapezfläche ist identisch
mit dem Produkt aus dem Mittelwert der beiden Prozesswerte und dem Zeitintervall.

Der Code in SCL:

// Reset
IF #reset = true THEN
#integral := 0.0;
#statOldValue := 0.0;
#statIntegral := 0.0;
RETURN;
END_IF;

// Write input value to temp variable
#tempValue := #value;

// Convert scan time in seconds
#tempScanTime := #scanTime / 1000.0;

IF NOT #enable THEN
#statOldValue := 0.0;
RETURN;
END_IF;

// Add LastScalIn to ScalIn
#tempValue := #tempValue + #statOldValue;

// Save last input
#statOldValue := #value;

// Divide in half statScalIn
#tempValue := #tempValue / 2.0;

// Multiply with Delta Time
#tempValue := #tempValue * #tempScanTime;

// Calculate new integral
#statIntegral := #statIntegral + #tempValue;

// Write outputs
#integral := #statIntegral;

Alle Variablen die mit stat beginnen sind speichernde Variablen (Variablen die der Klasse gehören).
Alle Variablen die mit temp beginnen sind temporäre Zwischenspeicher.

Ich habe den I und D Anteil nach dem P-Anteil gebildet.

Der Reset ist ein Eingang um den I-Anteil zu nullen.

Ich melde mich nachher nochmal.

Hallo, wollte mal bescheid geben wie es weiterging.
Kurz: Ich teste noch…
Hab mehrere Fehler gefunden und ausgebessert. Und nun auch ein Zeitintervall für die Integralkomponente hinzugefügt. Das sieht schon viele besser aus jetzt.
Gut isses aber immer noch nicht, weil es sein kann das der Integralwert zu groß wird, und dann braucht es ewig bis er wieder „zurückkommt“. Da muß ich noch irgendwie harte Limits definieren.

Muß aber sagen das der Hauptzweck die zWave Spritthermostate zu steuern nicht gut klappt.
ich mein es geht schon, wirklich zuverlässig ist das nicht. Die Dinger sind im Stellwertmodus zu zickig. Das gefällt mir nicht.

gruß
bb