mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Regler regelt nicht :-(


Autor: Kartoffel (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo zusammen, mache jetzt weiter an dem Regler für einen GS Motor.
Ich programmiere mit Keil, µC ist der XC167.
Ich habe mir überlegt, den Regler in einem Timer Interrupt aufzurufen, 
denn dann kann ich ja die Zeit einstellen, wie oft der Regler aufgerufen 
wird.

In einem anderen C-Teil schreib ich dann die Stellgröße, die der Regler 
liefert, in das zugehörige Register, der für die Breite von PWM 
zuständig ist  und zwar so :
void CC2_viTmr8(void) interrupt CC2_T8INT //using RB_LEVEL8
{
  // USER CODE BEGIN (Tmr8,2)

 a=0x0000;
 a = Drehzahl_mot; // Istdrehzahl
 b=Regeln (a);    // Regeln mit Istdrehzahl
 CC2_CC30=b; // Stellwert reinladen
 
  // USER CODE END

}

der Regler schaut so aus:


//*************************************************************************************
//                     Includes
//*************************************************************************************

#include "MAIN.H"
#include <REGLER.h>



//*************************************************************************************
//                    Defines
//*************************************************************************************
#define MAX 65535    // untere Grenze
#define MIN 65135     // obere Grenze


//*************************************************************************************
//                    Variablen
//*************************************************************************************

bit Begrenzung;        //Flag signalisiert, wenn Stellgröße in der Begrenzung ist
int Pulsbr = 400;
extern unsigned int Solldrehzahl; // Drehzahlvorgabe


//*************************************************************************************
//                    Prototypen
//*************************************************************************************

//unsigned long int Regeln (unsigned long int Istdrehzahl); // Funktion zum Aufrufen des Reglers


//*************************************************************************************
//                     Funktionen
//*************************************************************************************
extern int PI_Init(void)
{         
pi_r.Kp = 18;
pi_r.Ki = 60;
Begrenzung=0;
pi_r.I_Anteil=0;
pi_r.Regelabweichung = 0;

return 0;

}
//*************************************************************************************

unsigned long int Regeln (unsigned long int Istdrehzahl)
{
signed long int Stellwert = 0;       // Bereich zwischen -65535 bis +65535
signed long int Stellwert_skall = 0;    // Bereich zwischen -400 bis 400


  pi_r.Istwert=Istdrehzahl;
  pi_r.Sollwert=Solldrehzahl;  
  pi_r.Regelabweichung = pi_r.Sollwert-pi_r.Istwert;             // e=w-x

  //         Antiwindup     

  if (Begrenzung!=1)          // dann nicht im begrenzten Bereich
  {
    pi_r.I_Anteil = pi_r.I_Anteil+pi_r.Regelabweichung;          // esum=esum+e

  }  

  //pi_r.I_Anteil = pi_r.I_Anteil+pi_r.Regelabweichung;          // esum=esum+e

  Stellwert = pi_r.Kp*pi_r.Regelabweichung + (pi_r.Ki*pi_r.I_Anteil)/100;  //Ta=0.01
  Stellwert_skall = Stellwert*Pulsbr/MAX;
  pi_r.Stellwert= CC2_CC30 + Stellwert_skall;
                         
  //   Begrenzung des Stellenwertes auf die maximale Größe

  if(pi_r.Stellwert<MIN)      // Begrenzung nach unten, also auf FE60
  {
    pi_r.Stellwert = MIN;
    Begrenzung = 1;         // Rergler läuft in der Begrenzung
 
  } 

  else if(pi_r.Stellwert>MAX)    // Begrenzung nach oben, also auf FFFF
  {  
    pi_r.Stellwert =MAX;
    Begrenzung = 1;            // Regler läuft in der Begrenzung
  }

  else
  {
    Begrenzung =0;
  }

  return pi_r.Stellwert;      // Übergabe Stellgröße
}
//****************************************************************************************


Mein Problem ist:
wenn ich das Programm reinlade, dreht sich der Motor nur ein paar 
Sekunden und bleibt dann stehen und es tut sich nichts mehr. Wenn ich 
die Zeile mit
 CC2_CC30=b; // Stellwert reinladen

auskommentier, dann dreht er sich mit der vorgegebenen 
Sollgeschwindigkeit (das geschieht in einer anderen C-Datei).
Hat jemand eine Idee woran das liegen könnte?

Danke schön

Autor: David (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
check mal die datentypen (typenumwandlung!)

Autor: Kartoffel (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hab jetzt eine Enteckung gemacht:
Ich habe ja eine Init Funktion für den Regler, wo ich die Kp und Ki 
Patameter initialisier. Jetzt hab ich an dem Ki gedreht. Und zwar ist er 
ja bei mir 60 gewesen. Jetzt hab ich ihn auf 8000 !!! erhöht (also nur 
so rumgespielt). Dann hat sich der Motor durchgehend gedreht, aber mit 
ner Istgeschwindigkeit von 3000, bei der Sollwertvorgabe von 1000. Was 
sagt mir das?

Autor: 3348 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Also. Du solltest dir die wichtigsten Parameter online ueber die 
serielle Schnittstelle ausgeben lassen und sie graphisch aufzeichnen.

Autor: Kartoffel (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@3348

also ich kann die Parameter ja auch beim Debuggen anschauen (watch 
Fenster),nicht?
Oder welche Parameter meinst du?

Autor: 3348 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Debuggen ? So heisst ja der Prozess des Fehlerfindens. Du kannst ja 
nicht singlesteppen, sonst ist der physikalische Prozess weg. Schau Dir 
Zwischenresultate, Sensordaten, Stellgroessen in Echtzeit an. Falls dies 
ueber die serielle Schnittstelle nicht moeglich ist, nimm einen 
Mehrfach-DAC und schreib die Werte auf den DAC, anschauen mit dem Scope. 
So kann man sehen, ob eine Variable sich unerwartet verhaelt.

Autor: Kartoffel (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@3348
kann ich eigentlich die Ser. Schnittstelle des µC verwenden?
Vllt. ne blöde Frage, aber wie geht das genau, ich hab sowas noch nie 
gemacht.
Kann ich die WErte, die ich sehen will, z.B. die Stellgröße oder so an 
die SSO per Programm schicken und dann am Hyperterminal irgendwie 
anschauen?

Autor: 3348 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wie die Serielle Schnittstelle geht sollte im X167 manual stehen. 
Allenfalls wird sie vom Compiler, resp dessen libraries unterstuetzt. 
Ja, man kann was mit dem hyperterminal machen. Besser ist allerdings ein 
Spezialisiertes zu schreiben, das graphische Ausgabe machen kann. Mit 
dem Hypertem kann man zb.
ein byte zum Controller senden, dadurch den Kanal(Variable) selektieren, 
die dann vom Controller periodisch zum Hyperterm geschickt wird.

Autor: Kartoffel (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
muss ich eigentlich mit der ASC die Daten auf den Hyperterminal 
SCHREIBEN oder die Werte aus dem Programm rausLESEN?
Also RxD oder TxD?

Autor: Thilo M. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich denke, du solltest mit dem Betrag der Regelabweichung arbeiten 
(ohne Vorzeichen), da die Stellgröße (PWM) ja nicht negativ werden kann.

Autor: Kartoffel (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
also ich denke, dass ich mir die Sprungantwort anschauen sollte.
Daraus kann ich die Reglerparameter bestimmen (Ta, Ki und Kp). Dann 
bekomme ich ja raus, ob es daran liegt, dass ich die Parameter mehr oder 
weniger willkürlich gewählt hab (bin irgedwo im Netz darauf gestoßen). 
Dazu habe ich aber ein paar Fragen:
1. Die Sprungantwort isd doch meine Istgeschwindigkeit, oder?
2.Wie nehm ich die am Besten in Abhängigkeit von der Zeit auf (ohne 
Hilfsmittel)? Hyperterminal und ser. Schnittstelle?

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Dein erster und wichtigster Schritt ist nach wie vor:
Du musst dir eine Möglichkeit schaffen, wie du dem Regler
bei der Arbeit zusehen kannst.
Ob das jetzt Zahlen im Hyperterminal sind oder eine Graphik,
die den zeitlichen Verlauf zeigt, spielt erst mal keine Rolle.
Aber du musst aus dem Zustand "im Nebel stochern" raus!

Ein Debugger ist da kein Ersatz dafür, weil du es mit einem
dynamischen System zu tun hast! Im Grunde ist selbst eine Ausgabe
über die serielle Schnittstelle schon grenzwertig, weil sie ebenfalls
Zeit verbraucht und damit die Regelcharakteristik verfälscht.
Aber du hast nichts anderes.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Thilo M. wrote:
> Ich denke, du solltest mit dem Betrag der Regelabweichung arbeiten
> (ohne Vorzeichen), da die Stellgröße (PWM) ja nicht negativ werden kann.

Aha. Und wie regelt der Regler dann bei einem Überschwingen wieder
zurück, wenn die Regelabweichung nicht negativ werden kann?

Autor: Kartoffel (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
das ist mir schon klar, nur weiß ich leider nicht ganz, wie ich da 
anfangen soll. Am Liebsten wär mir natürlich eine Grafik, wo ich das 
Reglerverhalten anschauen kann über eine bestimmte Zeit, aber wie ich 
das machen soll, da habe ich keine Ahnung :-( Ich habe keine 
zusätzlichen Programme oder so, nen Oszi hab ich..

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Kartoffel wrote:
> das ist mir schon klar, nur weiß ich leider nicht ganz, wie ich da
> anfangen soll.

Indem du dir über die serielle Schnittstelle mal
Sollwert, Istwert, und die daraus resultierende Stellgröße ausgeben
lässt. Wenn das nicht reicht, dann kommen noch ein paar
Zwischenergebnisse auf die Schnittstelle.

> Am Liebsten wär mir natürlich eine Grafik, wo ich das
> Reglerverhalten anschauen kann über eine bestimmte Zeit, aber wie ich
> das machen soll, da habe ich keine Ahnung

Du lässt dir die Ausgabe am PC in eine Datei schreiben und benutzt
danach Excel (oder was du sonst noch so hast) um aus dem Datenwust
eine Grafik zu machen. Wenn du die Ausgabe µC-seitig gleich
mal vernünftrig formatierst (Tab oder ; zwischen die Werte, am Ende
eines Datensatzes ein \n) dann ist das noch nicht mal viel Arbeit.
Bei Excel hast du nur das eine Problem, dass es gerne , als Dezimal-
punkt hätte. Also vorher mit einem Editor alle . gegen , austauschen
und du hast einen Fuß in der Tür.

Autor: Kartoffel (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@  Karl heinz Buchegger:
aber wie bekomme ich das mit den Zeiten hin?
Ich hab vielleicht Werte ohne Ende, aber wie soll ich die Werte den 
Zeiten zuordnen? Also ich weiß ja net, welchen Wert z.B. die Stellgröße 
nach 5s hat oder nach 10s etc. Also woher bekomm ich die Zeitskala?

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ein Durchlauf durch die Regelschleife dauert wie lange?
Zu welchem Zeitpunkt ist daher der 100te Datensatz angefallen?

Und nochwas: Es hat keinen Sinn mit allen Reglerparametern
gleichzeitig zu spielen. Setze mal den I Anteil
auf 0. Der verleibende P Anteil sollte die Istgröße der
Sollgröße nachführen, auch wenn er sie nie erreichen wird.
Aber wenn die SOllgröße steigt, muss auch die Istgröße steigen
und umgekehrt. Wenn nicht, dann hast du irgendwo einen Vorzeichen-
fehler. Probehalber mal das Kp mit anderem Vorzeichen nehmen.
Danach erhöhst du den P Anteil, bis die Regelung zu schwingen
anfängt und gehst dann wieder etwas zurück. Und erst dann
fängst du an den Ki mit kleinen Werten aus seiner 0 heraus
zu führen.

Systematisch vorgehen! Wildes Drauflosraten bringt dich nicht
weiter.

Autor: Kartoffel (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@ Karl heinz Buchegger:
Danke, werd ich versuchen. Ich weiß nur die Abtastzeit des Reglers, also 
ca. 13ms (Dann Timerüberlauf und Interrupt). Das heißt ja, dass ich pro 
13ms einen neuen Wert habe, stimmts?

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Kartoffel wrote:
> @ Karl heinz Buchegger:
> Danke, werd ich versuchen. Ich weiß nur die Abtastzeit des Reglers, also
> ca. 13ms (Dann Timerüberlauf und Interrupt). Das heißt ja, dass ich pro
> 13ms einen neuen Wert habe, stimmts?

Im Prinzip ja, nur wirds jetzt etwas mehr sein, da ja die Übertragung
auch Zeit braucht. Die exakte Zeit ist aber erst mal nicht soooo
wichtig. Wichtig ist erst mal, dass du siehst was in dem Regler
so vor sich geht.

Autor: Thilo M. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Karl heinz Buchegger wrote:
> Thilo M. wrote:
>> Ich denke, du solltest mit dem Betrag der Regelabweichung arbeiten
>> (ohne Vorzeichen), da die Stellgröße (PWM) ja nicht negativ werden kann.
>
> Aha. Und wie regelt der Regler dann bei einem Überschwingen wieder
> zurück, wenn die Regelabweichung nicht negativ werden kann?

Hoppla ...
war noch beim Schrittregler, der braucht 'ne variable Impuls- und 
Pausenlänge (immer positiv, der Schaltausgang wird durch's Vorzeichen 
bestimmt). PI-Regler muss natürlich auch negativ werden können. ;)

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.