Hallo, ich habe mir einen PI Regler für meine Durchflussregelung gebastelt, der eigentlich auch schon ganz gut funktioniert. Nur habe ich zu Beginn immer einen ziemlich riesigen Überschwinger. Ich frage mich, ob es ein Hardwareproblem sein könnte (A/D Wandler oder Gasflussensor), oder ob ich da noch etwas an der Regelung probieren müßte. Mit unterschiedlichen k_p Werten habe ich schon gearbeitet (s. excel file). Habt ihr noch eine Idee? (ps: Durchflussregelung müßte eigentlich auch ohne D-Anteil möglich sein, ich habe gehört, daß die D-Anteile immer relativ schwer einzustellen sind.) Gruß, Stefan
Hi evtl. hilft es die Regelabweichung die du errechnest auf einen gewissen Maximalwert zu begrenzen. Dann dauert es zwar etwas länger bis der Sollwert erreicht wird aber die Überschwinger sind lange nicht so heftig. Matthias
Hi Stefan 1. Ich würde mit einem D-Anteil arbeiten! 2. In deinem Fall ist aber der I-Anteil viel zu groß! Setze ihn mal um 0,6 runter und lasse den P-Anteil mal wie er ist! Liebe Grüße Tassilo
Hallo Tassilo, danke für die Tipps. Einen D-Anteil habe ich bisher nicht eingebaut, ich habe nur mal etwas am I-Anteil gedreht. Sieht aber nicht besonders viel besser aus, einen Überschwinger bekomme ich immer, ist jedoch immer nur genau ein AD Wert. Frage mich ob das vielleicht irgendwie mit dem Messrauschen des Sensors zusammenhängen könnte. Nur je kleiner ich den I-Anteil mache, desto größer wird die bleibende Regelabweichung (irgendwie logisch). Ich habe das Bild nochmal mit angehängt. Gruß, Stefan
Hat Du die Source von deinem Regler? Kannst Du die Mal Posten? LG Tassilo
Aber es schaut ja schon besser aus! - oder? Setze den P-Antel mal runter! Und der D-Antel mal hoch! LG Tassilo
Hier ist der wesentliche Sourcecode: (D-Anteil habe ich noch nicht eingebaut) unsigned int v_ist; int e_k; // Regelabweichung float k_i =0.05; float k_p =0.002; // 1.446 Verstärkungsfaktor int u_i = 0; int u_p = 0; int u_g = 0; volatile unsigned int v_soll; char istwert[4]; char wert[4]; #define ADC_VREF_TYPE 0x00 // ADC interrupt service routine interrupt [ADC_INT] void adc_isr(void) { unsigned int adc_data; //in adc_data wird das Ergebnis gespeichert // Read the AD conversion result adc_data=ADCW; // aktuelle Spannung einlesen (Wert zwischen 0 und 1023): v_ist = adc_data; // Regelabweichung e_k berechnen: e_k = v_soll - v_ist; // Begrenzung der Regelabweichung: if (e_k > 600) u_p = 600; else if (e_k < -600) u_p = -600; // P-Anteil u_p = (int) (e_k * k_p); // I-Anteil u_i += (int) (e_k * k_i); // gesamte Stellgröße (Summe aus P und I) u_g = u_i + u_p; // Stellgrößenbegrenzung: //if (u_p > 600) u_p = 600; //else if (u_p < 400) u_p = 400; // Stellgröße in entsprechenden PWM Wert umrechnen und // Pulsbreite setzen: OCR1A = (int) u_g; itoa(v_ist,istwert); puts(istwert); }
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.