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