mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik DC Motor: Stromregelung mit PWM


Autor: Mathias Quetschlich (paolo_pinkel)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo zusammen,

fuer mein Projekt - der Geschwindigkeitsregelung eines DC 
Reihenschlussmotors bin ich gerade dabei eine gescheite regelung zu 
entwerfen.

Geplant ist eine Kaskadenregelung mit Stromregler als Begrenzer im 
inneren Regelkreis.

Dieser soll als PI Regler ausgelegt sein, mit der Stellgroesse des 
Geschwindigkeitsreglers minus Strom als Regelgroesse und dem PWM 
Verhaeltniss als Stellgroesse.
Die Pulsweite PW1 geht von 40000...0 (aus...ein).

Zunaechst moechte ich mal den P Anteil festlegen.
(Nach Ziegler/Nichols ist p = 0.45 * Pkrit, wo es grade zu schwingen 
anfaengt)

Fuer den Fall das der Strom groesser wird als der Sollwert, wird der 
Regelanteil (Abweichung = Soll - Ist) negativ. Da ich aber keine 
negative Stellgroesse erzeugen kann, dachte ich mir ich begrenze diesen 
auf 0, sprich PW1 = 40000.

Jedoch merke ich in der Praxis, dass bei solchen Stroemen der PW Wert 
andauernd von aus auf x "springt" und nicht auf aus bleibt.

Koennte mir das nur dadurch erklaeren, dass die Stellgroesse immer nur 
ganz kurz in die Begrenzung geht, der Strom sollte aber auf Grund der 
Induktivitaet des Motors nicht so schnell folgen. Ich kappiers einfach 
nicht.

Der Code des Reglers ist angehaengt, lauft auf nem C167.

Waere toll wenn, mir jemand helfen koennte.

/* ----- A/D Conversion ready interrupt program ----------------------------- */
void ad_int (void) interrupt 0x3F
{

  
  
  ADST = 1;           /* Conversion start */

  while(ADBSY) {};         /* wait of end of conversion */
   
  current = ADDAT & 0x03FF;       /*read result of conversion  */
  


/* ----- PI current control ---------------------------------------- */

   current_error = (long) current_desired - (long) current;

/*** set Deadband ***/  
  current_error_temp = current_error;
   if (current_error_temp < 0)
      current_error_temp *= (-1);
   if (current_error_temp < 10)   /* current error < 100mA       */
      current_error = 0;    /* set current error zero      */
     

/*** Calculate Proportional Term ***/
 current_proportional_term=(current_error*(long)current_proportional_gain);
  

/*** Find Accumulated Error ***/
   if((current_controll_output>=0) && (current_controll_output<=40000))
     current_acc_error = ((long)current_acc_error) + (long)current_error;


/*** Calculate Integral Term ***/
   current_integral_term = (current_acc_error*(long)current_integral_gain) ;

/*** Check For Integral Term Out Of Range & Apply Saturation ***/
   current_integral_term_temp = ((long)current_acc_error * (long)current_integral_gain) ;
   
   if(current_integral_term_temp >= 40000) {  
      current_integral_term = 40000 ;  
      }
   else {
      if(current_integral_term_temp <= 0) {
         current_integral_term = 0 ;
         }
        }




/*** Sum Up Control Terms ***/
   current_controll_output = (long) current_integral_term ;
   current_controll_output += current_proportional_term ;
   

/*** Limit Value Of Control Term ***/
   if(current_controll_output >= 40000) {
      current_controll_output = 40000 ;
    }
   else {
     if(current_controll_output <= 0) {
        current_controll_output = 0 ;
      }
   }
   
  PW1 = 40000 - (short)current_controll_output;

  PWMIR  = 0;            

}


so far...

