Forum: Mikrocontroller und Digitale Elektronik Hilfe PI-Regler Realisierung


von Meier (Gast)


Lesenswert?

Hallo,

kann sich villeicht jemand mal meine nachfolgende Realisierung eines 
PI-Reglers in Festkommaarithmetik anschauen und mir sagen wo noch 
Verbesserunsgpotentiale oder auch Fehler sind?
Der Regler geht als Stellwert an eine 8bit PWM.

Insb. hab ich jetzt durch die vielen 16bit Variablen das Problem das 
mein Programmspeicher fast voll ist. Wo kann ich noch einsparen?

Und wie sollte die Grenze für den Anti Wind-up des I-Anteils gewählt 
werden?

Gruss
1
#define KP      1
2
#define KI      0
3
#define TA      0.1  //Abtastzeit 100ms
4
5
6
7
8
uint8_t pi_regler(int16_t regelabweichung)
9
{
10
  int16_t p_anteil,i_anteil,pi_regler_output;
11
  
12
  static int16_t regelabweichung_summe=0;
13
  
14
  regelabweichung=regelabweichung/8;        //vom Format S(11,4) zu S(14,1)
15
  
16
  //Bestimmung P-ANTEIL
17
  p_anteil=(p_factor*regelabweichung)/2;
18
  
19
  //Bestimmung I-ANTEIL
20
  regelabweichung_summe+=regelabweichung;
21
  
22
  
23
  //Begrenzung I-Anteil
24
  if(regelabweichung_summe<0)
25
  {
26
    regelabweichung_summe=0;
27
  }
28
  
29
  if(regelabweichung_summe>(255*2))      //Regelabweichung Summe im Format S(14,1)
30
  {
31
    regelabweichung_summe=(255*2);
32
  }
33
  
34
  
35
  i_anteil=(i_factor*regelabweichung_summe)/2;
36
  
37
  //Bestimmung RUECKGABEWERT
38
  pi_regler_output=(p_anteil+i_anteil)/16;
39
  
40
  
41
  if(pi_regler_output>255)
42
  {
43
    pi_regler_output=255;
44
  }
45
  
46
  
47
  if(pi_regler_output<0)
48
  {
49
    pi_regler_output=0;
50
  }
51
  
52
  return (uint8_t) pi_regler_output;
53
  
54
}

von Morz Kerl (Gast)


Lesenswert?

Ausprobieren ?

von Tom K. (ez81)


Lesenswert?

>>mein Programmspeicher fast voll ist.
>> #define TA      0.1   wird in diesem Ausschnitt zwar nicht benutzt,
aber landet die falsche floating point lib in deinem Hex?

von Martin S. (drunkenmunky)


Lesenswert?

Funktioniert das denn, was du hier zusammenprogrammiert hast?

Kannst dir auch mal das hier anschauen:
http://www.rn-wissen.de/index.php/Regelungstechnik

von Meier (Gast)


Lesenswert?

hi,

sorry, hab noch zwei defines vergessen:
1
#define p_factor  (KP*16)
2
#define i_factor  (KI*TA*16)

Wie kann ich heraus finden ob dadurch die floating point lib eingebunden 
wird?


Der P-Anteil funktioniert mal soweit. Beim I-Anteil bin ich mir nicht so 
sicher. Desweitern tue ich mir auch gerade schwer die Regelparameter zu 
bestimmen.

von Meier (Gast)


Lesenswert?

Volltreffer mit der folating point lib!

Wurde eingebunden. Danke für den Tip!!

von Tom K. (ez81)


Lesenswert?

Wenn Du float brauchst, das hier beachten, um keinen Speicher zu 
verschwenden: Beitrag "Re: Programmspeicher beim Tiny26 voll"

von Meier (Gast)


Angehängte Dateien:

Lesenswert?

Hallo,

hab das ganze nun nochmal etwas überarbeitet. Und versuche nun die 
Regelparameter zu ermitteln... Komme aber einfach nicht weiter und weiss 
auch nicht richtig woran es liegen könnte.

Bei einem KP von 1 (KI=0) kommt das ganze ins Schwingen. Könnte 
vielleicht der ein oder andere Reglungstechnik Profi hierzu was sagen?
Bzw. mir einen Anhaltspunkt geben mit welchem KP ich Anfangs beginnen 
sollte?

