Waste,

ich habe Deinen Code leicht modifiziert, da Dein Programm bei mir keiner Linie folgte.

Folgende Aenderungen habe ich vorgenommen:
1.) die Variablen drest, xsum und xalt in MAIN, da diese Variablen sonst nicht initialisiert werden
2.) Linedata mit LED off zur Initialisierung von doff in MAIN, da bei mir die LED beim Ein- und Ausschalten in FollowLine zu traege ist und scheinbar immer an bleibt.
3.) Implementierung mit Lib Ver. 2.70

Das war's. Nun folgt mein Asuro brav der Linie und der PID-Regler ist viel sensibler als der einfache P-Regelkreis!

Ich habe noch eine Frage:
Ich verstehe die Logik beim abbremsen nicht.

Links von der Linie (rechts bremsen)ist der Code:
speedRight = speed - y; // rechts abbremsen
Links dagegen
speedLeft = speed + y; // links abbremsen
Kannst Du mir das mal erklaeren. Besten Dank im voraus.

Hier ist der neue Code:
Code:
/*******************************************************************************
*
* Description: Asuro Linienverfolgung mit PID-Regler
* Version 1: Korrektur auf beide Motoren verteilt
* Author: Waste	26.8.05
*
* Version 2: initialization of parameters in Main, measurement with LED off in Main
* Author: irobot22587 11.03.2007
*
*****************************************************************************/
#include "c:/WinAVR/avr/include/asuro.h"			// ver 2.70

unsigned char speed;
int speedLeft,speedRight;
unsigned int lineData[2];
int x, xalt, don, doff, kp, kd, ki, yp, yd, yi, drest, y, y2, isum;

void FollowLine (void)
{
unsigned char leftDir = FWD, rightDir = FWD;
   LineData(lineData);                  // Messung mit LED ON
   don = (lineData[0] - lineData[1]);   
   x = don - doff;                  // Regelabweichung
   isum += x;
   if (isum > 16000) isum =16000;         //Begrenzung um Überlauf zu vermeiden
   if (isum < -16000) isum =-16000;
   yi = isum/625 * ki;               //I-Anteil berechnen
   yd = (x - xalt)*kd;               // D-Anteil berechnen und mit
   yd += drest;                     // nicht berücksichtigtem Rest addieren
   if (yd > 255) drest = yd - 255;      // merke Rest
   else if (yd < -255) drest = yd + 255;
   else drest = 0;
   if (isum > 15000) BackLED(OFF,ON);   // nur zur Diagnostik
   else if (isum < -15000) BackLED(ON,OFF);
   else BackLED(OFF,OFF);
   yp = x*kp;                        // P-Anteil berechnen
   y = yp + yi + yd;                  // Gesamtkorrektur
   y2 = y/2;                        // Aufteilung auf beide Motoren
   xalt = x;                        // x merken
   speedLeft = speedRight = speed;
   MotorDir(FWD,FWD);
   if ( y > 0) {                     // nach rechts
      StatusLED(GREEN);
      speedLeft = speed + y2;         // links beschleunigen
      if (speedLeft > 255) {
         speedLeft = 255;            // falls Begrenzung
         y2 = speedLeft - speed;      // dann Rest rechts berücksichtigen
      }
      y = y - y2;
      speedRight = speed - y;         // rechts abbremsen
      if (speedRight < 0) {
         speedRight = 0;
      }
   }
   if ( y < 0) {                     // nach links
      StatusLED(RED);
      speedRight = speed - y2;         // rechts beschleunigen !!!was speed - y2!!
      if (speedRight > 255) {
         speedRight = 255;            // falls Begrenzung
         y2 = speed - speedRight;      // dann Rest links berücksichtigen !!was speed - speedRight!!
      }
      y = y - y2;
      speedLeft = speed + y;            // links abbremsen  !! was speed + y!!!
      if (speedLeft < 0) {
         speedLeft = 0;
      }
   }
   leftDir = rightDir = FWD;
   if (speedLeft < 20)  leftDir = BREAK; // richtig bremsen
   if (speedRight < 20) rightDir = BREAK;
   MotorDir(leftDir,rightDir);
   MotorSpeed(abs(speedLeft),abs(speedRight));
}

int main(void)
{
unsigned char sw;
   Init();
   MotorDir(FWD,FWD);
   StatusLED(GREEN);
   speed = 150;
   kp = 3; ki = 10; kd = 70;      // Regler Parameter kd enthält bereits Division durch dt
   drest=0;
   isum=0;
   xalt=0;
   sw=0;
/*
   sw = PollSwitch();
   if (sw & 0x01)
      {ki=20;}
   if (sw & 0x02)
      {speed = 200;}
   if (sw & 0x04)
      speed = 100;
   if (sw & 0x08)
      kd = 35;
   if (sw & 0x10)
      kd = 70;
   if (sw & 0x20)
      kd = 140;
*/
   FrontLED(OFF);
   Msleep(50);
   LineData(lineData);                  // Messung mit LED OFF
   doff = (lineData[0] - lineData[1]);   // zur Kompensation des Umgebungslicht
   FrontLED(ON);
   Msleep(100);
   speedLeft = speed;
   speedRight = speed+25;
   while(1){
      FollowLine();
   }
    return 0;
}