Suche Regelalgorithmen in C

Hallo,

ich bin auf der Suche nach Sourcecode von Regelalgorithmen. Gib es dazu frei verf=FCgbaren Quellcode in C? Der Code sollte nur mit Integerwerten rechen.

Kurz mein 'Problemchen' umrissen:

Jede Sekunde bekomme ich einen Messwert geliefert. Die einzelnen Messwerte schwanken jedoch sehr in ihrer Gr=F6=DFe. Um das zu Mitteln bzw. zu 'gl=E4tten', ist daran gedacht, die Werte durch ein PT1-Filter zu schicken.

Danke f=FCr jeden Tip!

Gru=DF Hans

Reply to
laterna
Loading thread data ...

Du willst also Messwerte sammeln und einen Durchschnitt bilden? Das macht man CPU-technisch am effizientesten so:

int Wertesammeln, aktuellerwert = 0;

for i = 1 bis 64 do {(..) Wertesammeln = Wertesammeln + aktuellerwert;} //z.B. für 64 Werte.

aktuellerwert >> 6;

Wenn du aber nur jede Sekunde einen WErt bekommst kannste doch genausogut mit floats rechnen.

PS.: kA was ein PT-Filter is.

MfG,

Markus

Reply to
Markus

Da Du ja Google-Nutzer bist:

formatting link
snipped-for-privacy@duhanic-com.com.invalid (räusper)

Ansonsten s. "gleitender Durchschnitt" und dergleichen, bei dem Du Dir aber Gedanken machen solltest, wie es an den Grenzen aussieht, also z.B. bei t=0.

Gruß, Mario

Reply to
Mario F. Duhanic

Und zwar fortlaufend, so habe ich es verstanden.

Hört hört, der Meister spricht. :-)

Super, dann hat er den Mittelwert der letzten 64 Sekunden. Und was ist eine Sekunde später? Und die danach?

Geschickter ist IMHO einen Ringpuffer zu nehmen, z.B. ein Array mit n Elementen. Das füllt man von Anfang her mit den Messwerten, mit einem Index i = j MOD n, wobei j für jeden Messwert inkrementiert wird. Dann muß man zwar für einen Mittelwert jedesmal n Elemente addieren und durch n teilen, aber dafür hat man in jedem Schritt die letzten n-1 Werte "im Gedächtnis". Auf dem Ringpuffer aufbauend kann man natürlich auch andere Berechnungen durchführen (quadratische Abweichung etc. pp).

Selbstredend ergibt die Ausgabe erst Sinn, wenn jedes Element des Arrays mit einem Meßwert gefüllt ist, und nicht mit Nullen oder meist schlimmer noch: uninitialisiertem Speichermüll. Aufpassen sollte man auch, daß der Datentyp für das Akkumulieren groß genug für n * max_messwert ist, sonst gibt's einen Überlauf, was Ausreißer im Ergebnis erzeugen dürfte.

Wobei je nach Plattform float nicht so richtig Spaß macht.

Gruß, Felix

Reply to
Felix Opatz

Argh, ist wohl schon etwas spät heute. Natürlich kann man auch einen Akkumulator mitlaufen lassen, und den jeweils jüngsten Wert aufaddieren sowie den ältesten subtrahieren. Dann muß man nicht jedesmal das ganze Array aufaddieren. Aber der Ringpuffer als Gedächtnis muß natürlich bleiben, sonst hat man einen Gesamtwert, dem man seine Bestandteile nicht mehr ansieht.

Reply to
Felix Opatz

Noch keine Regelungstechnik gehört? PT1 ist simpler Tiefpaß 1. Ordnung.

Gruß Henning

Reply to
Henning Paul

Normaler gleitender Durchschnitt ist auch immer etwas stufig. Will man das wegkriegen, kann man die Werte im Fenster gewichten, dem Verfahren bei FFT-PSE nicht unähnlich. Die Gewichte kann man ja in einer Tabelle ablegen, Form ist nicht mal soo wichtig; Gauss, Dreieck, Parabel, Savitzky- Golay, ...

--
mfg Rolf Bombach
Reply to
Rolf_Bombach