Autor: Martin Cibulski (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Mathias,

wenn ich den Code richtig verstehe, begrenzt Du zuerst
die Zwischenergebnisse und am Ende den Ausgang noch einmal.
Dann dauert es beim Zurückschwingen erst eine gewisse Zeit, bis
am Ausgang die 100% verlassen werden.
Wenn also die P und I-Werte Vollausschlag (100%) und der Ausgang die
Summe auf 100% begrenzt, sind im Regler immernoch 200% vorhanden, die
beim Gegenregeln erst einmal abgebaut werden müssen.

Ich verwende einen Algorithmus nur mit Differenzen
zum vorigen Zyklus auskommt, dann tritt das Problem nicht auf.
Außerdem normiere ich erst alle Ein- und Ausgänge, das geht auch mit 
Integer-Zahlen.

Läuft der Motor nur vorwärts ?
Wenn nicht, brauchst Du auch negative Stellgrößen.
Zumindest beim Abbremsen braucht man doch negativen Strom, oder ?

Gruß,
Martin



VORGABEN:

istwert_min
istwert_max
sollwert_min = istwert_min
sollwert_max = istwert_max
stellgroesse_min
stellgroesse_max
V : Verstärkung
TN : Nachstellzeit in Rechenzyklen

NORMIEREN:

sollwert_norm = (sollwert - istwert_min) / (istwert_max - istwert_min)
istwert_norm = (istwert - istwert_min) / (istwert_max - istwert_min)
Stellgroesse_norm  = (stellgroesse - stellgroesse_min) / 
(stellgroesse_max - stellgroesse_min);

DIFFERENZEN ZUM LETZTEN ZYKLUS:

diff_sollwert = sollwert_norm - alt_sollwert_norm
diff_istwert = istwert_norm - alt_istwert_norm

NEUE STELLGROESSE (NORMIERT):

Stellgroesse_norm  = Stellgroesse_norm
                  + V * ((diff_sollwert - diff_istwert) + (sollwert_norm 
- istwert_norm) / TN);

STELLGROESSE DENORMIEREN:

Stellgroesse = stellgroesse_min
             + Stellgroesse_norm * (stellgroesse_max - 
stellgroesse_min);

STELLGROESSE BEGRENZEN:

if Stellgroesse > Stellgroesse_max then
    Stellgroesse = Stellgroesse_max;
end;
if Stellgroesse < Stellgroesse_min then
    Stellgroesse = Stellgroesse_min;
end;

Autor: Mathias Quetschlich (paolo_pinkel)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi Martin (und andere)

> Wenn also die P und I-Werte Vollausschlag (100%) und der Ausgang die
> Summe auf 100% begrenzt, sind im Regler immernoch 200% vorhanden, die
> beim Gegenregeln erst einmal abgebaut werden müssen.

Theoretisch stimmt das schon, aber bei den Tests, die ich fahre ist der 
I-Anteil sowieso erstmal auf null gesetzt. Es handelt sich um einen 
reinen P-Regler.


> Ich verwende einen Algorithmus nur mit Differenzen
> zum vorigen Zyklus auskommt, dann tritt das Problem nicht auf.
> Außerdem normiere ich erst alle Ein- und Ausgänge, das geht auch mit
> Integer-Zahlen.

Was einem D-Regler entspricht, den ich gar nicht einsetze. Spaeter werde 
ich den I-Anteil zuschalten.

> Läuft der Motor nur vorwärts ?

ja


Nochmal zu meinem eigentlichen Problem:

Wenn der Strom hoeher wird als der Sollwert, springt die Stellgroesse 
mit einigen Mhz zwischen 0 und ca. 70/80%. Eigentlich sollte Sie null 
bleiben bis der Strom unter den Sollwert sinkt.

Wenn ich das Ding simuliere tritt der Effekt nicht auf.

Koennte es sich um einen Aliasing - Effekt handeln? Der Regler wird 
einmal pro Puls, nach jeder A/D Wandlung aufgerufen

Autor: Mathias Quetschlich (paolo_pinkel)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Nachtrag:

Ich vermute, der Fehler liegt incht beim Regler, sondern vielleicht Beim 
Sensor oder A/D Wander, oder sonstwo.

Ich habe spasseshalber mal einen simplen Zweipunktregler genommen:
if(current > current_desired ) 
P7 = 0x0000;                     //Ausgang null

if(current < current_desired ) 
 P7 = 0x0002;                    //Ausgang eins

Gleiches Resultat: wenn der Strom ueber den Sollwert steigt (auch bei 
grosser Differenz) schaltet der Regler schnell zwischen null und eins, 
statt auf null zu bleiben.

*gruebel, gruebel*

Autor: Mathias Quetschlich (paolo_pinkel)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Nachtrag 2:

Der Stromwert bricht ab und zu (auch im hoeren Bereich) ein, fragt nicht 
warum, vermute das haengt mit dem Stromfreilauf zusammen. Sollte auf 
Grund der Induktivitaet aber gar incht gehen, na weiss der Kuckuck.

Ich habe das Problem jetzt geloest, indem ich den Stromwert 
approximiere:
current = (49*current + current_temp)/50;

Geht ganz gut...

LG

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.