Hallo
Aus dieser Grundfunktion ist bei mir dann das entstanden:
Bild hier
(Aus: ProBot mit asuro-Mega8)
Das Programm verwendet diese ACS(AntiCollisionSystem)-Funktion:
Code:
void ACSData(unsigned int *data)
{
UCSRB &= ~(1<<TXEN); // USART TX disable
OCR2=0xff;
DDRD |= (1<<PD1);
PORTD &= ~(1<<PD1); // ACS LED left on
while(PIND & 1)
{
acs=15;
while(acs);
OCR2--;
}
PORTD |= (1<<PD1); // ACS LED left off
data[0]=OCR2;
while(!(PIND &1));
OCR2=0xff;
PORTB &= ~(1<<PB0); // ACS LED right on
while(PIND & 1)
{
acs=15;
while(acs);
OCR2--;
}
PORTB |= (1<<PB0); // ACS LED right off 6
data[1]=OCR2;
while(!(PIND &1));
OCR2=0x91; //36kHz
}
Die Variable acs wird dabei in der 36kHz-ISR nach jeder Periode des Signals verkleinert:
volatile unsigned char count36kHz=0;
volatile unsigned char acs=0;
volatile unsigned long timebase=0;
/* uses timer2 (36kHz for IR communication */
SIGNAL (SIG_OVERFLOW2)
{
TCNT2 += 0x25;
count36kHz ++;
if (!count36kHz) timebase ++;
if(acs) acs--;
}
Der Probot hat auf jeder Seite drei IR-LEDs mit denen man die Abstände auf jeder Seite messen kann. Die rechten IR-LEDs hängen an PB0. Die eigentliche Messung findet hier statt:
Code:
OCR2=0xff;
...
while(PIND & 1)
{
acs=15;
while(acs);
OCR2--;
}
Beginnend mit OCR=255 (geringste Impulslänge) werden jeweils 15 Impulse im 36kHz-Takt gesendet und anschliesend der OCR2-Wert verringert. Das wird solange fortgesetzt wie der IR-Empfänger kein Trägersignal erkennt (sein Ausgang also high ist). Nach verlassen dieser Schleife ist der Wert in OCR2 ein Mass für den Abstand des reflektierenden Gegenstands. Das funktioniert hier ohne Timeout, weil ab einer gewissen Impulslänge immer irgendetwas im Raum erkannt wird.
Wichtig ist nun noch, dass man abwartet, bis der IR-Empfänger nach dem Abschalten der IR-LED keine "verirrten" IR-Signale mehr empfängt bevor man eine neue Messung startet:
while(!(PIND &1));
Mit der bee sieht das dann übrigends so aus:
https://www.roboternetz.de/phpBB2/ze...=480524#480524
Gruß
mic
Lesezeichen