# Ableitung eines zeitlich veränderlichen Wertes bilden



## Draco Malfoy (10 November 2012)

Hallo Forum,

gegeben sei ein zeitlich veränderlicher Wert, von welchem ich eine d/dx Funktion zur Weiterverarbeitung in einer SPS bilden muss. Wie würde man hier vorgehen, ist es überhaupt möglich, die SPS z.B. mittels Data Tables solche Sachen ausrechnen zu lassen ? 

Danke im Voraus


----------



## Larry Laffer (10 November 2012)

Hallo,
kannst du dein Vorhaben auch etwas präzisieren ? Vielleicht auch mit welcher SPS du das zu realisiern gedenkst (wenn es denn geht) ?

Gruß
Larry


----------



## Draco Malfoy (10 November 2012)

Ja, also es ist folgendes: die SPS ist eine von diesen hier: http://www.unitronics.com/Series.aspx?page=Vision350 und mir geht es darum, daß während ein Schrittmotor bestimmte Bahn abfährt, ein analoger Eingang zyklisch abgefragt werden soll und dabei bestimmte werte entstehen. Ganz grob gesagt, ein Motorschritt - eine Abfrage - ein Wert in der Tabelle. Worauf es ankommt, ist zu verstehen, ob die Werte wachsen oder sinken, und letztenendes, ein Minimum zu finden.


----------



## Larry Laffer (10 November 2012)

Also ... bei der von dir gewählten SPS muss ich passen. Die kenne ich nicht und kann auch so nichts dazu sagen.

Ganz grundsätzlich allerdings :
Deine SPS muß eine relativ kleine Zykluszeit realisieren können.
Ferner sollte sie eine inderekte Adressierung von Speicherstellen (und hier in für dich ausreichender Menge) zulassen.
Letztlich würdest du dann die eingelesenen Daten prüfen/auswerten.

In dem Teil der SPS-Welt in dem ich mich bewege (also Siemens-SPS) wäre so etwas durchaus machbar ...

Gruß
Larry


----------



## Draco Malfoy (10 November 2012)

Ok, danke schon mal. Welche Zykluszeiten wären hier angebracht ? Letztenendes durchfährt mein Schrittmotor die Bahn mit einer Geschwindigkeit von etwa 200°/Sek und jeder Schritt sind 0,9°, also allzu schnell müssen diese Daten wiederum auch nicht fließen. Wenn wir hier von einer S7-314 reden würden, wie würdest Du dann vorgehen ? Vielleicht, ist es ja sogar einfacher, die richtige SPS zu kaufen, anstatt die bestehende anzupassen...


----------



## MSB (10 November 2012)

Also fangen wir mal an:
200°/Sek = 5ms / Grad
0,9° entsprechen dann also 4,5ms

Nach gängiger Logik sollte für eine gewisse Reaktionsgarantie die Abtastzeit ungefähr doppelt so schnell sein,
also wäre die absolut maximale Zykluszeit so bei ~2,5 ms, was schon eine gewisse Hausnummer darstellt.

Das ist jetzt aber noch nur die halbe Wahrheit, industrielle Analogeingänge und auch Ausgäng haben im Regelfall,
genaueres verrät das Datenblatt, eine Wandlungszeit von 20ms Aufwärts,
das heißt im Gegenzug das du nur alle ~ 4° überhaupt einen neuen Wert erhältst, auf den du dann irgendwie reagieren kannst.

Desweiteren haben auch die Analogausgäng noch eine gewisse Wandlungszeit, z.B. 5ms, d.h. nochmal ~ 1° Verzögerung NACH der Berechnung.

Also ist die allererste Aufgabe erst mal, Hardware zu finden, welche schnell genug Werte liefern bzw. ausgeben kann.
Wenn du hier mal was gefunden hast, kannst du dir dann noch mal über den Rest Gedanken machen.

Mfg
Manuel


----------



## Draco Malfoy (10 November 2012)

Jo... also bei weitem nicht trivial das Ganze. Die Analogeingänge laufen über ein über MODBUS angekoppeltes IO also ist es wahrscheinlich noch ärger. Alternativ, könnte man natürlich auch regelungstechnisch ganz anders vorgehen, und eine ganz andere Erfassungsmethode wählen, wie z.B. ein anlaloger Differenzierer der einfach Signale wie "Positiv" oder "negativ" an digitale Eingänge der SPS legt.

