Hallo,
ich bin nachwievor dabei meinen PI Regler zu programmieren. So richtig
funktioniert´s jedoch leider immer noch nicht, und ich frage mich ob es
an meinen aus der Sprungantwort der Strecke errechneten Parametern
liegt, oder ob noch ein Fehler im Programm steckt.Nochmal kurz zur
Problematik:
ich möchte einen konstanten Luftstrom regeln. Ich gebe also einen
Sollfluss vor (bzw. eine Sollspannung die einem Sollfluss entspricht).
Abhängig davon verändere ich die Pulsbreite, mit der ich mein Ventil
ansteuere. Am Flussensor messe ich den Ist-Fluss bzw. die Ist-Spannung.
Egal was für einen Sollwert ich für meinen Luftfluss einstelle, der
Ist-Wert pendelt sich immer bei ca. 3,3 Volt ein.
Da ich leider alleine davor sitze und keinen anderen Ansprechpartner
habe, stelle ich die Frage nochmal hier ins Forum, mit der Bitte sich
mal den in der ISR befindlichen Regelalgorithmus anzusehen. Vielleicht
seht ihr ja einen Fehler.
#include <mega323.h>
// Standard Input/Output functions
#include <stdio.h>
#include <stdlib.h>
#define ADC_VREF_TYPE 0x00
// Read the AD conversion result
unsigned int read_adc(unsigned char adc_input)
{
ADMUX=adc_input|ADC_VREF_TYPE;
// Start the AD conversion
ADCSR|=0x40;
// Wait for the AD conversion to complete
while ((ADCSR & 0x10)==0);
ADCSR|=0x10;
return ADCW;
}
float v_ist;
float e_k; // Regeldifferenz
float e_k_alt;
float k_p = 1.446; // Verstärkungsfaktor
float t_i = 0.007343; // Verzugszeit
float t_0 = 0.017708; // Abtastzeit
float u_k; // Stellgröße
float u_k_alt;
int v_soll;
int stell;
// Timer 2 overflow interrupt service routine
interrupt [TIM2_OVF] void timer2_ovf_isr(void)
{
// aktuelle Spannung berechnen:
v_ist = (5.0/1023)*read_adc(0);
// Regelabweichung e_k berechnen:
e_k = v_soll - v_ist;
// Stellgröße u_k berechnen:
u_k = u_k_alt + k_p*(e_k*(1+t_0/t_i)-e_k_alt);
// Stellgrößenbegrenzung:
if (u_k > 5.0) u_k = 5.0;
else if (u_k < 0.0) u_k = 0.0;
// Stellgröße in entsprechenden PWM Wert umrechnen:
stell = (int) (u_k*255/5.0);
// Pulsbreite setzen:
OCR0 = stell;
u_k_alt = u_k;
e_k_alt = e_k;
}
void main(void)
{
// Input/Output Ports initialization
// Port A initialization
// Func0=In Func1=In Func2=In Func3=In Func4=In Func5=In Func6=In
Func7=In
// State0=T State1=T State2=T State3=T State4=T State5=T State6=T
State7=T
PORTA=0x00;
DDRA=0x00;
// Port B initialization
// Func0=In Func1=In Func2=In Func3=Out Func4=In Func5=In Func6=In
Func7=In
// State0=T State1=T State2=T State3=1 State4=T State5=T State6=T
State7=T
PORTB=0x08;
DDRB=0x08;
// Port C initialization
// Func0=Out Func1=Out Func2=Out Func3=Out Func4=Out Func5=Out Func6=Out
Func7=Out
// State0=1 State1=1 State2=1 State3=1 State4=1 State5=1 State6=1
State7=1
PORTC=0xFF;
DDRC=0xFF;
// Port D initialization
// Func0=In Func1=In Func2=In Func3=In Func4=In Func5=In Func6=In
Func7=In
// State0=T State1=T State2=T State3=T State4=T State5=T State6=T
State7=T
PORTD=0x00;
DDRD=0x00;
// Timer/Counter 0 initialization
// Clock source: System Clock
// Clock value: 460,800 kHz
// Mode: Phase correct PWM top=FFh
// OC0 output: Non-Inverted PWM
TCCR0=0x62;
TCNT0=0x00;
OCR0=0x00;
// Timer/Counter 1 initialization
// Clock source: System Clock
// Clock value: Timer 1 Stopped
// Mode: Normal top=FFFFh
// OC1A output: Discon.
// OC1B output: Discon.
// Noise Canceler: Off
// Input Capture on Falling Edge
TCCR1A=0x00;
TCCR1B=0x00;
TCNT1H=0x00;
TCNT1L=0x00;
OCR1AH=0x00;
OCR1AL=0x00;
OCR1BH=0x00;
OCR1BL=0x00;
// Timer/Counter 2 initialization
// Clock source: System Clock
// Clock value: TCCR2=0x07: 3600 Hz -> t_0 = 1/(3600/255) = 70.83 ms
// TCCR2=0x06; 14400 Hz -> t_0 = 1/(14400/255) = 17,708 ms
// TCCR2=0x05; 28800 Hz -> t_0 = 1/(28800/255) = 8,85 ms
// Mode: Normal top=FFh
// OC2 output: Disconnected
ASSR=0x00;
TCCR2=0x00;
TCNT2=0x00;
OCR2=0x00;
// External Interrupt(s) initialization
// INT0: Off
// INT1: Off
// INT2: Off
GICR|=0x00;
MCUCR=0x00;
MCUCSR=0x00;
// Timer(s)/Counter(s) Interrupt(s) initialization
TIMSK=0x40;
// USART initialization
// Communication Parameters: 8 Data, 1 Stop, No Parity
// USART Receiver: On
// USART Transmitter: On
// USART Mode: Asynchronous
// USART Baud rate: 115200
UCSRA=0x00;
UCSRB=0x18;
UCSRC=0x86;
UBRRH=0x00;
UBRRL=0x01;
// Analog Comparator initialization
// Analog Comparator: Off
// Analog Comparator Input Capture by Timer/Counter 1: Off
// Analog Comparator Output: Off
ACSR=0x80;
SFIOR=0x00;
// ADC initialization
// ADC Clock frequency: 115,200 kHz
// ADC Voltage Reference: AREF pin
ADMUX=ADC_VREF_TYPE;
ADCSR=0x85;
// Global enable interrupts
#asm("sei")
// Sollspannung über Terminal einlesen:
v_soll = (int) getchar()-48;
// Timer loslaufen lassen:
TCCR2=0x06;
}
eine Idee kam mir da noch gerade:
könnte es Probleme geben, daß die Abarbeitung der Befehle so lange
dauert, daß zwischendurch bereits wieder ein Interrupt aufgerufen wird?
Obwohl doch eigentlich alle Interrupts während der Abarbeitung gesperrt
sind, oder? Was würde denn in so einem Fall passieren?
Und wie könnte man die Zeit herausfinden, die die Ausführung der ISR
braucht? Ich habe schonmal in den AVRStudio Debugger nachgesehen und
wollte anhand der Anzahl der Maschinenbefehle zurückrechnen, jedoch sehe
ich in dem Wirrwarr garnicht wo nun meine ISR anfängt und wo sie wieder
aufhört.
Nochmal zu meiner Hard/ Software:
ATmega323
AVRStudio
Gruß,
Stefan
Hallo Stefan!
Ich sehe gerade, dass du v_soll einen int-Wert zuweist, der über die
Konsole reinkommt. In deiner ISR rechnest du aber mit einem
float-Bereich von 0-5V. Ich bin nicht 100% sicher, aber das passt glaube
ich nicht ganz zusammen und muss als erstes korrigiert werden.
Dann würde ich folgendermaßen vorgehen:
Als erstes würde ich die Regelroutine komplett auskommentieren und
zunächst mal den Sollwert, den du über die Konsole sendest als
Stellgröße für die PWM benutzen, D.h. du setzt OCR0=v_soll*255/5.0. So
kannst du zunächst testen, ob 1. deine Konsolensteuerung funktioniert
und 2. die PWM am Ventil das macht, was sie soll. Mit den eingegeben
Werten müsste sich das Ventil dann von 0-100% steuern lassen. Wenn das
funktioniert, hast du deine I/O-Ebene getestet.
Erst jetzt würde ich dann die Regelung mit hinzu nehmen, wobei du
zunächst nur eine P-Regelung realisierst:
u_k = u_k_alt + k_p*e_k
Gib z.B. 2,5 als v_soll ein, die Regelung müsste sich dann auf einen
Wert einstellen. Falls das System schwingen sollte, ist dein k_p zu
groß. Ist das System bei diesem Wert stabil, wähle als v_soll z.B. 4.
Das Ventil muss dann auf jeden Fall weiter öffnen. Reißt das Ventil ganz
auf, so ist k_p zu groß. Läßt sich kaum eine Änderung am Ventil
feststellen, ist dein k_p zu klein.
Erst wenn du diese Schritte hinter dir hast, und das Ventil reagiert
einigermaßen auf dein v_soll, würde ich den I-Anteil dazu nehmen.
Halte mich ruhig auf dem Laufenden, mich interessiert es sehr.
Gruß, Sascha
Moment, statt u_k = u_k_alt + k_p*e_k muss es
u_k = k_p*e_k
heißen, sonst würdest du bei jedem Aufruf der ISR den alten Wert
hinzuaddieren. Langsam frage ich mich, ob deine PI-Realisierung
überhaupt stimmt...
Hallo Sascha,
das mit int und float habe ich erstmal behoben, ich dachte das würde
nichts ausmachen, aber ist vielleicht doch besser. Ich denke auch, daß
der Summand u_k_alt bei der PI Realisierung falsch ist. Ich habe ihn nun
weggelassen, da ich auch in RT Büchern nichts derartiges gefunden habe.
Du schriebst, ich sollte erstmal testen ob/ wie die I/O Ebene funzt. Das
habe ich gemacht und bin auf folgendes Problem gestoßen: Beim
kontinuierlichen Erhöhen der Pulsbreite (von 0 angefangen) tut sich sehr
lange garnichts. Bei einer Pulsbreite von ca. 58% "springt" das Ventil
plötzlich auf (zwischen 58 und 60%). Für ein Proportionalventil ist das
natürlich ein sehr merkwürdiges Verhalten, da könnte ich ja gleich ein
herkömmliches Schaltventil nehmen. Ich werde mich deshalb morgen nochmal
mit dem Hersteller in Verbindung setzen, da ich so gerde keinen Sinn
sehe weiter rumzuexperimentieren. Ich werde dich auf dem laufenden
halten.
Bis dann,
Stefan
Ohne auf die Theorie rückgreifen zu wollen,
würde ich vorschlagen, den Regelalgorithmus
wie folgt zu gestalten:
Da durch den timer-Interrupt mit einer konstanten
Abtastzeit gearbeitet wird, braucht diese im
Regelalgorithmus nicht mehr berücksichtigt werden.
Im Endeffekt berücksichtigt der Faktor ki das Verhältnis
von Regelzeitkonstante und Abtastzeit.
e_k = v_soll - v_ist;
// für PI Regler in P-Regler und I-Regler trennen
// P-Regler
u_p = e_k * kp; // Regelabweichung * Proportionalfaktor
// I-Regler
u_i = u_i + e_k * ki; // Regelabweichung * Nachstellzeit
u_k = u_i + u_p;
Eine andere Sache sind die Datenformate. Bei 8Bit
Prozessoren auf jeden Fall auf Fließkomma verzichten.
Das kostet nur zuviel Rechenzeit. Das ist wahrscheinlich
der Grund warum der PI Regler nicht funktioniert.
Am sinnvollsten ist es, alle Größen auf 8Bit bzw.
16Bit Werte zu normieren um dadurch nur mit ganzen Zahlen
rechnen zu können.
Die meiste Arbeit besteht jetzt im normieren und begrenzen
der Zahlenwerte.
Hallo Harald,
danke für deine Tipps, ich werde mich jetzt mal ranmachen und meinen
Code etwas modifizieren. Die Problematik mit den floats ist mir auch
schon aufgefallen, wußte jedoch noch nicht genau wie ich das so gut
umrechnen soll, da ja die Regelparameter ki und kp nunmal kommabehaftete
Zahlen sind...
Bei deiner Gleichung für den I-Regler: entspricht das u_i nach dem
Gleichheitszeichen dem u_i_alt (also dem aus dem vorherigen Durchlauf)?
Dann würde es also lauten
u_i = u_i_alt + e_k * ki ?
Gruß,
Stefan
Hallo,
ich habe jetzt nochmal so einiges an meinem Programm gemacht:
1) erstmal nur einen P-Regler realisiert
2) von float auf int umgestellt
3) 10 bit PWM (und nachwievor 10 bit ADC).
Gedacht habe ich mir das nun wie folgt:
Zuerst wird der Sollwert eingelesen. Das mache ich, indem ich einen
String über den Terminal einlese. 1023 entspricht dabei einer
Flussmessersollspannung von 5 Volt.
Dann starte ich den Timer, wenn der überläuft wird regelmäßig die
Spannung meines Flussmessers A/D gewandelt, ich habe dann einen Wert
zwischen 0 und 1023. Nun kann ich die Regelabweichung e_k errechnen. Mit
diesem Wert wird dann direkt (noch mit dem Faktor k_p) die Pulsbreite
gesteuert. Bei der größtmöglichen Regelabweichung wird dann 1023 in das
OCR1A Register geschrieben, was dann einer Pulsbreite von 100%
entspräche. Soweit die Theorie.
So wie ich mir das gedacht habe, funktioniert das jedoch leider noch
nicht. Immerhin bekomme ich schonmal unterschiedliche Ist-Werte für
verschiedene Sollwerte, aber immernoch eine ziemliche Regelabweichung.
Ich habe da auch schon zwei mögliche Fehlerquellen im Kopf, weiß jedoch
noch nicht genau wie ich sie beheben könnte.
A) Ich bin mir, da ich jetzt auch nicht mehr mit floats, sondern
"normierten" ints rechne nicht mehr sicher wie ich den Faktor k_p
gewichten / bestimmen soll.
B) Wenn das Ventil geschlossen ist, es also keinen Fluss gibt, gibt mir
der Flussmesser eine Spannung von 1 Volt (und nicht 0 Volt!!!) aus. Das
müßte ja eigentlich meinen ganzen Regelalgorithmus ziemlich
durcheinander bringen. Ich weiß nur nicht genau, wie ich diesen "offset"
ausgleichen könnte. Habt ihr eine Idee?
Ich hänge unten nochmal meinen Programmcode an.
Vielen dank im voraus,
Stefan
#include <mega323.h>
// Standard Input/Output functions
#include <stdio.h>
#include <stdlib.h>
#define ADC_VREF_TYPE 0x00
// Read the AD conversion result
unsigned int read_adc(unsigned char adc_input)
{
ADMUX=adc_input|ADC_VREF_TYPE;
// Start the AD conversion
ADCSR|=0x40;
// Wait for the AD conversion to complete
while ((ADCSR & 0x10)==0);
ADCSR|=0x10;
return ADCW;
}
int v_ist;
int e_k; // Regeldifferenz
int e_k_alt;
int k_p =296; // entspricht 1.446 (ermittelt aus Sprungantwort)
Verstärkungsfaktor normiert
// 1023*1,446/5 Volt = 296
int u_p; // Stellgröße
int u_p_alt;
int v_soll;
int stell;
char wert[4];
// Timer 2 overflow interrupt service routine
interrupt [TIM2_OVF] void timer2_ovf_isr(void)
{
// aktuelle Spannung einlesen (Wert zwischen 0 und 1023):
v_ist = read_adc(0);
// Regelabweichung e_k berechnen:
e_k = v_soll - v_ist;
// P-Regler
u_p = e_k * k_p;
// Stellgrößenbegrenzung:
if (u_p > 1023) u_p = 1023;
else if (u_p < 0) u_p = 0;
// Stellgröße in entsprechenden PWM Wert umrechnen:
stell = u_p;
// Pulsbreite setzen:
OCR1A = stell;
u_p_alt = u_p;
e_k_alt = e_k;
}
void main(void)
{
// Input/Output Ports initialization
// Port A initialization
// Func0=In Func1=In Func2=In Func3=In Func4=In Func5=In Func6=In
Func7=In
// State0=T State1=T State2=T State3=T State4=T State5=T State6=T
State7=T
PORTA=0x00;
DDRA=0x00;
// Port B initialization
// Func0=In Func1=In Func2=In Func3=In Func4=In Func5=In Func6=In
Func7=In
// State0=T State1=T State2=T State3=T State4=T State5=T State6=T
State7=T
PORTB=0x00;
DDRB=0x00;
// Port C initialization
// Func0=Out Func1=Out Func2=Out Func3=Out Func4=Out Func5=Out Func6=Out
Func7=Out
// State0=1 State1=1 State2=1 State3=1 State4=1 State5=1 State6=1
State7=1
PORTC=0xFF;
DDRC=0xFF;
/// Port D initialization
// Func0=In Func1=In Func2=In Func3=In Func4=In Func5=Out Func6=In
Func7=In
// State0=T State1=T State2=T State3=T State4=T State5=0 State6=T
State7=T
PORTD=0x00;
DDRD=0x20;
// Timer/Counter 0 initialization
// Clock source: System Clock
// Clock value: Timer 0 Stopped
// Mode: Normal top=FFh
// OC0 output: Disconnected
TCCR0=0x00;
TCNT0=0x00;
OCR0=0x00;
// Timer/Counter 1 initialization
// Clock source: System Clock
// Clock value:
// TCCR1B=0x04: 4.400 kHz/ 2046 = 7 Hz
// TCCR1B=0x01: 3686.400 kHz/2046 = 1800 Hz
// Mode: Ph. correct PWM top=03FFh
// OC1A output: Non-Inv.
// OC1B output: Discon.
// Noise Canceler: Off
// Input Capture on Falling Edge
TCCR1A=0x83;
TCCR1B=0x01;
TCNT1H=0x00;
TCNT1L=0x00;
OCR1AH=0x00;
OCR1AL=0x00;
OCR1BH=0x00;
OCR1BL=0x00;
// Timer/Counter 2 initialization
// Clock source: System Clock
// Clock value: TCCR2=0x07: 3600 Hz -> t_0 = 1/(3600/255) = 70.83 ms
// TCCR2=0x06; 14400 Hz -> t_0 = 1/(14400/255) = 17,708 ms
// TCCR2=0x05; 28800 Hz -> t_0 = 1/(28800/255) = 8,85 ms
// Mode: Normal top=FFh
// OC2 output: Disconnected
ASSR=0x00;
TCCR2=0x00;
TCNT2=0x00;
OCR2=0x00;
// External Interrupt(s) initialization
// INT0: Off
// INT1: Off
// INT2: Off
GICR|=0x00;
MCUCR=0x00;
MCUCSR=0x00;
// Timer(s)/Counter(s) Interrupt(s) initialization
TIMSK=0x40;
// USART initialization
// Communication Parameters: 8 Data, 1 Stop, No Parity
// USART Receiver: On
// USART Transmitter: On
// USART Mode: Asynchronous
// USART Baud rate: 115200
UCSRA=0x00;
UCSRB=0x18;
UCSRC=0x86;
UBRRH=0x00;
UBRRL=0x01;
// Analog Comparator initialization
// Analog Comparator: Off
// Analog Comparator Input Capture by Timer/Counter 1: Off
// Analog Comparator Output: Off
ACSR=0x80;
SFIOR=0x00;
// ADC initialization
// ADC Clock frequency: 115,200 kHz
// ADC Voltage Reference: AREF pin
ADMUX=ADC_VREF_TYPE;
ADCSR=0x85;
// Global enable interrupts
#asm("sei")
// Sollspannung (10 bit integer zwischen 0 und 1023) über Terminal
einlesen:
gets(wert,4);
// Array in int umrechnen:
v_soll = atoi(wert);
// Timer 2 loslaufen lassen:
TCCR2=0x06;
}
Also, ein Fehler ist mir gerade noch aufgefallen: Beim P-Regler muß in
die Berechnung der Stellgröße auf jedem Fall auch die vorherige
Stellgröße mit hinzuaddiert werden:
u_p = u_p_alt + e_k * k_p;
Ansonsten würde ja sobald die Regelabweichung verschwindet auch die
Stellgröße zu Null werden, sprich das Ventil ganz geschlossen werden.
Nun bleibt nur noch die Frage wie ich mein k_p richtig wähle, das
Verhalten meines Regelkreises kommt mir noch etwas spanisch vor. Das mag
aber auch an der Charakteristik des Proportionalventils liegen, da
dieses sich nur innerhalb eines sehr kleinen Fensters (Pulsbreite
zwischen 55% und 60%) regt. Außerhalb dieses Bereichs ist es entweder
ganz auf, oder ganz zu.
Stefan
Das mit dem u_p_alt wird nicht funktionieren. Stell dir vor, u_p_alt
wäre 50%, dann hättest du nach zwei Aufrufen der Reglerroutine eine
Stellgröße von 100% und dein Ventil wäre voll auf und käme auch nicht
wieder runter. Was du brauchst ist ein Offset, den du nach den
Berechnungen einfach hinzuaddierst. u_p_0 könnte z.B. 512 (50%) sein.
//Offset
u_p_0=512;
// Stellgröße in entsprechenden PWM Wert umrechnen:
stell = u_p + u_p_0;
Das Problem mit dem Ventil ist natürlich das größte im Moment. Wenn es
wirklich nur zwischen auf und zu zu steuern ist, sind alle deine
Bemühungen mit einem Regler umsonst. Das Ganze kann nur funktionieren,
wenn dein Stellglied einigermaßen linear arbeitet, und nicht so
schaltend wie zur Zeit.
@ edi: Nur zur Info: das Ventil daß ich derzeit verwende ist ein
Proportionalventil. So super linear zwischen 0 Volt und 24 Volt arbeiten
die aber leider nicht. Die öffnen sich erst ab einer relativ hohen
Spannung, und dann geht´s ziemlich fix bis sie auf sind.
@ sascha: Danke für die Tipps, so richtig sehe ich jedoch nicht den
Unterschied und das Problem. Meine Stellgröße ist ja begrenzt, kann also
maximal 1023 groß werden. Und die Regelabweichung kann ja auch negativ
werden, d.h. u_p müßte dann auch wieder kleiner werden können.
Ich habe es zumindest mal mit einem Offset probiert und kam aufs selbe
Ergebnis: Der Sollwert von 1023 wird ohne Regelabweichung erreicht und
gehalten. Wenn ich z.B. einen Sollwert von 512 eingeben, so bekomme ich
folgendes merkwürdige Verhalten: die Ist-Spannung zittert zwischen 1023
und ca. 230 hin- und her. Das Ergebnis ist natürlich absoluter Müll. Ich
denke ja noch, daß ich einen Fehler in meinem Algorithmus habe...
Zur Linearität des Proportionalventils: Ich habe da mal so eine
Kennlinie mit Excel (s. Anhang) aufgenommen: Ausgangsspannung des
Flussmessers in Abhängigkeit von der Pulsbreite. Ich habe das alles mal
bei unterschiedlichen PWM Frequenzen gemacht, das Ergebnis ist aber
immer ziemlich ähnlich: es tut sich nur was in einem relativ kleinen
Bereich. (die gelbe Linie interessiert nicht, da habe ich es mal mit
einem normalen auf - zu - Ventil probiert).
Die Kennlinie des Proportionalventils ist halt nur in einem ziemlich
kleinen Bereich linear. Kann ich vielleicht irgendwie meinen
Regelalgorithmus an die Kennlinie anpassen?
Gruß,
Stefan
Ach ja, mir viel gerade noch etwas ein zum Thema Offset u_p_0 oder alter
Stellgröße u_p_alt:
Bei Verwendung eines Offsets hätte ich ja, wenn die Regelabweichung
bereits 0 ist, immer noch eine Stellgröße.
D.h. das Ventil würde sich weiterhin bewegen, obwohl es ja eigentlich in
seiner Position verharren müßte...
Stefan
Du musst mit dem Offset den Arbeitspunkt in die Mitte deiner Kennlinie
legen, da wo sie den linearen Verlauf hat. Ist dein Sollwert kleiner als
der Arbeitspunkt, so bekommst du eine negative Regelabweichung und deine
Stellgröße verkleinert sich. Sollwert zu groß -> Stellgröße größer.
Versuche folgenden Code:
// Timer 2 overflow interrupt service routine
interrupt [TIM2_OVF] void timer2_ovf_isr(void)
{
// aktuelle Spannung einlesen (Wert zwischen 0 und 1023):
v_ist = read_adc(0);
// Regelabweichung e_k berechnen:
e_k = v_soll - v_ist;
// P-Regler
u_p = e_k * k_p + u_p_0;
// Stellgrößenbegrenzung:
if (u_p > 1023) u_p = 1023;
else if (u_p < 0) u_p = 0;
// Stellgröße in entsprechenden PWM Wert umrechnen:
stell = u_p;
// Pulsbreite setzen:
OCR1A = stell;
u_p_alt = u_p;
e_k_alt = e_k;
}
Durch setzen von k_p=0 kannst du erstmal herausfinden, welchen Wert
u_p_0 haben muss, damit du ca. 50% Durchfluss hast. Dann k_p wieder
zurücksetzen.
Übrigens musst du deinen Timer 2 noch initialisieren (TCCR2)!
Nochmals zum P-Regler.
Beim P-Regler DARF!!! der alte p-Wert nicht mit dazugerechnet werden
(sonst haben wir ja den I-Regler!!).
Beim P-regler ist ja das Problem, das er den Sollwert nie erreicht, bzw.
erst bei undendlich großer Verstärkung.
Beim I-regler braucht man sich den berechneten Wert z.B u_i_alt nicht zu
merken. Den vorherigen Wert merkt sich schon der Kompiler.
Tschüß!
@ sascha: Der Timer 2 wird ganz unten im Programmcode mit 0x07
initialisiert. Danach müßte dann alle 70,83 ms ein Interrupt ausgelöst
werden.
Ich habe dann mal k_p auf 0 gesetzt und probiet den richtigen Offset zu
finden. Dabei trat jedoch das merkwürdige Phänomen auf, das die Spannung
langsam immer geringer wurde, wenn ich also als Stellgröße nur u_p =
u_p_0 = 470 hatte. Das konnte ich mir nicht erklären.
Ich habe nun erstmal u_p_0 auf 470 gelasen und k_p wieder auf 1 gesetzt.
Nun klappt das alles schon besser. Zumindest die Spannung die mir mein
Multimeter anzeigt kommt besser hin. Das was mir mein A/D Wandler auf
dem Terminal ausgiebt wackelt immernoch ziemlich hin- und her.
Ich werde hier nochmal etwas rumtüfteln. Erstmal vielen Dank und
wahrscheinlich bis später :-)
Stefan
Hallo,
irgendwie habe ich das Gefühl, daß ich das Einlesen meiner aktuellen
Spannung von der Regelroutine (also von der ISR) trennen muß, und
kontinuierlich nebenher messen muss. Ich habe nämlich folgendes Problem
(s. Excel File): Wenn ich mittlere Sollwerte (also mittleren Fluss)
vorgebe, so wackelt mein Signal zwischen min und max hin und her. Etwas
ähnliches ist auch an der Pulsbreite auf dem Oszi zu beobachten: Die
Pulsbreite springt immer zwischen sehr geringen (~5%) und sehr hohen
(~95%) hin und her. D.h. daß die Stellgröße permanent wackelt, und dies
kann nur an der Regelabweichung e_k liegen. In e_k geht als variable
Größe ja nur v_ist bzw. read_adc(0) vom A/D Wandler ein. Hier muß also
denke ich die Fehlerquelle liegen, da sich e_k offenbar immer
sprungartig ändert. Hat jemand eine Idee wie ich da etwas ändern kann?
Stefan
Das Schwingen ist eigentlich ein typisches Anzeichen für ein zu großes
k_p. Verkleinere es vielleicht auf ca. 75% vom jetztigen Wert und
beobachte nochmal. Ist die x-Achse die Zeit in Sekunden? Wenn ja, ist
das wahrscheinlich die Lösung. Dadurch nimmt natürlich die
Regelgenauigkeit ab, aber das kompensiert man dann nachher mit dem
I-Anteil (aber erst, wenn der P-Anteil stabil läuft).
Hallo Sascha,
das mit dem k_p hatte ich auch schon gedacht, wußte jedoch bisher nicht
wie ich den Wert kleiner als 1 machen soll, da ich ja nur mit Integer
Werten arbeite.
Die X-Achse ist noch garnicht skaliert. Jedes mal wenn der Timer 2
überläuft, wird ein Interrupt ausgelöst und ich lese das A/D Ergebnis.
D.h. die Intervalle auf der X-Achse sind ca. 70 ms groß.
Stefan
Ja, überlegt hatte ich das mal. Habe aber bisher nur einen Kondensator
hinter meinem Flussmesser hängen, um die Ausgagnsspannung zu glätten.
Man hat mir gesagt das würde reichen, ich kann aber auch nochmal einen
"richtigen" Tiefpass probieren.
Stefan
Hallo,
wenn ich k_p durch 2 dividiere, bekomme ich unabhängig vom Sollwert den
selben Ist-Wert raus. Ich bin mir auch nachwievor nicht sicher wie ich
ein k_p von 1/2 in einen Regelalgorithmus einbinden soll, der nur mit
Integer Werten arbeitet. Hier nochmal der Ausschnitt aus dem Programm
(ich werde mich jetzt auch nochmal um die Sache mit dem Tiefpass
kümmern).
Stefan
int v_ist;
int e_k; // Regeldifferenz
int e_k_alt;
float k_p =1/2; // 1.446 Verstärkungsfaktor
int u_p; // Stellgröße
int u_p_alt;
int u_p_0=470; // Offset
int v_soll;
int stell;
char wert[4];
char istwert[4];
int i;
int ad_summe;
// Timer 2 overflow interrupt service routine
interrupt [TIM2_OVF] void timer2_ovf_isr(void)
{
// aktuelle Spannung einlesen (Wert zwischen 0 und 1023):
v_ist = read_adc(0);
// Regelabweichung e_k berechnen:
e_k = v_soll - v_ist;
// P-Regler
u_p = e_k * k_p + u_p_0;
// Stellgrößenbegrenzung:
if (u_p > 1023) u_p = 1023;
else if (u_p < 0) u_p = 0;
// Stellgröße in entsprechenden PWM Wert umrechnen und
Typeconversion nach int:
stell = (int) u_p;
// Pulsbreite setzen:
OCR1A = stell;
u_p_alt = u_p;
e_k_alt = e_k;
/******
// Mittelung des A/D Ergebnis:
for(i=1; i<=10; i++)
{
ad_summe += read_adc(0);
}
ad_summe/=10;
itoa(ad_summe, istwert);
******/
itoa(read_adc(0),istwert);
puts(istwert);
}
Ja, 1.446 war kein Int-Wert, aber den hatte ich auch durch 1 ersetzt,
als ich von meinem float Regelalgorithmus zu integern übergegangen bin.
Wenn ich obiges Programm mit k_p = 0.7 betreibe, bekomme ich das selbe
"zittern" der Ausgangsgröße. Das merkwürdige dabei ist ja, daß es
wirklich mit konstanter Frequenz und (annähernd konstanter) Amplitude
schwingt. Wenn ich beispielsweise 512 als Sollwert vorgebe, wechseln
sich am Ausgang (Ist-Wert) die Werte ~215 (+-1) und ~1018 (+-1) konstant
ab. Das sah man ja auch in der Excel Tabelle die ich gestern hier
gepostet habe. Ob das durch einen simplen Tiefpaß zu beheben ist weiß
ich ja nochnicht so ganz....ich bin aber dabei.
Stefan
Hast Recht, hab mir mal die Tabelle angeschaut. Das Diagramm sieht ja so
aus, als wenn es harmonische Schwingungen wären, aber das liegt nur an
der Darstellung. Die Werte sehen so aus, als wenn noch irgendein
systematischer Fehler drinsteckt. Es ist unmöglich, dass die gewandelten
Werte dem korrekten Messsignal entsprechen, da sie ja wie du schon
sagtest so springen. Hast du den AD-Wandler schon mal mit einer
Gleichspannung getestet? Gibt es eigentlich ein DAtenblatt über den
Durchflusssensor?
Eben, es scheint mir auch so daß da noch ein systematischer Fehler
drinsteckt. Den AD Wandler habe ich gerade nochmal mit einer
Gleichspannung getestet. Das funktioniert einwandfrei.
Datenblätter vom Durchflussmesser habe ich ebenfalls. Was möchtest du
denn wissen? Abhängig vom Durchfluss gibt das Teil am Ausgang 1 Volt
(kein Fluss) oder 5 Volt (voller Fluss) aus.
Stefan
Ich dachte, der Sensor gibt vielleicht ein frequenzproportionales Signal
statt einer Gleichspannung raus. Wenn der Wandler funktioniert, hilft
vielleicht ein Tiefpass.
Hallo,
ich habe es nun nochmal mit einem Tiefpaßfilter probiert. Das hat jedoch
nichts gebracht. Die Werte die mir mein A/D Wandler für die Ist-Spannung
ausgibt, sehen genau gleich aus und schwanken immernoch so heftig. Es
muß also nachwievor irgendein logischer Fehler im Programm sein. Die
Frage ist nur welcher? Ich finde partout keinen Denkfehler im Programm,
es ist ja eigentlich auch nicht so kompliziert...
Hallo Stefan ,
hab mir mal das Excel File angesehen und bin auch der Meinung
dass der Regler übersteuert d.h. er ist zu scharf eingestellt.
Ich kann zwar kein C , aber probier das mal um den Regler
zu "entschärfen".
e_k = v_soll - v_ist;
e_k = e_k / 2;
u_p = e_k + u_p_0;
Damit kannst du die Abweichung halbieren.
Gruss Gerhard
Hallo Stefan!
Ohne das ich mich jetzt mit dem Prog. beschäftigt habe, setze doch Kp
einfach mal auf 0, versorge den Eingang mit 1-5V und schaue dir die Ua
im Bezug auf die Differenz Usoll zu Ue an.
Ich denke jedenfalls dein Kp ist zu hoch.
Wie wäre es eigentlich mal mit simulieren, da zeigen sich oft kleine
aber böse Fehler.
MFG Uwe
@ Gerhard: Wenn ich e_k = e_k / 2; setze, tut sich eigentlich nichts
bzgl. des merkwürdigen Verhaltens. Es wackelt immernoch genauso hin und
her. Das Problem muß also irgendwo anders liegen, ich vermute ja schon,
daß der A/D Wandler irgendwie doch murks baut, obwohl er sonst normal
funzt.´
@ Uwe: Wenn ich k_p auf 0 setze, geht ja keine Variable Größe mehr in
meine Stellgröße ein. Ich bekomme also unabhängig vom Sollwert immer
denselben Ist-Wert.
Wie meinst du das mit Simulieren? Mit Matlab? Da hätte ich jetzt keine
Ahnung wie ich da rangehen sollte, und wüßte auch nicht wirklich was für
Erkenntnisse ich daraus gewinnen sollte...
Stefan
Hallo Stefan,
hab mir nochmal das Excel File angeschaut.
Eigentlich kann man sagen dass der Regler
bei Sollwert 1000 schon halbwegs funktioniert.
Sieht auch bei Sollwert 200 nicht ganz so schlecht aus.
2 Vorschläge habe ich noch.
1. e_k noch durch einen höheren Wert dividieren.
z.B. 5 , 10 , 20 ...
2. Ich weiß nicht wie exakt die Werte vom Durchflussmesser
rüberkommen. Probier vielleicht mal den Mittelwert der
letzten 5 od. 10 Messungen zu bilden und diesen für
die Berechnungen herzunehmen. Etwaige Fehlmessungen
bzw. Störungen würden dadurch entschärft.
Hoffe für dich dass das hilft.
Gruss Gerhard
Hallo Gerhard,
genau die Sachen die du mir gerade nanntest habe ich schonmal probiert.
Ohne Erfolg. Das "Wackeln" ist immer noch da, jedoch nicht mehr zwischen
~200 und ~1000, sondern zwischen ~500 und ~1000. (bei einer
Regelabweichung von e_k = e_k/8, einem k_p von 0,7 und einer Mittelung
des A/D Ergebnisses über 10 Werte). Ich erkenne da absolut kein System.
STefan
Hallo Stefan!
Ich habe mich mal mit deinem Probl. genauer beschäftigt und dazu dein
Progr. betrachtet. Wenn das alles ist, was die PWM beeinflusst, kann es
nicht gehen.
Wo ist der SOLLWERT im Ausgangswert? Der P,I,D-Anteil sind nur
Abweichungen, davon!
Solltest du nicht drauf kommen schreibe ich es dir heute Nacht, es ist
ganz einfach.
MFG Uwe
Hallo Stefan!
Deine Geschichte ist mir nict aus dem Kopf gegangen und mir sind noch
einige Dinge Eingefallen.
Ich denke dein Grundprobl.ist das "schnappen" deines Ventil's
in Verbindung mit den 70ms Tastzeit. Wie schnell jetzt der Sensor +
Luftstrom reagieren ist natürlich auch so eine Sache.
jedenfalls ist dein Kp, auf den engen Stellbereich gesehen, viel zu
klein. Andererseits passt ein hoher Kp nicht zu den 70 ms Abtstzeit(da
könnte viel geschehen). Mein 2. Gedanke war eigentlich:
v_ist = ADC - Offset(1V)
e_k = (v_soll - v_ist) * Kp ;
u_p = v_soll + e_k
Dabei muss sich v_soll aber im Regelbereich deines Vent. befinden. Kp
würde ich jetzt in Schritten von 5 erhöhen.
Wo ich kein gutes Gefühl habe sind die 70ms Abtastzeit.
Passt denn das zur Regelzeit deines Systems. Kannst du nicht mal die
Zeit messen von Sensor 0->100% bei Vent.0->1
Übrigens ist es möglich das du dein Vent. stromgesteuert fahren musst?
Das wird zb.im KFZ-Bereich oft so gemacht.
MFG Uwe
hi Stefan,
wie sieht dein ventil aus? ist es motorgesteuert oder
pneumatisch?
dass es erst bei 58% 'aufmacht' ist alles andere als linear.
dokumentation?
ed
@ edi: Bei dem Ventil handelt es sich um ein Magnetventil. Es hat also
eine Spule, die von Strom durchflossen wird und somit einen Kolben
bewegt. Daß das Ventil so spät erst aufmacht kommt mir halt auch sehr
merkwürdig vor. Auch der Vertreter der Firma (Fluid Automation Systems)
konnte mir nicht sagen, ob das normal ist. Etwas schwache Leistung, aber
offenbar kennen die sich schlecht mit PWM aus. Er sagte mir nur, daß die
Steuerspannung ca. zwischen 12 und 24 Volt liegt, insofern würde es ja
passen, daß das Ventil erst noch geschlossen bleibt...
@ Uwe: Danke erstmal für deine zahlreichen Tipps. Ich habe Freitag nicht
gearbeitet, daher antworte ich erst jetzt. Mit deinem Posting vom 20.06
konnte ich nicht so viel anfangen. Was meinst du mit "Wenn das alles
ist, was die PWM beeinflusst,..."?
Inwiefern meinst du daß die Abtastzeit ein Problem darstellt? Da fehlt
mir etwas der theoretische Hintergrund. Die Abtastzeit kann ich ja noch
über den Timer verändern. Und wie muß die Abtastzeit im Verhältnis zur
"Ansprechzeit" meines Systems gewählt werden? Eine Sprungantwort habe
ich ja schonmal aufgenommen. Das System reagiert wie ich fand sehr
schnell. Am Ausgang (also am Flussensor) sieht man ebenfalls nahezu
einen Sprung. Die Totzeit betrug 2,205 ms, die Zeitkonstante (also die
Zeit die das System braucht um nach "Ablauf" der Totzeit auf Sollwert 5
V zu kommen) betrug 0,513 ms. Ist deine Idee also, daß ich die
Abtastzeit wesentlich verringern müßte? Muß die Abtastzeit ähnlich groß
sein wie die Systemzeitkonstante?
Ich werde nun nochmal probieren einige von dir vorgeschlagene Änderungen
in mein Programm mit zu übernehmen.
Das Vewntil könnte ich auch stromgesteuert antreiben. Da habe ich aber
keine Ahnung wie ich eine Strom PWM hinbekommen soll. Mit Spannung
sollte es zumindest auch funktionieren.
Bis dann,
Stefan
Zu dem Ventil: So, wie Du das beschreibst, ist das kein
Proportionalventil, sondern ein ganz ordinäres Magnetventil mit einer
Nennspannung von 24 Volt. Die schalten bei 12V auch (manchmal).
Ein Proportionalventil ist häufig mit einer motorgetriebenen Spindel
ausgestattet, es gibt auch rein magnetisch angetriebene. Die ersteren
haben entweder ein Poti oder einen Impulsgeber als Rückmeldung, die
letzteren eine komplizierte Elektronik. Zumeist kann man Prop.- Ventile
daran erkennen, daß sie 1. Sauteuer sind und 2. drei Anschlüsse haben (2
für Spannungsversorgung, einer für das Steuersignal (0-20mA od. 4-20
mA).
Bei dem Ventil handelt es sich jedoch definitiv um ein
Proportionalventil. Vielleicht ist es ja hinüber, glaube ich aber
eigentlich nicht. Es hat 2 Anschlüsse, steuerbar mit Strom, Spannung
oder PWM. Sauteuer war es im Vergleich zu einem "normalen" Ventil
ebenfalls: 130 Euro.
Stefan
Ich habe gerade nochmal die Abtastzeit (also die Zeit nach der die
Regelroutine wieder aufgerufen wird) verringert. Jedoch auch bei einer
Zeit von 0,07ms ändert sich nichts an dem Verhalten: Auf dem Oszilloskop
sieht man nachwievor, daß die Pulsbreite ständig zwischen zwei sehr
unterschiedlichen Werten springt. Es wechseln sich fortlaufend
Pulsbreiten von ca. 10% und dann wieder 90% ab.
Hallo Stefan!
Du hast also eine Reaktionszeit über alles von ~2,7ms.
70us Abtastzeit? Das schafft doch der ADW garnicht,du hattest doch
130Khz für'n ADC eingestellt? 2,7ms/0,07ms=~38 Werte zwischen Fluss min
und max, du hast also eine max-Auflösung von 38 Werten. Dein System ist
veflixt schnell! Das 10/90% Springen kommt bestimmt aus einer relativ
grossen Wertänderung am Sensor wärend der Abtastzeit und dem schmalen
Steurbereich deines Vent.Sehr heikle Sache für Ferndiagnose wenn man
noch nicht einmal das System kennt.Eins kann ich dir aber jetzt schon
sagen: Wenn das System so schnell bleibt kommst du um knallhartes ASM
nicht drummherum. Eventuell könnte ein externer ADC das Probl.
entschärfen. Ein anderer Kontroller wäre bei mir auf jedenfall schon in
Verwendung. Sehe ich das richtig, du hast einen Takt von 3,68MHz?
Wenn ja, viel zu langsam, es sind ja noch andere Aufgaben zu erledigen!
Wie schnell kann der Mega323? Maximal ausreitzen bis Übertakten! Die
Tastzeit nicht vom Timer bestimmen lassen sondern vom ADC -immer wenn
fertig Neustart und Daten verarbeiten.Mehr fällt mir momentan nicht ein.
Ach ja Sollwert, Das ist dein notwendiger Offset um die Reglung in den
Arbeitsbereich zu bringen. Durch den
"gleitenden" Offset werden Regelabweichungen besser ausgeglichen. Dein
schlimmstes Probl. ist und bleibt aber das sch... Vent. Ist das Ding
einseitig federbelastet, oder sind das 2 Magneten die gegeneinander
arbeiten? Alles Mist, sehen und austesten muss man sowas!
Trotzdem viel Erfolg, Uwe
Hallo,
ja, das ganze per Ferndiagnose zu machen ist allerdings ziemlich sche...
. Aber leider habe ich hier keinen Fachkundigen vor Ort. Ich werde nun
mal deine einzelnen Fragen der Reihe nach abarbeiten:
1) Wieso meinst du daß mein AD Wandler die 0,07 ms Abtastzeit nicht
schafft? Die AD Wandlung erfolgt mit einer Frequenz von 115,2 kHz. Das
heißt das alle (1/115200) Sekunden eine Wandlung vorgenommen wird, also
alle 0,00868 ms, oder? Das müßte doch ausreichen...
2) Was genau ist ASM?
3) Ich glaube 4 MHz ist die maximale Taktfrequenz. Mit Übertakten kenne
ich mich nicht richtig aus. Wieso meinst du ist das viel zu langsam?
(naja, irgendwo hast du wahrscheinlich recht, ich muß nämlich noch jede
Menge andere Aufgaben erledigen wie Temperaturregelung und eine
Flussregelung für insgesamt 10 (!!!) Ventile)
4) Im Ventil befindet sich meines Wissens eine Spule, die den Kolben
steuert. Ohne Spannungsversorgung ist das Ventil geschlossen.
Stefan
Hallo Stefan!
Ich habe mir dein Probl. noch mal durch den Kopf gehen lassen und bin zu
dem Schluss gekommen, mit einem P-Regler kommst du nicht ans Ziel. Was
du brauchst ist ein I-Regler dessen Stellwert nur bewertet wird.
Die Schnelligkeit deines Systems, die beim P-Regler stört, kommt uns
jetzt bei der Regelgeschwindigkeit entgegen. Wie meine ich das nun.
Erstmal was grundsätzliches : der ausgebbare Stellwert bewegt sich im
Bereich Wert(Vent.zu)-5% bis Wert(Vent. offen) +5% , die Tastzeit legst
du auf den 3-4 Wert der Systemregelzeit, also ca.10ms. Der Wert der
Regelabweichung wird nur bewertet, und als Stellwert ausgegeben. Also ,
Abweichung <5 kein Stellwert; 5-10 = Stellwert 1; 11-20 = Stellwert 2
und >20 = Stellwert 3. Die Werte sind jetzt natürlich frei festgelegt
und bedürfen der Optimierung. Bei jedem Regeltakt wird deine PWM also um
max. 3 verändert Das System wird dadurch mächtig ausgebremst und hat
Zeit sich einzustellen.
Als kleiner Nebeneffekt entsteht ein Zeitgewinn für die anderen Aufgaben
des Kontrollers. Durch die 10ms Tastzeit hast du hoffentlich ein noch
genügend schnelles System (100 Stellwerte je Sekunde)
Ich hoffe du kannst mir irgendwie folgen, bin ein schlechter Erklärer,
und bringst den Regler jetzt zum regeln.
<Wieso meinst du daß mein AD Wandler die 0,07 ms Abtastzeit <nicht
schafft? Die AD Wandlung erfolgt mit einer Frequenz <von 115,2 kHz. Das
heißt das alle (1/115200) Sekunden eine <Wandlung vorgenommen wird, also
alle 0,00868 ms, oder? Das <müßte doch ausreichen
Das ist der Takt für den ADC, du musst aber 10 Bit Wanden, also 70us.
Das ist übrigens genau das was im Datenblatt anderer Kontroller steht.
Oder ist der Mega323 schneller?
MFG Uwe
Hallo Stefan
Ich verstehe nicht warum du eine so hohe samplingfrequenz nimmst (soweit
ich weiss ist die maximale samplefrequenz 15khz) und innerhalb der muss
deine Regelroutine durchlaufen werden.Ich glaube nicht dass dein Ventil
schneller ist als eine typische PWM mit 4KHz.Als Samplefrequenz sollte
500Hz vollkommen ausreichen.(oder was sollen da für Druckunterschiede
geregelt werden?)
Zwischen dem Luftdrucksensor und dem ADC sollte ein Tiefpass sein der
mindestens 40dB Daempfung bei 250 Hz hat(eigentlich sollte ueberhaupt
keine Frequenzen oberhalb der halben Samplefreq durchgelassen werden
weil dein Regler sonst auf
Frequenzen im falschen Frequenzbereich antwortet.(aliasingeffekte)
und muessen die Reglerwerte nicht auch an die Samplefrequenz
angeglichen werden?
Ist die Exceltabelle die oeffnung des Ventils bei reiner PWM oder in
Verbindung mit dem Regler aufgenommen?
Du solltest eine Tabelle machen: eingangswerte 0..100% ausgangswerte
entsprechende PWM Werte ueber die du linearisierst.
Ich hoffe das hilft ein bisschen
CU Wolfram
Hallo Wolfram, erstmal danke für die Antwort.
Wie bastel ich mir denn einen Tiefpass mit 40 db Dämpfung bei einer
frequenz von 250 Hz? Wie ein "normaler" Tiefpaß aussieht weiß ich, wie
ich das mit den 40 dB mit einbeziehe weiß ich leider nicht.
Was genau meinst du mit "Reglerwerten" die an die Samplefrequenz
angepaßt werden sollen?
Die Excel Tabelle ist übrigens die Öffnung des Ventils (bzw. der vom
Flussmesser gemessene Durchfluss, der abhängig von der Ventilöffnung
variiert) in abhängigkeit (nur) von der Pulsbreite. Eine Regelung ist
dort nicht dabei, ich habe einfach die Pulsbreite von 0 angefangen
kontinuierlich erhöht und mir angesehen was am Flussmesser ankommt.
Stefan
@ Uwe: Danke für deine Tipps, ist gut möglich daß ich mit einem reinen
P-Regler nicht weiterkomme. Jedoch sehe ich in deiner Beschreibung nicht
genau wo denn nun eigentlich der I-Anteil steckt. So wie du das erklärt
hast:
>Der Wert der Regelabweichung wird nur bewertet, und als>Stellwert ausgegeben. Also , Abweichung <5 kein Stellwert; 5->10 = Stellwert 1;
11-20 = Stellwert 2 und >20 = Stellwert 3.
würde ich das mit if und else Schleifen abprüfen, dann sehe ich jedoch
nicht genau, wo da noch ein richtiger PI Regler hintersteckt.
Gruß,
Stefan
Hallo Stefan!
Ich sagte ja, bin ein schlechter Erklärer.
Der I-Anteil entsteht durch das Aufsummieren der Stellwerte (sagen wir
+3)bei jedem Zyklus zb.:
PWM=100->Zyklus->PWM=103->Zyklus->PWM=106 ....
und beim Überschwingen natürlich zurück. Durch die grosse Tastzeit
sollte aber kein Überschwingen eintreten.
Habe mir übrigens deine Öffnungskurven noch einmal angeschaut und
festgestellt das bei 110Hz der Stellvorgang recht gut ausschaut. ->Kann
es möglich sein das das Vent.am besten mit Gleichspannung funktioniert?
Hast du das mal getestet? Ich meine so ein Vent. ist ja auch nur eine
Induktivität und die sind nicht gut auf NF zu sprechen.
Nicht locker lassen, das wird schon!
MFG Uwe
Stefan,
schau mal hier
http://209.41.13.11/d/NEWS_S6_D.pdf
dein ventil ist ein hundsnormales magnetventil: entweder
auf... oder ...zu!
ich glaube du verlierst nur deine zeit.
ed
@ edi: Ich glaube mittlerweile daß Proportionalventile garnicht so
proportional arbeiten wie es sich anhört... . Ich habe gerade nochmal
ein anderes Proportionalventil eines anderen Herstellers (Bürkert)
erhalten. Dessen Kennlinie sieht ziemlich ähnlich aus: der halbwegs
lineare Teil befindet sich in einem sehr kleinen Fenster. Ich habe das
Excel File mit der Kennlinie nochmal angehängt, guck dir das mal an. Daß
beide Ventile einen Fehler haben ist ja eher unwahrscheinlich...
Gruß,
Stefan
ps: die Werte auf der x-Achse entsprechen übrigens der Pulsbreite meiner
10 bit PWM: 1023 entspricht Pulsbreite von 100 %.