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


von Kartoffel (Gast)


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 :
1
void CC2_viTmr8(void) interrupt CC2_T8INT //using RB_LEVEL8
2
{
3
  // USER CODE BEGIN (Tmr8,2)
4
5
 a=0x0000;
6
 a = Drehzahl_mot; // Istdrehzahl
7
 b=Regeln (a);    // Regeln mit Istdrehzahl
8
 CC2_CC30=b; // Stellwert reinladen
9
 
10
  // USER CODE END
11
12
}

der Regler schaut so aus:
1
//*************************************************************************************
2
//                     Includes
3
//*************************************************************************************
4
5
#include "MAIN.H"
6
#include <REGLER.h>
7
8
9
10
//*************************************************************************************
11
//                    Defines
12
//*************************************************************************************
13
#define MAX 65535    // untere Grenze
14
#define MIN 65135     // obere Grenze
15
16
17
//*************************************************************************************
18
//                    Variablen
19
//*************************************************************************************
20
21
bit Begrenzung;        //Flag signalisiert, wenn Stellgröße in der Begrenzung ist
22
int Pulsbr = 400;
23
extern unsigned int Solldrehzahl; // Drehzahlvorgabe
24
25
26
//*************************************************************************************
27
//                    Prototypen
28
//*************************************************************************************
29
30
//unsigned long int Regeln (unsigned long int Istdrehzahl); // Funktion zum Aufrufen des Reglers
31
32
33
//*************************************************************************************
34
//                     Funktionen
35
//*************************************************************************************
36
extern int PI_Init(void)
37
{         
38
pi_r.Kp = 18;
39
pi_r.Ki = 60;
40
Begrenzung=0;
41
pi_r.I_Anteil=0;
42
pi_r.Regelabweichung = 0;
43
44
return 0;
45
46
}
47
//*************************************************************************************
48
49
unsigned long int Regeln (unsigned long int Istdrehzahl)
50
{
51
signed long int Stellwert = 0;       // Bereich zwischen -65535 bis +65535
52
signed long int Stellwert_skall = 0;    // Bereich zwischen -400 bis 400
53
54
55
  pi_r.Istwert=Istdrehzahl;
56
  pi_r.Sollwert=Solldrehzahl;  
57
  pi_r.Regelabweichung = pi_r.Sollwert-pi_r.Istwert;             // e=w-x
58
59
  //         Antiwindup     
60
61
  if (Begrenzung!=1)          // dann nicht im begrenzten Bereich
62
  {
63
    pi_r.I_Anteil = pi_r.I_Anteil+pi_r.Regelabweichung;          // esum=esum+e
64
65
  }  
66
67
  //pi_r.I_Anteil = pi_r.I_Anteil+pi_r.Regelabweichung;          // esum=esum+e
68
69
  Stellwert = pi_r.Kp*pi_r.Regelabweichung + (pi_r.Ki*pi_r.I_Anteil)/100;  //Ta=0.01
70
  Stellwert_skall = Stellwert*Pulsbr/MAX;
71
  pi_r.Stellwert= CC2_CC30 + Stellwert_skall;
72
                         
73
  //   Begrenzung des Stellenwertes auf die maximale Größe
74
75
  if(pi_r.Stellwert<MIN)      // Begrenzung nach unten, also auf FE60
76
  {
77
    pi_r.Stellwert = MIN;
78
    Begrenzung = 1;         // Rergler läuft in der Begrenzung
79
 
80
  } 
81
82
  else if(pi_r.Stellwert>MAX)    // Begrenzung nach oben, also auf FFFF
83
  {  
84
    pi_r.Stellwert =MAX;
85
    Begrenzung = 1;            // Regler läuft in der Begrenzung
86
  }
87
88
  else
89
  {
90
    Begrenzung =0;
91
  }
92
93
  return pi_r.Stellwert;      // Übergabe Stellgröße
94
}
95
//****************************************************************************************

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
1
 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

von David (Gast)


Lesenswert?

check mal die datentypen (typenumwandlung!)

von Kartoffel (Gast)


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?

von 3348 (Gast)


Lesenswert?

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

von Kartoffel (Gast)


Lesenswert?

@3348

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

von 3348 (Gast)


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.

von Kartoffel (Gast)


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?

von 3348 (Gast)


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.

von Kartoffel (Gast)


Lesenswert?

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

von Thilo M. (Gast)


Lesenswert?

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

von Kartoffel (Gast)


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?

von Karl H. (kbuchegg)


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.

von Karl H. (kbuchegg)


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?

von Kartoffel (Gast)


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..

von Karl H. (kbuchegg)


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.

von Kartoffel (Gast)


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?

von Karl H. (kbuchegg)


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.

von Kartoffel (Gast)


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?

von Karl H. (kbuchegg)


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.

von Thilo M. (Gast)


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. ;)

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
Noch kein Account? Hier anmelden.