Code:
	#include "RP6RobotBaseLib.h"
#define mpower 50
#define spur 145
// Achtung! Die PWM-Werte werden hier OHNE Rampe verändert!
void setMotorPWM(uint8_t power_links, uint8_t power_rechts)
{
extern uint8_t mleft_ptmp, mright_ptmp;
	if(power_links > 210) power_links = 210;
	if(power_rechts > 210) power_rechts = 210;
	mleft_power=mleft_ptmp=power_links;
	mright_power=mright_ptmp=power_rechts;
	OCR1BL = power_links;
	OCR1AL = power_rechts;
	if(power_links || power_rechts)
		TCCR1A = (1 << WGM11) | (1 << COM1A1) | (1 << COM1B1);
	else
		TCCR1A = 0;
}
void get_lines(uint16_t delay, uint8_t zeilen)
{
	uint8_t pixel[256],*pixelzeiger;
	uint8_t i, step, lines, h_step, h_sync, h_delay;
	uint16_t gamma[16],g_hell, g_dunkel, g_sprung;
	uint16_t strich_links, strich_rechts, strich_mitte, strich_breite;
	step=(260-35)/zeilen; // 30-260 sind die sichtbare Zeilen
	lines=zeilen;   // Anzahl der einzulesenden Zeilen
	pixelzeiger=&pixel[0]; // Zeiger auf Start Pixelspeicher
	cli();
	do // vsync abwarten
	{
		h_sync=0; while (ADCH > 20); while (ADCH < 30) h_sync++;
	} while (h_sync < 40);
	h_step=35;
	while (h_step) // 30 Zeilen Austastzeit überlesen
	{
		while (ADCH > 20); while (ADCH < 30); h_step--;
	}
 	while (lines--)
	{
		h_step=step;
		while (h_step) // auf die nächste gültige Zeile warten
		{
			while (ADCH > 20); while (ADCH < 30); h_step--;
		}
		h_delay=delay;
		while (h_delay--); // auf richtiges Pixel warten
		*pixelzeiger=ADCH; // letzten ADC-Wert auslesen und wegwerfen
		*pixelzeiger++=ADCH;  // aktuellsten ADC-Werte speichern
	}
	sei();
	//*pixelzeiger=0; // Endekennung der Daten
	for (i=0; i<16; gamma[i++]=0); // 16 gammawerte zählen
	pixelzeiger=&pixel[0];
	for (lines=0; lines < zeilen; lines++) gamma[*pixelzeiger++ >> 4]++;
	g_sprung=5;
	g_dunkel=0;
 	for (i=1; i<16; i++)
	{
	   if (gamma[i] > gamma[i-1])
			if ((gamma[i] - gamma[i-1]) > g_sprung)
				if (!g_dunkel) g_dunkel=i;
	}
	g_hell=0;
 	for (i=14; i; i--)
	{
	   if (gamma[i] > gamma[i+1])
			if ((gamma[i] - gamma[i+1]) > g_sprung)
				if (!g_hell) g_hell=i;
	}
/*
	for (i=0; i<16; i++)
	{
		if (i) writeString_P("-");
		writeInteger(gamma[i],DEC);
	}
	writeString_P("\n\r");
	writeInteger(g_dunkel, DEC);
	writeString_P("-");
	writeInteger(g_hell, DEC);
	writeString_P("\n\r");
*/
	strich_links=0;
	strich_rechts=0;
	for (i=0; i<zeilen; i++)
	{
		if ((pixel[i] >> 4) == g_dunkel) writeString_P("*");
			else writeString_P(" ");
		if (((pixel[i] >> 4) == g_dunkel) && ((g_hell-g_dunkel)>1))
		{
			if (!strich_links) strich_links=i;
				else strich_rechts=i;
		}
	}
	strich_mitte=(strich_links+strich_rechts)/2;
	strich_breite=strich_rechts-strich_links;
	writeString_P(" | ");
	writeInteger(strich_links, DEC);
	writeString_P("-");
	writeInteger(strich_rechts, DEC);
	writeString_P("-");
	writeInteger(strich_mitte, DEC);
	writeString_P("\n\r");
}
int main(void)
{
//	uint16_t strich_links, strich_rechts, strich_mitte, strich_breite;
//	uint8_t pow_l,pow_r;
	initRobotBase();
	extIntOFF(); // schaltet den E_INT1-Port auf Eingang für den ADC
	//powerON();
// ADC interne Referenz 2,56V, Ergebniss linksbündig, Kanal ADC4 (E_INT1)
	ADMUX = (1<<REFS1) | (1<<REFS0)  | (1<<ADLAR) | 4;
// setzte free running triggern
	SFIOR = (0<<ADTS2) | (0<<ADTS1) | (0<<ADTS0);
// kein interupt, Wandler einschalten, prescaller /2
	ADCSRA = (0<<ADIE) | (1<<ADEN) | (0<<ADPS2) | (0<<ADPS1)  | (1<<ADPS0);
// Autotriggern bedeutet jetzt free running aktivieren, altes Flag löschen
	ADCSRA |= (1<<ADATE) | (1<<ADIF);
// Initialisierung starten
	ADCSRA |= (1<<ADSC);
// und noch die wohl eher unnötige Initiallesung
	while (!(ADCSRA & (1<<ADIF)));
	ADCSRA |= (1<<ADIF);
while (1){
	get_lines(50,48);
	mSleep(50);
}
/*
	setMotorDir(BWD,BWD);
	pow_l=pow_r=mpower;
	setMotorPWM(pow_l/2,pow_r/2);
	mSleep(mpower);
	setMotorPWM(pow_l,pow_r);
	do
	{
	   strich_links=strich_rechts=0;
		zeile=30;
		do
		{
		   if (!strich_links && (get_line(zeile)<gamma))
			{
				strich_links=zeile;
				zeile+=5;
			}
		   if (strich_links && (get_line(zeile)>gamma)) strich_rechts=zeile;
			zeile+=10;
		} while ((zeile<260) && !strich_rechts);
		if (!strich_rechts) strich_rechts=260;
		strich_mitte=(strich_links+strich_rechts)/2;
		strich_breite=strich_rechts-strich_links;
		if ((strich_links < spur) && (strich_rechts > spur))
			pow_l=pow_r=mpower;
		else
		{
			if (strich_links > spur) {pow_l=pow_l/2; pow_r=mpower;}
			if (strich_rechts < spur) {pow_l=mpower; pow_r=pow_r/2;}
		}
		setMotorPWM(pow_l,pow_r);
		//writeInteger(spur,DEC);
		//writeString_P(" - ");
		writeInteger(strich_mitte,DEC);
		writeString_P(" - ");
		writeInteger(strich_breite,DEC);
		writeString_P("\n\r");
 		//mSleep(100);
	} while (strich_breite < 100);
	//setMotorDir(FWD,FWD);
	setMotorPWM(pow_l/2,pow_r/2);
	mSleep(mpower);
	setMotorPWM(0,0);
	//mSleep(500);
*/
	while (1);
	return(0);
}
 Der Funktion get_line() wird der Wert für den h_delay und die Anzahl der gewünschten Pixel/Spalte übergeben (das Pixelfeld hat 256 Elemente, ich lese aber nur 48 Pixel ein).
Lesezeichen