Angeschlossen ist ein kleiner Heizstab und als Sensor kommt ein DS18B20 
zum Einsatz. Der Outputwert des Reglers wird direkt als Stellwert für 
die 8bit PWM genutzt.
Der Regler soll alle 100ms aufgerufen werden.

Ist die Realisierung meines Reglers nun so korrekt?

hier mein vollständiger Sourcecode:
1
#define F_CPU 16000000UL
2
3
#include <avr/io.h>
4
#include <avr/interrupt.h>
5
#include <stdint.h>
6
7
#include "ds18b20.h"
8
#include "debug_master.h"
9
#include "statusled.h"
10
11
12
//###########################################################################################################
13
//Definiton Soll-Temperaturwert
14
//###########################################################################################################
15
16
#define temperatur_sollwert_eingabe            50
17
//#define temperatur_korrektur_offset            0
18
19
20
21
//###########################################################################################################
22
//Definiton PI-Regler Parameter
23
//###########################################################################################################
24
25
#define SCALING_FACTOR 128
26
27
#define KP          ((uint16_t)(1*SCALING_FACTOR))    //KP Eingabe bis 255 möglich
28
#define KI          ((uint16_t)(0*SCALING_FACTOR))    //KI Eingabe bis 255 möglich
29
#define TA          ((uint16_t)(0.1*SCALING_FACTOR))  //Abtastzeit 100ms
30
31
//##################################
32
33
#define PRELOAD_VALUE    131
34
#define TIME_INTERVAL    50
35
36
//##########################################################################################################
37
38
39
volatile uint8_t regler_flag;
40
41
42
43
44
void Timer1_PWM_init()
45
{
46
  //Set OC1B as output;
47
  DDRB|=(1<<PB3);
48
  
49
  //Set COM1B1 and COM1B0 --> OC1B cleared on compare match and set when TCNT1=01; Set PWM1B --> Enable PWM B
50
  TCCR1A=(1<<COM1B1)|(1<<PWM1B);
51
  
52
  //Set Prescaler 8, ergibt 7812,5 Hz bei F_CPU=16 Mhz
53
  TCCR1B=(1<<CS12);
54
  
55
}
56
57
58
59
uint8_t pi_regler(int16_t regelabweichung)
60
{
61
  int16_t p_factor,i_factor;
62
  
63
  int32_t p_anteil,i_anteil,pi_regler_output;
64
  
65
  static int16_t regelabweichung_summe=0;
66
  
67
  p_factor=KP;                //Format S(8,7)
68
  i_factor=(((int32_t)KI)*TA)/SCALING_FACTOR;        //Format S(8,7)
69
  
70
  
71
  regelabweichung=regelabweichung/8;          //Umwandlung Format S(11,4) zu S(14,1), da Sensor sowieso nur einen Wert mit 0,5 Grad Auflösung liefert
72
  
73
  //Bestimmung P-ANTEIL
74
  p_anteil=((int32_t)p_factor*regelabweichung)/2;        //Berechnung im Format S(24,7)
75
  
76
  //Bestimmung I-ANTEIL
77
  regelabweichung_summe+=regelabweichung;          //Berechnung im Format S(14,1)
78
  
79
  
80
  //Begrenzung I-Anteil
81
  if(regelabweichung_summe<0)
82
  {
83
    regelabweichung_summe=0;
84
  }
85
  
86
  if(regelabweichung_summe>(255*2))          //Regelabweichung Summe im Format S(14,1)
87
  {
88
    regelabweichung_summe=(255*2);
89
  }
90
  
91
  
92
  i_anteil=((int32_t)i_factor*regelabweichung_summe)/2;      //Berechnung im Format S(24,7)
93
  
94
  //Bestimmung RUECKGABEWERT
95
  pi_regler_output=(p_anteil+i_anteil)/SCALING_FACTOR;      //Berechnung im Format S(31)
96
  
97
  
98
  if(pi_regler_output>255)
99
  {
100
    pi_regler_output=255;
101
  }
102
  
103
  
104
  if(pi_regler_output<0)
105
  {
106
    pi_regler_output=0;
107
  }
108
  
109
  return (uint8_t) pi_regler_output;
110
  
111
}
112
113
114
115
116
117
//Preload Value von 131 und Count von 50 soll eine Gesamtverzögerung von 100ms ergeben
118
void Timer0_init()
119
{
120
  //setzen des Preload Value
121
  TCNT0=PRELOAD_VALUE;
122
  
123
  //Prescaler 256
124
  TCCR0|=(1<<CS02);
125
  
126
  //Enable Timer Overflow Interrupt
127
  TIMSK|=(1<<TOIE0);
128
  
129
}
130
131
132
ISR(TIMER0_OVF0_vect)
133
{
134
  TCNT0=PRELOAD_VALUE;
135
  
136
  static uint8_t i=0;
137
  
138
  i++;
139
  
140
  if(i==TIME_INTERVAL)
141
  {
142
    regler_flag=1;
143
    i=0;
144
  }
145
}
146
147
148
int main(void)
149
{
150
  //########################################################################################################
151
  //Variablen definieren
152
  //########################################################################################################
153
154
  uint8_t ds18b20_scratchpad[2];
155
  
156
  int16_t temperatur_istwert;
157
  int16_t temperatur_sollwert;
158
  int16_t temperatur_regeldifferenz;
159
160
  
161
162
  //DS18B20 Werte für 9bit Auflösung ins Scratchpad schreiben
163
  ds18b20_config_9bit();
164
  
165
  
166
  //Statusled initalisieren
167
  statusled_init();
168
  
169
170
  //Debug Ausgabe initalisieren  
171
  debug_master_init();
172
  
173
174
  //Timer0 für Erzeugung Abtastzeit initalisieren
175
  Timer0_init();
176
  
177
178
  //Timer1 für PWM Ausgabe initalisieren
179
  Timer1_PWM_init();
180
  
181
182
  //Interrupts freigeben
183
  sei();
184
  
185
  
186
  
187
  
188
  while(1)
189
  {
190
    if(regler_flag)
191
    {
192
      regler_flag=0; //PI Regler Flag zurücksetzen
193
      
194
      
195
196
      //Start der Temperaturmessung und anschließendes auslesen
197
      ds18b20_convert_and_readout(ds18b20_scratchpad,2);
198
      
199
200
      //Temperatur-Sollwert in 16bit Variable schreiben im Formate S(11,4)
201
      temperatur_sollwert=(temperatur_sollwert_eingabe*16);
202
      
203
204
      //Temperatur-Istwert in 16bit Variable schreiben, Format S(11,4)
205
      temperatur_istwert=(ds18b20_scratchpad[1]<<8)+ds18b20_scratchpad[0];
206
      
207
208
      //Berechnung Regeldifferenz in 16bit Variable schreiben, Format S(11,4)
209
      temperatur_regeldifferenz=temperatur_sollwert-temperatur_istwert;
210
      
211
212
      //PI-Regler
213
      OCR1B=pi_regler(temperatur_regeldifferenz);
214
215
    
216
    }
217
  }
218
}

