PID Microcontroller in C - myavr board.Problem!!

Gast #1026453
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...
Gast #1026541
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
Gast #1026573
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....

Antwort schreiben

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.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.