also wenn es nur um Glättung geht, ist eine Tiefpaßfilterung doch eine einfache Sache. Wie man z.B. eine PID-Regelung in der Praxis realisiert, weiß ich nicht, kann aber nicht so schwer sein. Bei einem Tiefpaß würde ich nicht mit gleitendem Mittelwert, Ringpuffer wie bei FIR oder sonstigen abgedrehten Sachen arbeiten, sondern einen simplen Tiefpaß 1. Ordnung nehmen. Digital braucht der genau 1 Variable als Speicherplatz für 1 verzögerten Funktionswert, 3 Koeffizientenmultiplizierer, 2 Addierer. In C ist das doch simpelst zu machen.

Einen Tiefpaß 1. Ordnung läßt sich leicht mit der bilinearen Transformation entwerfen. Nehmen wir 1 Beispiel:

V(s)=V0/(1+s/om_e)

s= j*omega omega=2*pi*f f=Signal-Frequenz j=sqrt(-1) om_e=2*pi*f_e f_e=Eckfrequenz des Tiefpasses, 3 dB-Frequenz

Die Beschreibung sollte eindeutig sein. Frei nach Mildenberger (Tietze/Schenk erklärt da IMHO zu umständlich) geht die bilineare Transformation einfach so:

Verschiebungssatz der Laplace-Transformation, um T verschieben: z=exp**(sT) T=1/fa fa=Abtastfrequenz

nach s umstellen: s=(1/T)*ln(z)

Leider läßt sich mit ln(z) nix anfangen, deshalb abbrechende Reihenentwicklung:

s=(2/T)* (z-1)/(z+1)

Das heißt bilineare Transformation und hat sehr günstige Eigenschaften. Jetzt ersetzen wir

V(s)=V(z)

indem wir einfach jedes s durch obigen Ausdruck von z ersetzen. Dann wird aus

V(s)=V0/(1+s/om_e)

mit aus Tietze/Schenk übernommener Struktur 1. Ordnung das:

V(z)=(b0+b1*z)/(a0+z)

b0=b1=V0/(1+2/(om_e*T)) a0=(1-2/(om_e*T))/(1+2/(om_e*T))

Wichtig für die Stabilität ist, daß |a0| < 1 ist, das ist hier immer der Fall. Die Struktur der Schaltung sieht so aus:

X o--->o------------------------------- | | | | | | \|/ \|/ b0 b1 | | | + | + __|__ _______ __|___ | | | | + | | |Summe|------>| 1/z |-------->|Summe |--------o----->o Y |_____| |_______| |______| | /|\ | - | | | | ----------------------a0--------------------

Ich hoffe, es ist zu erkennen was gemeint ist. 1/z = exp**(-s*T) und bedeutet Verzögerung um 1 Abtastwert der Periode T. Die Addierer sollten bei Overflow gesättigt arbeiten, sonst wird's instabil.

Diese Struktur sollte sich in C mit wenigen Zeilen erschlagen lassen, alle Variablen sollten natürlich signed integer sein, da der AD-Wandler ja kein float ausgibt, sondern sicher 2er-Komplement. Falls nicht, entsprechend in 2er-Komplement umwandeln, Rest ist dann klar.

Mit om_e wird dann der Glättungsgrad eingestellt, man kann auch Tiefpässe höherer Ordnung entsprechend entwerfen, mit entsprechendem Aufwand und besserer Wirkung. Sinnvollerweise sollte f_e deutlich unter fa/2 liegen.

mfg. Winfried

Reply to
Winfried Salomon

Glückwunsch, Du hast soeben die Z-Transformation erfunden. ;-)

Gruß Henning

Reply to
Henning Paul

Hallo Henning,

das war auch nötig, wenn Du Dir die anderen Antworten anschaust ;-). Welche Vorteil gleitender Mittelwert hier bringen soll, ist mir unklar, vielleicht weil man keine Multiplizierer braucht? Falls das Filter in der Rückkopplung liegen sollte, wäre das Ganze sowieso fatal und es müßte optimiert werden. Aber diese wichtige Information fehlt in der urprünglichen Fragestellung.

mfg. Winfried

Reply to
Winfried Salomon

ElectronDepot website is not affiliated with any of the manufacturers or service providers discussed here. All logos and trade names are the property of their respective owners.