von mr. mo (Gast)


Lesenswert?

Meier schrieb:
> Bei einem KP von 1 (KI=0) kommt das ganze ins Schwingen. Könnte
> vielleicht der ein oder andere Reglungstechnik Profi hierzu was sagen?
> Bzw. mir einen Anhaltspunkt geben mit welchem KP ich Anfangs beginnen
> sollte?

Du hast ja immerhin schonmal eine ?Sprungantwort? von deinem Aufbau. Da 
gibt es zum Beispiel ein Tangentenverfahren um die einzelnen Parameter 
ermitteln zu können. Ausprobieren ist auch eine Möglichkeit. Auf der 
Roboternetz seite zum Thema Regelungstechnik wird dazu auch was erzählt, 
also wie man durch ausprobieren auf gute Werte für die einzelnen 
Parameter kommt.

http://www.rn-wissen.de/index.php/Regelungstechnik#Dimensionierung_des_Reglers

"Dimensionierung durch Probieren (Empirisches Einstellen)" ist genau das 
was du dir durchlesen solltest. Wo dein System eh schon ein wenig 
schwingt kannst auch mal schauen ob du auf ein brauchbares Ergebnis mit 
Hilfe von "Einstellung nach der Schwingungsmethode" kommst, wird dort 
ebenfalls recht gut erklärt.

von Morz Kerl (Gast)


Lesenswert?

Mit etwas Voraussicht oder Glueck hat der Controller eine verfuegbare 
serielle Schnittstelle, die auch einen Treiber furt RS232 ode so 
angeflanscht hat. Dann braucht man nur noch ein kleines Protokoll, das 
erlaubt die Parameter zur Laufzeit zu verstellen.
Ueber die gleiche Schnittstelle kann man sich dann auch Werte von 
interesse geben lassen. Alternativ kann man sich einen 4/8 fach DAC 
anflanschen und die Werte ueber den DAC ausgeben, zum mit dem Scope 
zuschauen.
Ohne so einen Ansatz wird's schwierig.

