13.08.2013, 07:03 PM
EDIT: Fehler korrigiert am 14.8. - 18:50
Ich habe heute (mit anderer Hardware) nochmal mit dem Regler experimentiert und finde das Teil recht interessant. Der bereits gezeigte Code war ja nur rudimentär und beinhaltete einen logischen Fehler beim Übergang vom letzten Ausgabewert zum ersten (ein Fehler wurde dabei nicht gespeichert).
Vielleicht kann das ja auch ein anderer brauchen.
Worum geht es genau:
Funktion:
Ich habe heute (mit anderer Hardware) nochmal mit dem Regler experimentiert und finde das Teil recht interessant. Der bereits gezeigte Code war ja nur rudimentär und beinhaltete einen logischen Fehler beim Übergang vom letzten Ausgabewert zum ersten (ein Fehler wurde dabei nicht gespeichert).
Vielleicht kann das ja auch ein anderer brauchen.
Worum geht es genau:
- Digitaler Regler, der ein vorgegebenes Signal wiederholend (Periodisch) in eine (theoretisch beliebig) nichtlineare Strecke einregelt
- es werden mehrere Signalperioden benötigt, bis die maximale Genauigkeit erreicht ist
- Der Rechenaufwand ist denkbar minimal dafür der Speicheraufwand erhöht
- Eine bekannte oder Vermutete Phasendrehung in der Strecke kann vorgesteuert werden, indem die Fehlerwerte "verschoben" in das Fehlerarray geschrieben werden (s.u.)
- Mit einer Totzeit in der Strecke funktioniert der Regler in dieser Form nicht.
- Über das Fehler-Array misst "der" Regler quasi on-the-fly die Strecke aus - diese Streckeninformation kann man auch weiterverwenden
- Ist der Regler ausgeschaltet, wird das Sollsignal mit seiner einfachen Amplitude augegeben. Nach dem Anschalten des Reglers wird langsam die gewünschte Amplitude angefahren.
Funktion:
Code:
[navy]//2 Arrays der Länge n. Eines enthält eine Periode (Achtung, deckt sich hier nicht mit dem klassischen Periodenbegriff!) des Sollsignals (Bereich z.b. -1.0f...1.0f). Das andere nur Nullen.[/navy]
const float soll[n] = {-1.0, -0.99, ...}
float err[n] = {0.0, 0.0, ...}
[navy]//ein paar Steuervariablen (von "außen" modifizierbar)[/navy]
int reglerOn = 0;
float sollAmplitude = 1;
float kr = 0.2;
[navy]//Variablen für den Ablauf[/navy]
float error, ist;
int reglerOnOld = 0;
int firstrun = 1;
int i, j;
[navy]//Interrupt, der im immer gleichen Zeitabstand aufgerufen wird.[/navy]
void c_int(void){
...if(reglerOn == 1 && reglerOnOld == 0){....[navy]//Regler frisch angeschaltet, err[] nullen[/navy]
......for(j = 0; j < n; j++){
.........err[j] = 0.0;
......}
...}
...if(firstrun == 1){
......setOut(soll[0]);
...}else{
......ist = getIst();
......error = (sollAmplitude * soll[i]) - ist;
......err[i] += error * kr;
......if(i == n - 1){
.........i = -1;
......}
......i++;
......if(reglerOn == 1){
.........setOut(soll[i] + err[i]);
......}else{
.........setOut(soll[i]);
......}
...}
...firstrun = 0;
...reglerOnOld = reglerOn;
}
Pffffffffft. "Da entwich das Vakuum" - Heinrich Physik, 1857.