Forum: Mikrocontroller und Digitale Elektronik PID Microcontroller in C - myavr board.Problem!!


von Gabriel 85 (Gast)


Lesenswert?

Hallo!

Ich habe mir letzens ein myavr Board geholt und muss damit nun einen PID 
Regler aufbauen. Ich kenne mich in C Sprache einigermaßen aus weswegen 
ich das auch direkt in C Programmieren wollte. Ich habe auch einige 
Beiträge in dem Forum gelesen und einige Quellcodes für einen PID Regler 
gefunden.

Da ich aber trotz allem ein ziemlicher Anfänger in Sachen µC bin, hat es 
natürlich nicht geklappt...leider finde ich den Fehler nicht. Die 
Ausgabe der PWM an meinem Port (PORTB2) gibt immer nur einen Maximalwert 
aus.

Ich habe ein myAVR Board MK2 mit USB Anschluss und verwende einen Atmel 
Mega8 Controller.

Hier mein Quellcode:
1
#define F_CPU 3686400
2
#include <avr\io.h>
3
4
5
uint16_t ReadChannel(uint8_t mux_adc_channel); 
6
7
unsigned int PID_Berechnung (signed int x, signed int w); 
8
9
int main(void)
10
{
11
        TCCR1A = (1<<WGM11) | (1<<WGM10) | (1<<COM1A1); // 10Bit-PWM-Modus (Auflösung=1024!)
12
                                //Nicht Invertierend
13
    TCCR1B = (1<<CS10); // Aktivieren mit Prescaler 1, also keine Frequenz-'Teilung'
14
     DDRB |= (1<<DDB1); 
15
  while(1){
16
17
      uint16_t adc_value;
18
      adc_value = ReadChannel(1);
19
    OCR1A = PID_Berechnung(adc_value, 22); 
20
    
21
  
22
23
   
24
25
    
26
}
27
return 0;
28
}
29
30
uint16_t ReadChannel(uint8_t mux_adc_channel) 
31
{
32
  uint8_t i;
33
  uint16_t result = 0;         
34
                               
35
  ADCSRA = (1<<ADEN) | (1<<ADPS2) | (1<<ADPS0);    // Frequenzvorteiler auf 32 setzen und ADC aktivieren 
36
 
37
  ADMUX = mux_adc_channel;                      
38
  ADMUX |= (1<<REFS1) | (1<<REFS0); 
39
 
40
  ADCSRA |= (1<<ADSC);                       
41
  while ( ADCSRA & (1<<ADSC) ) {
42
     ;     
43
  }
44
 
45
 
46
  for(i=0;i<4;i++)
47
  {
48
    ADCSRA |= (1<<ADSC);            
49
    while ( ADCSRA & (1<<ADSC) ) {
50
      ;         }
51
    result += ADCW;            
52
  }
53
  ADCSRA &= ~(1<<ADEN);            
54
 
55
  result /= 4;                      
56
  return result;
57
}
58
59
60
unsigned int PID_Berechnung (signed int x, signed int w)
61
{
62
63
double Kp;
64
double I;
65
double Ta;
66
double D;
67
unsigned int prop;
68
unsigned int integ;
69
unsigned int diff;
70
unsigned int ealt;
71
unsigned int esum;
72
unsigned int e;
73
unsigned int y;
74
75
Kp = 0.3;
76
I = 0.1;
77
D= 0.05;
78
Ta = 0.3;
79
   
80
e = w - x;                  
81
if ((integ <= 1023)&&(integ >= 0))
82
  {
83
    esum+=e;          }
84
85
prop = (Kp*e);   // Proportional Faktor
86
integ = (I*Ta*esum); // Integraler Anteil
87
diff = (D*((e-ealt))/Ta);   // Differenzieller Anteil
88
ealt = e;                   // Regelabweichung für nächste Abtastung merken
89
y = prop + integ + diff;    // Ausgangsstellgröße
90
91
if (y > 1023)               // Stellgröße auf 0..1023 begrenzen(10 bitPWM)
92
  {
93
    y = 1023;
94
  }
95
    if (y < 1)
96
  {
97
    y = 0;
98
  }
99
return y;              // unsigned int weil y nur zwischen 0 und 1023
100
}

Für Hilfe danke ich im Voraus! Im myAVR Forum hat mir bislang keiner 
Helfen können...

von Martin Schneider (Gast)


Lesenswert?

Was hast du denn alles schon versucht?

Ohne jetzt intensiv die Quellen durchsucht zu haben:

Was passiert denn, wenn du den gemessenen ADC-Wert direkt auf die 
PWM-Ausgabe schreibst (statt PID-Berechnung)?

Wie hast du die PID-Verstärkungen ermittelt? Ich vermute da zumindest 
Probleme, da in deinem Programm kaum von aquidistanter Abtastung die 
Rede sein kann, der Reglertakt ist ja rein durch Laufzeiten bestimmt.

Ahoi, Martin

von Michael K. (mmike)


Lesenswert?

Hallo,

unsigned int e;

Deine Regeldifferenz kann nie negativ werden ...

Zudem könnte ein "Anti-Wind-Up" für den Integrator nicht schaden ...

Grüße,
Michael

von Gabriel 85 (Gast)


Lesenswert?

Hallo!

Also die PWM klappt wunderbar, ich habe es gerade ausprobiert. Die Werte 
die ich mit einem Poti einstelle werden auch am Ausgang ausgegeben. Also 
es liegt vermutlich am Regler oder an seiner implementierung....oder 
irgenwo ein kleinerer Fehler....

von Gabriel 85 (Gast)


Lesenswert?

PS: Danke schon mal für die schnellen Antworten :-)

beste Grüße,
GABRIEL

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.