Hallo m.a.r.v.i.n,

Danke für die netten Worte und vor allem für das Testen. In der Zwischenzeit habe ich ein paar kleinere Änderungen vorgenommen, die Du vielleicht auch gleich mittesten kannst:

1.) Eine kleine kosmetische Änderung, die eine Zeile code spart.

Code:
...
// --- find next active channel ---
if (ADC_CHANNELS) // at least one channel must be set
{
   do
   {
     if (++ADC_CHANNEL > 5) ADC_CHANNEL = 0;
   } while (!(ADC_CHANNELS & (1<<ADC_CHANNEL)));
   ...
2.) Ich glaube es ist eine bessere Idee, die ENCODER[] rückwärts zählen zu lassen. Dann kann man bei Erreichen der Null den zugehörigen Motor stoppen. Damit das nun wieder geht, muss man die Richtungen für die Motoren in globale Variablen schreiben.
Das Ganze sieht dann so aus:
Code:
...
volatile unsigned char STOP_ON_ENCODER  = FALSE;          //if this is TRUE and ENCODER[] hits zero the corresponding motor will be stoped
volatile long          ENCODER[2]       = {0,0};          //Ticks for right [0] and left [1] wheel (They will be decreased)
...
volatile unsigned char DIRECTION_LEFT   = BRAKE;					//Use this together with STOP_ON_ENCODER in order to stop the left motor if ENCODER reaches null
volatile unsigned char DIRECTION_RIGHT  = BRAKE;					//Use this together with STOP_ON_ENCODER in order to stop the right motor if ENCODER reaches null


ISR(SIG_ADC)
{	
    ...
    if (ADC_DATA[ADC_CHANNEL] < dval)
    {
       if (last_odo_segment[ADC_CHANNEL] == WHITE)
       {
          ENCODER[ADC_CHANNEL]--;
          last_odo_segment[ADC_CHANNEL] = BLACK;
          NEW_ENCODER_DATA |= (1 << ADC_CHANNEL);
        }
        if (last_odo_segment[ADC_CHANNEL] == UNKNOWN)
        {
           last_odo_segment[ADC_CHANNEL] = BLACK;
        }
    }
    
    // --- bright light ---
    if (ADC_DATA[ADC_CHANNEL] > lval)
    {
       if (last_odo_segment[ADC_CHANNEL] == BLACK)
       {
          ENCODER[ADC_CHANNEL]--;
          last_odo_segment[ADC_CHANNEL] = WHITE;
          NEW_ENCODER_DATA |= (1 << ADC_CHANNEL);
        }
        if (last_odo_segment[ADC_CHANNEL] == UNKNOWN)
        {
           last_odo_segment[ADC_CHANNEL] = WHITE;
        }
    }
    
    // --- stop motor if ENCODER reaches null ---
    if (!ENCODER[ADC_CHANNEL] && STOP_ON_ENCODER)
    {
       if (ADC_CHANNEL == RIGHT) MotorDir(DIRECTION_LEFT, BRAKE);
       if (ADC_CHANNEL == LEFT)  MotorDir(BRAKE, DIRECTION_RIGHT);
    }
}
...
Natürlich muss man dann am Anfang die Encoder auf die Werte setzten, die der Strecke entsprechen, die die Motoren bewegt werden sollen.
Ich halte diese Änderungen für notwendig, da man sonst gegenüber dem Pollingbetrieb keine Verbesserung erreicht.

Gruß,

_HP_