www.mikrocontroller.net

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


Autor: Gabriel 85 (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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:
#define F_CPU 3686400
#include <avr\io.h>


uint16_t ReadChannel(uint8_t mux_adc_channel); 

unsigned int PID_Berechnung (signed int x, signed int w); 

int main(void)
{
        TCCR1A = (1<<WGM11) | (1<<WGM10) | (1<<COM1A1); // 10Bit-PWM-Modus (Auflösung=1024!)
                                //Nicht Invertierend
    TCCR1B = (1<<CS10); // Aktivieren mit Prescaler 1, also keine Frequenz-'Teilung'
     DDRB |= (1<<DDB1); 
  while(1){

      uint16_t adc_value;
      adc_value = ReadChannel(1);
    OCR1A = PID_Berechnung(adc_value, 22); 
    
  

   

    
}
return 0;
}

uint16_t ReadChannel(uint8_t mux_adc_channel) 
{
  uint8_t i;
  uint16_t result = 0;         
                               
  ADCSRA = (1<<ADEN) | (1<<ADPS2) | (1<<ADPS0);    // Frequenzvorteiler auf 32 setzen und ADC aktivieren 
 
  ADMUX = mux_adc_channel;                      
  ADMUX |= (1<<REFS1) | (1<<REFS0); 
 
  ADCSRA |= (1<<ADSC);                       
  while ( ADCSRA & (1<<ADSC) ) {
     ;     
  }
 
 
  for(i=0;i<4;i++)
  {
    ADCSRA |= (1<<ADSC);            
    while ( ADCSRA & (1<<ADSC) ) {
      ;         }
    result += ADCW;            
  }
  ADCSRA &= ~(1<<ADEN);            
 
  result /= 4;                      
  return result;
}


unsigned int PID_Berechnung (signed int x, signed int w)
{

double Kp;
double I;
double Ta;
double D;
unsigned int prop;
unsigned int integ;
unsigned int diff;
unsigned int ealt;
unsigned int esum;
unsigned int e;
unsigned int y;

Kp = 0.3;
I = 0.1;
D= 0.05;
Ta = 0.3;
   
e = w - x;                  
if ((integ <= 1023)&&(integ >= 0))
  {
    esum+=e;          }

prop = (Kp*e);   // Proportional Faktor
integ = (I*Ta*esum); // Integraler Anteil
diff = (D*((e-ealt))/Ta);   // Differenzieller Anteil
ealt = e;                   // Regelabweichung für nächste Abtastung merken
y = prop + integ + diff;    // Ausgangsstellgröße

if (y > 1023)               // Stellgröße auf 0..1023 begrenzen(10 bitPWM)
  {
    y = 1023;
  }
    if (y < 1)
  {
    y = 0;
  }
return y;              // unsigned int weil y nur zwischen 0 und 1023
}


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

Autor: Martin Schneider (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Michael K. (mmike)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Gabriel 85 (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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....

Autor: Gabriel 85 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
PS: Danke schon mal für die schnellen Antworten :-)

beste Grüße,
GABRIEL

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.