von Meier (Gast)


Lesenswert?

@ Morz Kerl

Hallo,

sowas ähnliches zumindest hab ich vorgesehen ;)

Die Werte oben sind direkt vom Controller ausgegeben worden (die in der 
angehängten Grafik). Die Regler Parameter ändere ich direkt über die ISP 
Schnittstelle.

Ich hab nur das Problem das mein System eigentlich bei jedem Wert von KP 
schwingt. Und ich weiss auch nicht so Recht wie ich jetzt weiter 
vorgehen soll... da ich eigentlich das Faustformelverfahren nutzen 
wollte :(

Desweitern wäre es mir zunächst einmal sehr wichtig ob mein 
PI-Controller Code so richtig realisiert ist insb. das mit dem Anti 
Windup..

von Uwe (Gast)


Lesenswert?

Hi,
>DS18B20 und
>#define TA          ((uint16_t)(0.1*SCALING_FACTOR))  //Abtastzeit 100ms
passt so garnicht weil fast 1 Sekunde vergeht ehe du einen neuen Wert 
hast.
Solange KI=0 ist sollte aber nichts falsches rauskommen. Das dein Regler
aber ohne KI schon schwingt ist nicht ok, er sollte sich eigentlich 
abhängig von KP etws unterhald des Sollwertes einregeln.
Dein Ganzer Code sieht irgendwie recht komisch aus, aber es ist schon 
recht spät und ich acker das jetzt nicht durch.

Viel Erfolg, Uwe

von Meier (Gast)


Lesenswert?

hi Uwe,

der DS18B20 ist auf 9bit konfiguriert und braucht zur messung daher max. 
93,75 ms...

Ich weiss echt wo das Problem liegen könnte, warum das ganz direkt 
anfängt zu schwingen... Von daher wäre ich echt sehr dankbar wenn noch 
jemand genauer drüber schauen könnte :(

Ratlos

von Karl H. (kbuchegg)


Lesenswert?

Das hier
1
  if(regelabweichung_summe<0)
2
  {
3
    regelabweichung_summe=0;
4
  }
5
  
6
  if(regelabweichung_summe>(255*2))          //Regelabweichung Summe im Format S(14,1)
7
  {
8
    regelabweichung_summe=(255*2);
9
  }

erscheint mir nicht logisch.
Warum soll die Summe der Regelabweichungen nicht auch negativ werden 
können? Dein I-Regler kann auf die Art niemals in die negative Richtung 
korrigieren, sondern muss warten, bis der P-Anteil unterschwingt, so 
dass die Summe wieder positiv wird und der I-Anteil den restlichen 
Fehler ausregeln kann.

von Karl H. (kbuchegg)


Lesenswert?

Deine willkürlichen *2, /2, /8  rufen bei mir da jetzt auch keine 
Begeisterungsstürme hervor.
1
    p_anteil=((int32_t)p_factor*regelabweichung)/2

Warum ist der Faktor '/2' nicht im p_faktor enthalten?

von fart (Gast)


Lesenswert?


von Meier (Gast)


Lesenswert?

Danke für den Hinweis!

War mir irgendwie garnicht aufgefallen!

Im Moment hänge ich an dem Problem das mein System eigentlich immer 
schwingt ca. minimal +1 / -2.5 °C bei einem KI=0...

Woran kann das liegen?

Regelstrecke besteht aus meinem kleinen Heizungselement das in einer 
Hülse steckt. Der Temperatursensor ist außen an der Hülse angebracht.

Btw.: Ist die Erzeugung meiner Abtastzeit TA korrekt?

von Morz Kerl (Gast)


Lesenswert?

WEnn's schwingt sind die Parameter noch zu hoch. Mach den I-Teil ganz 
weg. Dann den P Teil kleiner. Wenn's dann immer noch schwingt ist eine 
Verzoegerung drin. Dann nach Standard.

von Morz Kerl (Gast)


Lesenswert?

Ich wuerd auf eine Verzoegerung tippen.Das kann man nur mit einem ganz 
kleinen I Teil wegmachen. Allenfalls mit vorwaerts Steuerung. Indem man 
die Umwelt parameter mitmisst.

von Karl H. (kbuchegg)


Lesenswert?

Meier schrieb:
> Danke für den Hinweis!
>
> War mir irgendwie garnicht aufgefallen!
>
> Im Moment hänge ich an dem Problem das mein System eigentlich immer
> schwingt ca. minimal +1 / -2.5 °C bei einem KI=0...

lass dir halt mal die ganzen Werte ausgeben.
regelabweichung, p-Anteil, i-anteil, etc.

Wenn ein reiner P Regler schwingt (und sonst alles korrekt ist) dann ist 
das Kp zu groß.

> Regelstrecke besteht aus meinem kleinen Heizungselement das in einer
> Hülse steckt. Der Temperatursensor ist außen an der Hülse angebracht.

Also quälend langsame Regelstrecke.

von Meier (Gast)


Lesenswert?

@Karl Heinz Buchegger

Wie kann ich eine Festkommaarithmetik den am besten bzw. am 
geschicktesten implementieren? So das ich nicht so oft bzw. willkürlich 
dividieren muss??

Es ging einfach darum das ich mir gemerkt hatte zuerst zu multiplizieren 
und anschließend erst zu dividieren...

von kukuk (Gast)


Lesenswert?

warum 100ms...moechtest du Gluehdraht messen?
Temp_messungen sind traege Angelegenheiten !

Immer diese Eile !

von Meier (Gast)


Lesenswert?

Hab gerade glaubig schonmal einen Fehler gefunden...

Kann es sein das das OCR1C nicht standardmässig mit 0xff initalisiert 
wird? Hat das nämlich irgendwo hier mal gelesen...

Oder is das von AVR zu AVR nochmal unterschiedlich? Studiere mal jetzt 
mal das Datenblatt...


Gruß

von Meier (Gast)


Angehängte Dateien:

Lesenswert?

Hallo erneut,

also der primäre Fehler lag tatsächlich an dem nicht gesetzten TOP Wert 
der PWM.... :(

Hab das ganze jetzt erneut laufen mit einem KP von 25.0 aufgezeichnet. 
(Siehe Anhang).
Sieht das ganze jetzt normal aus für einen reinen P-Regler? (KP ist wohl 
schon ein wenig zu hoch denk, daher die leichte Schwingung)

Ich möchte jetzt die Regelparameter nach der Schwingungsmethode von 
Nichols Ziegler bestimmen. Muss die hierbei zu ermittelnde kritische 
Schwingung genau mit gleicher Amplitude (bzw. symmetrisch) um den 
Sollwert schwingen?
Bzw. wann weiß ich das das jetzt die kritische Schwingung ist? (wenn 
sich danach die Amplitude der Schwingung aufschaukelt??)

Kann mir noch einer die Frage beantworten wie groß ich die Größen des 
Anti Wind-up wählen soll?


Hier kam die Aussage auf das mein Quellcode komisch aussieht. Bitte ein 
bisschen konkreter und mögliche Verbesserungsmöglichkeiten.

Ich hab das mit dem I-Anteil im negativen Bereichen jetzt noch 
angepasst. Hier mein derzeitiger Stand vom PI-Regler.
1
uint8_t pi_regler(int16_t regelabweichung)
2
{
3
  int16_t p_factor,i_factor;
4
  
5
  int32_t p_anteil,i_anteil,pi_regler_output;
6
  
7
  static int16_t regelabweichung_summe=0;
8
  
9
  p_factor=KP;                      //Format S(8,7)
10
  i_factor=(((int32_t)KI)*TA)/SCALING_FACTOR;        //Format S(8,7)
11
  
12
  
13
  regelabweichung=regelabweichung/8;            //Umwandlung Format S(11,4) zu S(14,1), da Sensor sowieso nur einen Wert mit 0,5 Grad Auflösung liefert
14
  
15
  //Bestimmung P-ANTEIL
16
  p_anteil=((int32_t)p_factor*regelabweichung)/2;      //Berechnung im Format S(24,7)
17
  
18
  //Bestimmung I-ANTEIL
19
  regelabweichung_summe+=regelabweichung;          //Berechnung im Format S(14,1)
20
  
21
  
22
  //Begrenzung I-Anteil
23
  if(regelabweichung_summe<(-255*2))            //Regelabweichung Summe im Format S(14,1)
24
  {
25
    regelabweichung_summe=(-255*2);
26
  }
27
  
28
  if(regelabweichung_summe>(255*2))            //Regelabweichung Summe im Format S(14,1)
29
  {
30
    regelabweichung_summe=(255*2);
31
  }
32
  
33
  
34
  i_anteil=((int32_t)i_factor*regelabweichung_summe)/2;  //Berechnung im Format S(24,7)
35
  
36
  //Bestimmung RUECKGABEWERT
37
  pi_regler_output=(p_anteil+i_anteil)/SCALING_FACTOR;  //Berechnung im Format S(31)
38
  
39
  
40
  if(pi_regler_output>255)
41
  {
42
    pi_regler_output=255;
43
  }
44
  
45
  
46
  if(pi_regler_output<0)
47
  {
48
    pi_regler_output=0;
49
  }
50
  
51
  return (uint8_t) pi_regler_output;
52
}

Danke für eure Hilfe

von Karl H. (kbuchegg)


Lesenswert?

Meier schrieb:

> Ich möchte jetzt die Regelparameter nach der Schwingungsmethode von
> Nichols Ziegler bestimmen. Muss die hierbei zu ermittelnde kritische
> Schwingung genau mit gleicher Amplitude (bzw. symmetrisch) um den
> Sollwert schwingen?

Nein.
Denn ein reiner P-Regler erreicht den Sollwert nicht.
Erst mit einem kleine I-Anteil ist das dann der Fall.

> Kann mir noch einer die Frage beantworten wie groß ich die Größen des
> Anti Wind-up wählen soll?

Das sind alles Erfahrungswerte, die am jeweiligen Objekt bestimmt werden 
müssen.

> Hier kam die Aussage auf das mein Quellcode komisch aussieht. Bitte ein
> bisschen konkreter und mögliche Verbesserungsmöglichkeiten.

elends lange Variablennamen, wobei die Länge nichts zum Verständnis 
beiträgt. Dafür dann als Ausgleich keine Leerezeichen, die das Auge beim 
Lesen unterstützen würden einzelne Wörter zu erkennen. Dafür dann 
haufenweise sinnlose Kommentare.


Der Code sieht meiner Meinung nach extrem in die Länge gezogen aus. Der 
Anteil an unnützem White-Space ist übermässig hoch, ohne dass es was an 
der Übersicht bringt.


zb
>
>   //Bestimmung P-ANTEIL
>   p_anteil=((int32_t)p_factor*regelabweichung)/2;      //Berechnung im
> Format S(24,7)

No, na. Links vom = steht p_anteil. Wozu brauch ich da noch einen 
Kommentar "Bestimmung P-Anteil". Wenn da eine Zuweisung an die Variable 
p_anteil erfolgt, dann wird hier wohl nicht die aktuelle Temperatur 
gemessen werden.

Im Kommentar steht was vom "Format S(24,7)".
Nur leider ist im ganzen Programm kein einziger Hinweis darauf, was das 
überhaupt sein soll. Daher: Dieser Kommentar ist ein 0-Kommentar. Er 
erzählt mir nichts, was für das Verständnis relevant wäre.

1
uint8_t pi_regler(int16_t regelabweichung)
2
{
3
  int16_t p_factor,i_factor;
4
  
5
  int32_t p_anteil,i_anteil,pi_regler_output;
6
  
7
  static int16_t regelabweichung_summe=0;

Nach jeder Zeile eine Leerzeile einfügen bewirkt nur eines: Der Code 
wird in die Länge gezogen. Übersicht bringt das keine. Ganz im 
Gegenteil. Wenn ich beim Code-Lesen ständig hin und her scrollen muss, 
verliert man meist ständig den Faden.

von Karl H. (kbuchegg)


Lesenswert?

1
void Timer1_PWM_init()
2
{
3
  //Set OC1B as output;
4
  DDRB|=(1<<PB3);
5
  
6
  //Set COM1B1 and COM1B0 --> OC1B cleared on compare match and set when TCNT1=01; Set PWM1B --> Enable PWM B
7
  TCCR1A=(1<<COM1B1)|(1<<PWM1B);
8
  
9
  //Set Prescaler 8, ergibt 7812,5 Hz bei F_CPU=16 Mhz
10
  TCCR1B=(1<<CS12);
11
  
12
}

Du darfst ruhig davon ausgehen, dass dein Leser ein wenig AVR 
Programmieren kann. Das PB3 am Port B der OC1B Pin ist, das weiß man 
nicht unbedingt auswendig, ist schon richtig. Aber das das Bitsetzen im 
DDR Register den Pin auf Ausgang schaltet, das weiß wohl jeder. Wenn du 
dir am Anfang der Funktion die angestrebte Konfiguration zusammenfasst, 
dann macht das auch nicht so den Eindruck von Zersplitterung
1
void Timer1_PWM_init()
2
{
3
  // PWM mit 7.8Khz   (F_CPU: 16Mhz, Prescaler: 8)
4
  //   8 Bit PWM am B-Kanal (Pin OC1B  (PORTB, PB3))
5
  //   "Clear on match" und "Set on Top"
6
7
  DDRB |= (1<<PB3);
8
  TCCR1A = (1<<COM1B1) | (1<<PWM1B);
9
  TCCR1B = (1<<CS12);
10
}

von Meier (Gast)


Lesenswert?

Bzgl. der Schwingungsmethode von Nichols Ziegler:

Heisst das jetzt das ich solange KP erhöhe bis sich eine gleichförmige 
Schwingung ergibt? Unabhängig von deren Amplitude und die Lage um den 
Sollwert?

Gruß

von Meier (Gast)


Lesenswert?

Und nochmal zurückkommend auf das Format S(24,7):

Ich dachte eigentlich das die Angabe bei Festkommaarithmetik mit U(x,y) 
für eine unsigned integer mit x Vorkommabits, y Nachkommabits und analog 
für signed integer S(x,y) eine Art Konvention ist.

Dem ist wohl nicht so?! Gibt es eine andere gängigere Angabe diesbzgl.?

Gruß

von Ina (Gast)


Lesenswert?

Hat denn keiner eine Ahnung?! Stehe vor einem ähnlichen Problem und 
würde dieses gerne noch am Wochenende lösen. :)

von Purzel H. (hacky)


Lesenswert?

Ina... was ist das Problem? Natuerlich haben wir eine Ahnung. Aber die 
Poster sollen auch etwas lernen, etwas selbst debuggen. Die Technologien 
wurden erklaert.

wo liegt dein Problem, das so schnell geloes werden muss.

von Carsten (Gast)


Lesenswert?

Hallo,

das Anti-Windup sollt ja nur verhindern, dass deine Stellgröße ins 
unendliche wächst(Theorie). In der Praxis wird die Stellgröße durch die 
PWM begrenzt, ich glaube du hast da 8-bit. Dann sollte die Begrenzung 
bei max. Stellgröße 255 liegen. Für eine ausreichend gute Regelung kann 
man ruhig die volle Stellgröße fahren um den Idealfall den aperiodischen 
Grenzfall zu erreichen. Das ganze hat also nichts mit Erfahrungswerten 
zu tun. Z.B. kann ein Dead-Beat Regler in einen digitalen Regelschritt 
eine Temperaturstrecke ausregeln.

Um Faustformeln anwenden zu können musst du auf alle Fälle eine 
Sprungantwort auf die Stellgröße aufnehmen. Das kann so aussehen, dass 
du z.B. 100% Stellgröße auf den Heizstab gibst und die 
Temperaturerhöhung aufzeichnest. Das wird dann ein PT1 oder eher PT2 
Verhalten geben, da sollte aber nichts schwingen!

Wie sieht denn dein Regelalgorithmus aus?

Es sollte nach dieser Formel gerechnet werden

yk=yk-1 + kr (xdk - (1-t/tn) * xdk-1) wobei xdk der Istwer ist.

Das ist der Stellungalgorithmus, wobei yk der Stellwert ist.

von Meier (Gast)


Lesenswert?

Hallo Carsten,

vielen Dank für deine Antwort!

Mein derzeit genutzter genutzter Code steht oben im Post vom
Datum: 28.09.2012 15:09.

Als Alogorithmus benutzte ich da: y=e*KP+KI*TA*e_summe (D-Anteil hab ich 
keinen)

Bzgl. dem Anti Wind-up heisst das jetzt das ich die Begrenzung von 
e_summme so einstellen soll das der alleine I-Anteil noch einen 
Vollauschlag der Stellgröße herbeiführen kann in der Begrenzung?

Sprich maximal Wert PWM 255 --> e_summe_max= +/- 255/(TA*KI) ??

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.