Wie schnell kann denn eine SPS mit, sagen wir mal, 20mS Zykluszeit auf eine Änderung der über MODBUS von einem externen I/O übermittelten Analogwerte reagieren ? Muss ich hier gar 100mS sicherheitshalber ansetzen ??


----------



## Larry Laffer (10 November 2012)

Es ist immer noch die Frage nach dem Sinn und der Notwendigkeit.
Wenn du schon bereit bist z.B. in Richtung Siemens zu gehen, so gibt es dort natürlich auch Equipment, dass dir da keine Steine in den Weg legt. Zu der Modbus-Geschichte kann ich dir aber gar nichts sagen. Siemens hat aber auch A/D-Wandler, die dir im Millisekundentakt (wenn nötig) Werte liefern können. Aber ... was misst du denn Analog ? Vielleicht einen Abstand ?

Du kannst aber auch noch anders vorgehen :
Du misst einfach zyklisch (z.B. alle 5 ms) und liest dann den Weg und den Analogwert zusammengehörig ein.

In jedem Fall - bei der Sache solltest du schon zusehen, dass dein Einlesezyklus (ggf. mit Hilfe eines Zeit-OB's) im einstelligen ms-Bereich bleibt.
Eine CPU 314 wäre für die Aufgabenstellung auch nicht unbedingt meine Wahl (ich denke hier auch an die spätere Auswertung). Für mich fängt das gedanklich mit einer 317 an ...

Gruß
Larry


----------



## Draco Malfoy (10 November 2012)

Hm. Ja, sehr speziell das ganze, und v.a. teuer. CPU-317 ist gegenüber der visio schon eine ordentliche Ecke weiter, und v.a. für die eigentliche Aufgabe leicht überdimensioniert. Die Sachlage entspannt sich ein wenig dadurch, daß man über eine Vergrößerung der Messabstände bzw. der Bahngeschwindigkeit auf vertretbare Werte nachdenken könnte, wenn es nicht anders geht. Natürlich, 20 Sek/Umdrehung ist dann immer noch nicht tragbar, aber man kann das eventuell auf 1S/100° runterdrücken, und auch eventuell jeden zweiten Step auswerten. Das ergäbe dann schon vertretbare Zykluszeiten von 16-20mS. Die Frage ist halt, ob der MODBUS da mitmacht. Aber das kann man ggf. experimentell rausfinden.

Indirekte Adressierung indes unterstützt meine SPS, und auch so 20-30 Steps kann man da ruhig abspeichern. Wie würde man denn jetzt vorgehen, wenn man diese letzten z.B. 30 Schritte differenziell auswerten will ? Und, hauptsache, das Minimum nicht überfährt bzw. lokalisieren kann ? Letztenendes wäre das Wunschergebnis ein Algorithmus zur Minimumsfindung.

P.S: ähm, nein, es geht hier nicht um Abstand sondern um eine nur sehr schwer zu erfassende physikalische Größe, die durch eine Phasendifferenz dargestellt werden kann. Diese Phasendifferenz geht in Form von einem analogen Wert in die SPS rein. Ich habe weiter unten das Phasen-Gain Verhalten von dem Detektor angehängt.


----------



## Larry Laffer (10 November 2012)

Den Bezug von Minimum zu dem dargestellten Diagramm kann ich gerade nicht herstellen ...
Aber ganz grundsätzlich :
Du initialisierst deine "Wert_gefunden"-Variable mit einen Wert deiner Aufzeichnung.
Nun gehst du alle Werte deiner Aufzeichnung nacheinander durch und vergleichst sie mit "Wert_gefunden". Ist ein Wert kleiner dann trägst du ihn an der Stelle ein. Am Ende hast du dann den kleinsten Wert da drin stehen.

Gruß
Larry


----------



## Draco Malfoy (10 November 2012)

Das Minimum liegt in dem gegebenen Fall jeweils rechts und links von der Mitte, am Rande des Graphen. Aber der Graph wiederholt sich periodisch, das ist keine "von...bis..." Kurve, sondern ein Phasengain und es geht jeweils in beide Richtungen weiter. Und - deine Vorgehensweise spiegelt die Aufgabestellung leider nicht wieder. Ich brauche tatsächlich ein d/dx Differenzial, um festzustellen, ob die Werte wachsen, oder sinken. Wenn die Werte nämlich wachsen, dann fährt mein Motor ja ganz offensichtlich in die falsche Richtung. Die Kurvenlänge ist endlich, und es gibt nur ein Minmum auf der Fahrbahn. Dieses, gilt es, zu finden.


----------



## Larry Laffer (10 November 2012)

Diese Differential würde sich ja dadurch bilden, dass du das Array (mit den abgespeicherten Werten) durchläufst.
Was du da vorhast ist ja eher ein "den aktuellen Wert mit dem letzten Wert vergleichen und darüber den Gradienten bilden". Das würde ich so nicht machen da du keine idealen Werte einlesen wirst sondern eher etwas "zitteriges" - das heißt, dass du selbst bei einer kontinuierlichen Messung immer "einige" Werte rückwärts brauchst.

Ich muß aber auch zugeben, dass ich dein Vorhaben und dessen Sinn immer noch nicht verstanden habe. Vielleicht könnte ich dann bessere Tipps geben ...

Gruß
Larry


----------



## Draco Malfoy (10 November 2012)

Ok, es ist zum einen an und für sich schon nicht trivial, und, ich muss leider zugeben, meine Erklärungskünste waren noch nie sonderlich auf der Höhe. Könnte an einer zu sehr physikalischen und weniger elektrotechnischen Denke liegen.
Bitte um Entschuldigung, hier ein zweiter Versuch:

- Es gibt ein physikalisches Phänomen, was man am Besten mit einer Art Resonanz oder richtiger Abstimmung eines Schwingkreises beschreiben kann. Ist, wie gesagt, nur eine Übertragung bzw. Näherung. 
- Dieses Phänomen gibt als erfassbare, messbare physikalische Größe eine Phasendifferenz zweier Signale zurück, welche von einem elektronischen Detektor erfasst werden kann.
- Dieser Detektor wandelt die Phasendifferenz in einen analogen Wert um, der im Bereich 10mV - 1,8V liegt, und dessen Abhängigkeit von dem Delta Phi durch den obigen Graph dargestellt werden kann.

Nun, gibt es jetzt noch einen Schrittmotor, der die Stellgröße indirekt beeinflussen kann, in dem er einen Rotor dreht. Der Motor kann dabei die Position von 0° bis (20 Windungen x 360°) bis 7200° annehmen. Weiter darf er nicht fahren, am Anfang und Ende sitzen jeweils Endschalter. Die angenommene Phasendifferenz an einer x-beliebigen Stelle auf der Fahrbahn bewegt sich in einem Range von etwa +90° bis +270°, also immer so, daß dazwischen genau ein Minimum der Phasenfunktion eingeschlossen ist. Die Phasenfunktion hat genau dann ein Mnimum, wenn die Delta Phi =180° ist, also bei exact gegenläufiger Phasenlage.

So, jetzt muss meine SPS beim Drücken auf einen Knopf, den man vielleicht "Autotune" bezeichnen kann, automatisch, ohne fremde Hilfe, dieses Minimum finden. Wie würdest Du an diese Aufgabe herangehen ? Ich habe mir gedacht, ein d/dx von den jeweils letzten 30 Werten zu bilden, und gucken, ob da "+" oder "-" rauskommt, um festzustellen, in welche Richtung der Motor nun fahren soll.

Danke im Voraus

Gruß


----------



## Onkel Dagobert (10 November 2012)

Zur Hardware, sieh dir mal folgende Baugruppen an:

https://eb.automation.siemens.com/mall/de/de/Catalog/Product/6ES7151-8AB01-0AB0
https://eb.automation.siemens.com/mall/de/de/Catalog/Product/6ES7134-4FB52-0AB0

Ableitungen zeitdiskret zu bilden, ist eigentlich überhaupt kein Problem. Wichtig ist nur, besonders für die zweite Ableitung, die Bearbeitung im Weckalarm (S7 -OB35 etc) durch zu führen. Alles Real-Werte. Das Kürzel "AKT" steht für AKTUELL. Die Abtastzeit ist im einfachsten Fall der Aufrufintervall des OB.


```
//*** Differenz zum vorherigen Wert bilden
E_AKT := W_AKT - W_ALT;
W_ALT := W_AKT;

//*** erste Ableitung
D1_AKT := E / ABTASTZEIT;

//*** zweite Ableitung
D2_AKT := (D1_ALT - D1_AKT) / ABTASTZEIT;
D1_ALT := D1_AKT;
```

Gruß, Onkel


----------



## Draco Malfoy (10 November 2012)

Sorry, aber könntest Du die Vorgehensweise noch etwas genauer erläutern ?
Ich muss ja aus den ausgelesenen Werten mehr oder weniger einen Vektor bilden, richtig ? oder zumindest eine Wertetabelle erstellen.  Das sehe ich aber in deinem Code nicht. Wie genau passiert das in S7 ?

Und weiterhin möchte ich verhindern, daß meine Werte anfällig für zittern sind, also muss ich darauf mehr oder weniger einen Tiefpass anwenden. Die mathematische Grundlage dafür ist mir mehr oder weniger bekannt, aus der Abtasttheorie und der Lehre über diskrete LTI-Systheme und FIR-Filter. Aber diese Filter haben anspruchsvolle mathematische Implementierung, die immer auf Vektoren/Wertereihen angewendet wird. Wie kann ich also auf Wertetabellen in S7 mathematische Operation anwenden, zum Beispiel solche wie nachfolgend beschrieben: http://de.wikipedia.org/wiki/Filter_mit_endlicher_Impulsantwort ??

Ist es überhaupt möglich, in S7 komplexere mathematische Funktionen einzubauen ?


----------



## Thomas_v2.1 (11 November 2012)

Wenn ich deine Grafik aus Post #9 sehe, würde ich vermuten dass so was wie einen Extremwertregler benötigst.
Wenn du nur einmal tunen musst, kannst du am einfachsten (wenn der Prozess es ermöglicht) den kompletten Stellbereich durchfahren und die passende Stellgröße zum Extremwert suchen. Das funktioniert dann auch falls es mal mehr als nur ein lokales Extremum gibt.
Soll auch im laufenden Betrieb möglichst auf dem Extremwert gefahren werden, so gibt es dazu mehrere Strategien. Für die Solartechnik gibt es das sog. maximum power point tracking:
http://en.wikipedia.org/wiki/Maximum_power_point_tracking

Ich habe sowas noch nicht programmiert, aber ich habe meine Überlegungen wie ich das machen würde mal aufskizziert.
Die aktuelle Stellgröße y wird dazu immer um einen Wert delta-y erhöht und verringert. Die Änderung des Istwertes wird dann mit der Änderung der Stellgröße korreliert, hier einfach vorzeichenbehaftet multipliziert.
Wenn man aus diesem Wert über die Zeit das Integral bildet, ergibt sich wenn man sich auf dem Extremwert befindet der Wert 0 (optimal), wenn man sich auf der linken Seite befinden ein positiver und auf der rechten Seite ein negativer Wert.
Die Basisstellgröße y erhöht man nach einem Durchlauf um diesen Summenwert mal einen beliebigen Verstärkungsfaktor, und ergibt die neue Basisstellgröße für den nächsten Durchlauf. Dadurch 'fährt' man mit der Stellgröße sozusagen immer berghoch.
Man findet damit natürlich immer nur ein lokales Extremum. Vom Prinzip her müsste das zumindest so funktionieren.


----------



## Onkel Dagobert (11 November 2012)

Draco Malfoy schrieb:


> Sorry, aber könntest Du die Vorgehensweise noch etwas genauer erläutern ?..


Nun ja, du wolltest ja zunächst ermitteln, wie sich dein Wert über der Zeit ändert. Die erste Ableitung liefert dir die Geschwindigkeit und die Richtung der Änderung, die zweite Ableitung liefert dir die Änderung der Geschwindigkeit, bzw. die Beschleunigung.


----------



## Draco Malfoy (11 November 2012)

Hallo Thomas,
danke für die vorgeschlagene Vorgehensweise !


Thomas_v2.1 schrieb:


> Wenn ich deine Grafik aus Post #9 sehe, würde  ich vermuten dass so was wie einen Extremwertregler benötigst.


Letztenendes, genau das.


> Wenn du nur einmal tunen musst


Nein, es muss auch im laufenden Betrieb nachgefahren werden. Bzw., ein Komplettdurchlauf ist nicht wünschenswert.


> Ich habe sowas noch nicht programmiert, aber ich habe meine Überlegungen wie ich das machen würde mal aufskizziert.
> Die aktuelle Stellgröße y wird dazu immer um einen Wert delta-y erhöht  und verringert. Die Änderung des Istwertes wird dann mit der Änderung  der Stellgröße korreliert, hier einfach vorzeichenbehaftet  multipliziert.
> Wenn man aus diesem Wert über die Zeit das Integral bildet, ergibt sich  wenn man sich auf dem Extremwert befindet der Wert 0 (optimal), wenn man  sich auf der linken Seite befinden ein positiver und auf der rechten  Seite ein negativer Wert.


Wenn ich Dich richtig verstehe: Du schlägst vor, den Vektor mit den  Ableitungen der Istwerte zeilenweise mit dem dS (Änderung der Wegstrecke) und mit dem  dt (Fahrzeit für dieses Wegstück) zu multiplizieren, und die Ergebnisse  dann in einen Ergebniswertvektor zu schreiben ?? Kling nicht schlecht,  ich würde bloß auf die Werte vorher einen gleitenden Mittelwert (Filter)  sagen wir mal, über 3 anweden, um das "Zittern" loszuwerden. Können wir als Vorgehensweise festhalten.


> Die Basisstellgröße y erhöht man nach einem Durchlauf um diesen  Summenwert mal einen beliebigen Verstärkungsfaktor, und ergibt die neue  Basisstellgröße für den nächsten Durchlauf. Dadurch 'fährt' man mit der  Stellgröße sozusagen immer berghoch.


D.h., du schlägst vor, die Stellgröße variabel zu machen, um schneller  zum Ziel zu gelangen ? Das klingt ja richtig gut. Versteh am frühen  morgen noch nicht ganz, wie ich das auf meinen "Ergebnisvektor" praktisch  anwenden kann. Dann müsste ich die _aktuelle_ Stellgröße y mit dem ΔۤI, Δۤt, ΔۤS und dem Verstärkungsfaktor δ multiplizieren und an den Motor weitergeben ? Und am Ende komme ich ganz automatisch dahin, wo mein  Extremum liegt ? Weil die Stellgröße dadurch automatisch wachsen oder sinken würde, je nachdem, ob ich mich dem extremum nähere, oder entferne, und ihr Vorzeichen wechseln. Es ergäbe dann quasi eine intergrative Annäherung an die Minimumslage. Wenn das funktioniert, wäre das eine richtig gute Idee :wink: Jetzt müsste mir nur noch jemand beim Implementieren ein Wenig helfen...

P.S: Globale Extrema befinden sich wenn - dann nur am Rande, und müssen sicher ausgeschlossen werden. D.h. wenn der Motor durch den Regelvorgang  einen Endschalter anfährt, wird einfach ein Fehler zurückgemeldet und das System zum Reset aufgefordert.

P.P.S: D.h., die Formel für die Berechnung des neuen Wertes für y müsste lauten: ΔۤI/dt * y (alt) * δ * Δۤt = y(neu) - richtig oder nicht ?


----------



## Draco Malfoy (11 November 2012)

Onkel Dagobert schrieb:


> Nun ja, du wolltest ja zunächst ermitteln, wie sich dein Wert über der Zeit ändert. Die erste Ableitung liefert ....


Nein nein, ich wollte wissen, wie man einen Vektor sagen wir mal, mit n-Einträgen aufsetzt und diese Operationen in einer Schleife auf den Vektor anwendet. Im SPS-Code. Oder, von mir aus, auch ohne Schleifen, aber zumindest bei der (für meine SPS zuständigen) VisiLogic Software http://www.unitronics.com/Content.aspx?page=Downloads tue ich mich noch schwer damit, die Vektoren mathematisch zu verarbeiten.


----------



## Larry Laffer (11 November 2012)

Hallo,
ich muß sagen, dass sich die aktuelle Entwicklung "etwas" von meiner gedachten Vorgehensweise unterscheidet. Ich würde tatsächlich den ganzen Kurvenverlauf erst einlesen und ihn dann auswerten. Auf diesem Weg läßt sich auf jeden Fall sicher stellen, dass du den richtigen Punkt (aber leider erst im Nachhinein) findest.

Ob und wie weit es auch quasi "on the fly" geht wage ich nicht beurteilen zu wollen. Da du auf jeden Fall deine eingelesenen Werte glätten mußt (zumindestens nach meiner Erfahrung mit so etwas) denke ich, dass du die gewünschte Stelle auf jeden Fall "ein wenig" überfahren mußt um beurteilen zu können, ob du sie gefunden hast. Ob du mit einer Rückwärts-Speicherung von 30 Werten hinreichst mußt du ausprobieren - ich würde mich da aber zumindestens am Anfang nicht einschränken (also lieber etwas mehr und ggf. dann später reduzieren). Als Abtastung würde ich auch ein festes Zeit-Intervall nehmen - und wenn du dann gleich auch mit Auswerten willst und gleichzeitig schnell abtasten möchtest dann sind wir auch schon wieder bei einer leistungsfähigen CPU ...

Gruß
Larry


----------



## Draco Malfoy (11 November 2012)

Hey Larry,

ähm - also ein kompletter Suchlauf ist leider nicht möglich, nein. Die SPS _muss_ es "on the fly" machen, ansonsten muss man sich eben eine andere regelungstechnische Strategie überlegen, die das möglich macht.
Und wegen Werteglättung - ich habe mich gerade gefragt, ob das tatsächlich nötig ist. Letztenendes vergleichen wir immer zwei benachbarte Werte. Wenn deren Differenz bereits im "Rauschbereich" liegt, dann haben wir den Minimumspunkt bereits mit ausreichender genauigkeit erreicht. Ich habe mir sogar überlegt, den Motor ruhen zu lassen, sobald der zu fahrende Winkel kleiner als 1,8° beträgt. Ansonsten wird er eventuell immer um den Minimumspunkt oszillieren und kommt nicht zu Ruhe.


----------



## Thomas_v2.1 (11 November 2012)

Weil mich das doch interessierte ob das funktioniert, habe ich gerade mal einen Versuch gemacht und die Skizze in Programmcode umgesetzt. Vom Prinzip her findet das Programm den optimalen Punkt 

Ich habe zum Test eine Regelstreckensimulation programmiert deren Form einer Gaußschen Glockenkurve entspricht. Der Punkt an dem die Stellgröße einen maximalen Istwert annimmt kann man einstellen.
Dieses sind die Kurvenverläufe bei zwei verschiedenen Werten:
Maximaler Wert bei 50% Stellgröße:


Maximaler Wert bei 70% Stellgröße:



Die Maximumerkennung habe ich in Form einer Schrittkette programmiert. Es fehlen natürlich noch ein paar Dinge wie Grenzwertüberprüfungen, Zeitumstellungen nur bei Inaktivität ändern etc., aber das Prinzip sollte daraus hervorgehen:

```
FUNCTION_BLOCK "Extremwertregler"

VAR_INPUT
    Run : BOOL;                 // Funktion aktivieren
    X : REAL;                   // Istwert
    T_Wart : TIME := T#500ms;   // Wartezeit zwischen Suchfunktionen
    T_Takt : TIME := T#500ms;   // Dauer für welche die Stellgröße nach oben/unten verschoben wird
    T_Paus : TIME := T#500ms;   // Wartezeit zwischen oben/unten
    Gain : REAL := 0.1;         // Verstellverstärkung
    Y_Diff : REAL := 1.0;       // Differenz um die die Stellgröße verändert wird
    Y_Start : REAL := 30.0;     // Startwert für Y
END_VAR

VAR_OUTPUT
    Y : REAL;                   // Stellgröße
    Y_Basis : REAL;             // Bezugs-Stellgröße
    X_Basis : REAL;             // Bezugs-Istwert 
    Sum_UpDn : REAL;
    State : INT;                // Schrittkette
END_VAR

VAR    
    Timer1 : TON;    
END_VAR

BEGIN
IF NOT Run THEN
    State := 0;
END_IF;

(* Schrittkette Suchlauf *)
CASE State OF    
    0:  (* Initialisieren *)
        Y := Y_Start;
        Y_Basis := Y;
        X_Basis := X;
        Sum_UpDn := 0.0;
        Timer1.IN := false;
        IF Run THEN
            Timer1.PT := T_Takt;
            State := 1;
        END_IF;     
    1: (* Stellgröße nach oben fahren *)
        Y := Y_Basis + Y_Diff;
        IF Timer1.IN THEN
            Sum_UpDn := Sum_UpDn + (Y - Y_Basis) * (X - X_Basis);
        END_IF;        
        Timer1.IN := true;        
        IF Timer1.Q THEN
            Timer1.IN := false;
            Timer1.PT := T_Paus;
            State := 2;
        END_IF;
    2: (* Pausenzeit *)
        Y := Y_Basis;        
        Timer1.IN := true;
        IF Timer1.Q THEN
            Timer1.IN := false;
            Timer1.PT := T_Takt;
            State := 3;
        END_IF;
    3:  (* Stellgröße nach unten fahren *)
        Y := Y_Basis - Y_Diff;
        IF Timer1.IN THEN
            Sum_UpDn := Sum_UpDn + (Y - Y_Basis) * (X - X_Basis);
        END_IF;        
        Timer1.IN := true;        
        IF Timer1.Q THEN
            (* neue Basisstellgröße bestimmen *)
            //Y_Basis := Y_Basis + Sum_UpDn * Gain; // << funktioniert nicht so gut
            IF Sum_UpDn >= 0 THEN
                Y_Basis := Y_Basis + Y_Diff * Gain;
            ELSE
                Y_Basis := Y_Basis - Y_Diff * Gain;
            END_IF;
            Y := Y_Basis; 
            Sum_UpDn := 0.0;
            Timer1.IN := false;
            Timer1.PT := T_Wart;
            State := 4;
        END_IF;
    4:  (* Wartezeit für nächsten Durchlauf *)         
        Timer1.IN := true;
        IF Timer1.Q THEN
            X_Basis := X;
            Timer1.IN := false;
            Timer1.PT := T_Takt;
            State := 1;
        END_IF;        
END_CASE;

Timer1();

END_FUNCTION_BLOCK
```

Wenn in der Regelstrecke eine Zeitkonstante vorhanden ist, muss zwischen den Prüf-Schritten gewartet werden bis sich diese wieder eingeschwungen hat.
Was nicht so gut funktionierte ist die Basis-Stellgröße anhand der Stärke der Reaktion zu verändern (auskommentierter Teil). Es wird jetzt um einen konstanten Wert nach oben/unten verstellt. Dadurch dauert das einregeln relativ lange, da müsste man noch eine bessere Lösung finden.

Und hier mal eine Trendkurve wenn das Programm arbeitet:


Die grüne Linie zeigt die optimale Stellgröße an, das ist der Wert der an der Streckensimulation eingestellt wird.
Wie man sieht wird die Regelrichtung automatisch richtig erkannt. Das Verfahren sollte durch die Integration auch recht unempfindlich gegenüber Messwert-Störungen sein.


----------



## Draco Malfoy (12 November 2012)

Hallo Thomas,

ja danke vielmals für die Simulation und den Code. Allerdings stört mich noch ein wenig, daß es nicht möglich ist, die Suchschrittweite im Verlauf der Suche anzupassen, damit man schneller zu dem Ergebnis käme. Ich vermute mal, daß der ursprüngliche physikalische Sachverhalt sich sogar tatsächlich durch eine gaußsche Glocke darstellen ließe.


----------



## Thomas_v2.1 (12 November 2012)

Vom Prinzip her macht mein Programm ja nicht mehr als durch das Hoch- und Runtertakten die Steigung der Tangente am aktuellen (Basis- oder Bezugs-) Punkt zu bestimmen. 

Das mit der Anpassung der Schrittweite funktioniert darum theoretisch schon (der auskommentierte Teil). Wie gut das funktioniert hängt dabei vom Kennlinienverlauf ab. Zumindest müsste man in der Praxis die Schrittweite nach oben und unten hin auf sinnvolle Werte begrenzen, damit man bei einer Messwert-Störung nicht sofort völlig aus dem Ruder läuft. 

Was ich oben nicht dazugeschrieben habe: Die Funktion muss selbstverständlich in festen Zeitabständen aufgerufen werden, ansonsten müsste man die Zeit in die Berechnung noch mit aufnehmen.


----------



## borromeus (23 November 2012)

Mal eine ganz dumme Idee:
Bei einer Analogeingangskarte zB 7KF02 werden die Kanäle in einem MUX umgeschaltet und einem ADU umgerechnet.
Hänge ich das Spannungssignal nun an zwei Kanäle gleichzeitig, sollte ich eigentlich zeitversetzt Werte bekommen, da der MUX und ADU immer eine gewisse Zeit braucht.
Das zusammen in einem schnellen WeckOB und Teilprozessabbild sollte doch bei
Kanal 0 minus Kanal 1 > 0 heissen Wert sinkt
Kanal 0 minus Kanal 1 < 0 heissen Wert steigt

eventuell kann man auch Kanal 2,3,4 oder 7 statt Kanal 1 nehmen (mehr Zeit).

Beim ersten Minuswert habe ich den Tiefpunkt erreicht.....

Glaubt irgendwer, dass das funktionieren kann?
Ich bin mir nicht ganz klar wann die AE-Karte das/die Werte zur Verfügung stellt.....

Gruß
Karl


----------

