Hallo Christian

Für echte Bildverarbeitung sind die AVRs nicht besonders gut geeignet. Ob das mit einem Mega128 mit externem Speicher und schnellerem ADC über I2C viel besser als mit meinem 8MHz-Mega32 funktioniert kann ich nicht sagen. Aber um eine Linie zu erkennen und ihr folgen zu können benötigt man auch keine 320X240 Bildpunkte mit 8-Bit Auflösung. Man muss auch nicht jedes Halbbild auswerten dass die Kamera liefert.

Der ADC hat laut Atmel-Spezifikation sowieso keine Chance das Bas-Bild einzulesen, aber wie ich in meinem Kamera-Thread gezeigt habe, wenn man ihn etwas "quält" kann er es schon. Um zu verstehen, wie das funktioniert solltest du dich etwas in den Aufbau des Signals einlesen. Im Wesentlichen sieht das so aus:

Jede Zeile startet mit einem Syncronimpuls dem die Bilddaten folgen. Jede Seite startet mit einem besonders langem Syncronimpuls. Schwarz wird mit ca. 0,3V dargestellt, weiss mit ca. 1V. Spannungen kleiner 0,3V bedeutet Syncronimpuls.

Um nun das Bild einzulesen muss man zuerst die Sycronimpulse erkennen. Dazu schaltet man den ADC auf superschnellen Dauerlauf mit linksbündigem Ergebniss von dem man nur das High-Byte (ADCH) einliest und auswertet. Bei meinem 8MHz-Mega32 hatte ich prescaler /2 verwendet, möglicherweise muss man bei 16MHz einen größeren Teiler wählen. Als Referenzspannung nimmt man die internen 2,56V (sofern vorhanden). Da nur die oberen 8 Bit ausgewertet werden erhält man einen Wertebereich von 0 bis 255 für 0V bis 2,56V. (Das der ADC mit der Wandlung nicht immer fertig ist wird im Folgenden missachtet!)

Den Start des Syncronimpulses erkennt man nun daran, dass der eingelesenen Wert deutlich unter 0,3V (also unter 30) ist, der optimale Wert ist etwas von der Hardware abhängig. Dann wartet man bis der Wert wieder über 0,3V ist und zählt dabei die Anzahl der ADC-Messungen im Dauerlauf. Das ergibt die Länge des Sync. Dann zählt man die Anzahl der Messungen bis zum nächsten Sycronimpuls, das ist die Zeilenlänge. Der Code dazu sieht etwa so aus:

syncdauer=0;
zeilendauer=0;
while(ADCH>30); // warten auf Anfang Syncimpuls
while(ADCH<30) syncdauer++; // Synclänge messen
while(ADCH>30) zeilendauer++; // Zeilenlänge messen

Anstelle der Zeilendauer kann man auch die Messwerte speichern:

uint8_t werte[255]; // ich schaffte 63 Werte
uint8_t *speicherzeiger;
speicherzeiger=&werte[0];
syncdauer=0;
while(ADCH>20); // warten auf Anfang Syncimpuls
while(ADCH<30) syncdauer++; // Synclänge messen
do *speicherzeiger=ADCH; while (*speicherzeiger++ > 20); // Werte einlesen

Das wäre der Einstieg. Anhand der Syncdauer kann man dann noch den Bildstart erkennen. Bei mir war das länger als 40:

do
{
syncdauer=0; while (ADCH > 20); while (ADCH < 30) syncdauer++;
} while (syncdauer < 40);

Zu Beginn jeder Seite kommen einige Zeilen Schrott die man überlesen sollte:

zeile=10; // 10 Zeilen überspringen
while(zeile--) { while(ADCH > 20); while(ADCH < 30); }

(20/30 ergibt eine kleine Hysterese um die Flanken besser zu erkennen)

So kann man nun jede beliebige Zeile einlesen, allerdings nur eine pro Halbbild und nur mit geringer x-Auflösung. Wie man diese x-Auflösung deutlich erhöhen kann beschreibe ich später mal auf Nachfrage (Man kann es auch im Kamera-Thread nachlesen).

Gruß

mic