Forum: Mikrocontroller und Digitale Elektronik So baue ich ein digitales Differenzierglied.


von Armin (Gast)


Lesenswert?

Problemstellung
Es ist ohne Weiteres möglich ein zeitdiskretes Signal (Wertefolge, die 
in gleichmäßigen Abständen gemessen wird), zu differenzieren. Meistens 
allerdings braucht man diese Ableitung aber "sofort" also "on-the-fly" 
und nicht erst, wenn das komplette Signal eingelesen ist.
Hier also ein kleines How-To, wie man sich ein Differenzierglied 
beliebiger Genauigkeit baut.

Theorie
Die Theorie erfordert Grundlagenwissen Regelungstechnik & Mathematik:
Laplace-Transformation, z-Transformation, evtl. Tustin-Transformation, 
Übertragungsfuntkion, realisierbare Übertragungsglieder, 
Approximationsverfahren (speziell Padé-Approximation), ...
und wird möglichst klein gehalten.

Namenskonvention
Der Algorithmus zur Berechnung der Ableitung wird auf ein periodisch 
digitalisiertes Analogsignal angewandt. Diese Periode hat den Wert T. 
Durch einen großen Algorithmus steigt vermutlich T, da die nötige 
Berechnungszeit steigt.

Das kleinste denkbare Differenzierglied lautet y[k] = 1/T(u[k] - u[k-1]) 
und wird hier nur kurz für die Namenskonvention betrachtet. y[k] 
bezeichnet den Ausgang des Differenzierers, u[k] den aktuellen 
Eingangswert. Der vorige Eingangswert u[k-1] muss in einer Variable 
zwischengespeichert werden, die für den nächsten Schritt mit dem 
aktuellen Eingangswert überschrieben werden kann. In Pseudocode:
1
int u_k1 = 0;
2
do
3
{
4
  y = (u - u_k1)/T;
5
  u_k1 = u;
6
}


Praxis
- Man wählt eine Ordnung n. Der Algorithmus wird 2n Speicherplätze für 
Vergangenheitswerte benötigen.
- Man setzt den Wert für n in diese URL ein und lässt sich die 
Padé-Approximation für ein Differenzierglied berechnen:
http://www.wolframalpha.com/input/?i=PadeApproximant[-Log[x],+{x,+1,+n}]
- dieser Bruch wird nun aufgelöst, dass er folgende Form hat:
, wobei b0 = 1 vorgegeben ist.
- dieser Bruch wird mit 1 gleichgesetzt und Nenner nach "Links" 
multipliziert
- auf der Linken Seite bedeutet nun x^n soviel wie y[k-n], also den 
Wert, der vor n Schritten am Ausgang lag.
x^(n-1) bedeutet demzufolge y[k-n+1].
x^1 bedeutet demzufolge y[k-1]
1 bedeutet demzufolge y[k] - die gesuchte Größe.
Genauso bedeutet auf der Rechten Seite x^n soviel wie u[k-n].
Links stehen also die Ausgangswerte, rechts die Eingangswerte
- nun einfach nur noch die vergangenen Ausgangswerte mit "minus" nach 
rechts bringen und schon habt die Berechnungsvorschrift für eine 
Ableitungsnäherung beliebiger Genauigkeit.

Beispiel n=4 - hoffe mal, ich hab mich nicht verrechnet:
1
int u_k1 = 0;
2
int u_k2 = 0; // nur Zwischenspeicher, kommt in Formel nicht vor.
3
int u_k3 = 0;
4
int u_k4 = 0;
5
int y_k1 = 0;
6
int y_k2 = 0;
7
int y_k3 = 0;
8
int y_k4 = 0;
9
do
10
{
11
  y = (int)(5.0/6.0*(5*u + 32*u_k1 - 32*u_k3 - 5*u_k4) - 16*y_k1 - 16*y_k2 - 16*y_k3 - y_k4);
12
  u_k4 = u_k3;
13
  u_k3 = u_k2;
14
  u_k2 = u_k1;
15
  u_k1 = u;
16
  y_k4 = y_k3;
17
  y_k3 = y_k2;
18
  y_k2 = y_k1;
19
  y_k1 = y;
20
}

Weiterführendes
Aus einer Beliebigen Übertragungsfunktion G(s) lässt sich G(x) gewinnen, 
indem man einfach jedes auftretende s durch die gewählte 
Padé-Approximation ersetzt. Das Umformen und Auflösen könnte hier 
allerdings Arbeit bedeuten. Evtl eine Mathetool verwenden?

ToDo
- Ermitteln, bis zu welcher Ordnung sich der Genauigkeitsgewinn lohnt, 
da er ja Rechenzeit kostet, und damit T wächst. Im schlimmsten Fall 
bleibt die Realisierung in PLD als Ausweg. Dann steigt nämlich "nur" die 
Komplexität und nicht T. Außerdem liegt irgendwann der 
Genauigkeitsgewinn außerhalb der Wahrnehmbarkeit, wenn man nicht den 
Variablentyp ändert.
- Testen der Vorgehensweise in der Praxis = Fehlersuche... :/

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.