Hi,
mit diesem Code habe ich bis jetzt das beste Ergebnis erzielen können:
Code:
// nibobee IR-LEDs an PA0 und PA1 im Wechsel mit 36kHz ansteuern
// https://www.roboternetz.de/phpBB2/ze...=479870#479870
// Die Anoden der rechten IR-LEDs hängen mit Vorwiderstand an PA0 (X1-AN0)
// Die Anoden der linken IR-LEDs hängen mit Vorwiderstand an PA1 (X1-AN1)
// Die Kathoden beider IR-LEDs sind mit PA3 (X3-AN3) verbunden
// Der Empfänger SFH5110 ist mit PA2 (X2-AN2) verbunden
#include <nibobee/iodefs.h>
#include <nibobee/led.h>
#include <nibobee/sens.h>
#include <nibobee/i2cmaster.h>
#include <nibobee/lcdi2c.h>
volatile uint8_t count36kHz;
volatile uint8_t acs=0;
void Sleep(uint8_t pause);
void Msleep(uint16_t pause);
void ACSData(uint16_t *data)
{
OCR2=253;
PORTA |= (1<<PA1); // ACS LED left on
while((PINA & (1<<PA2)) && (OCR2 > 151))
{
acs=6; //6 Impulse senden, acs wird in OVF-ISR runtergezählt
while(acs);
OCR2--;
}
PORTA &= ~(1<<PA1); // ACS LED left off
data[0]=OCR2;
while(!(PINA & (1<<PA2))); // warten bis keine Echo mehr
OCR2=253;
PORTA|= (1<<PA0); // ACS LED right on
while((PINA & (1<<PA2)) && (OCR2 > 151))
{
acs=6;
while(acs);
OCR2--;
}
PORTA &= ~(1<<PA0); // ACS LED right off 6
data[1]=OCR2;
while(!(PINA & (1<<PA2)));
}
int main(void)
{
uint16_t data[2]; // Speicher für ACS-Werte
led_init();
sens_init();
i2c_init();
lcd_init(0x27);
lcd_setBacklight(0);
printf("Pinsel's NIBObee");
// Setup Timer2
TCCR2 = (1 << WGM20)|(1 << CS20); // PhaseCorrect-PWM, no prescaling, no OC2-Pin!
TCNT2 = 96; // (512-416) 36kHz @15MHz
OCR2 = 151; // (255-(208/2)) 151 ist 50:50 Compare Match für symetrische Halbwellen
TIMSK |= (1 << OCIE2)|(1 << TOIE2); // Comp und OVF-ISR enable, Overflow bei Bottum!
enable_interrupts();
led_set(0,1);
Msleep(2000); // wait4programmer
DDRA |= (1<<PA3)|(1<<PA1)|(1<<PA0);
PORTA &= ~((1<<PA3)|(1<<PA1)|(1<<PA0));
//DDRB |= (1<<PB4); // Test mit LineLEDs
//PORTB &= ~(1<<PB4);
// while(!sens_getLeft() & !sens_getRight()) // solange keine Taste gedrückt wird
// {Msleep(200); PORTB ^= (1<<PB0);} // hektisches Blinken mit LED0
while(1)
{
ACSData(data);
PORTB &= ~15; // alle Leds aus
if(data[0] > 251) led_set(1,1);
else if(data[0] > 230) led_set(0,1);
lcd_setCursor(0,1);
printf("Links: %4d", data[0]);
if(data[1] > 251) led_set(2,1);
else if(data[1] > 230) led_set(3,1);
lcd_setCursor(0,2);
printf("Rechts: %4d", data[1]);
Msleep(500);
}
return(0);
}
ISR (TIMER2_COMP_vect)
{
PORTA ^= (1<<PA3); // IR-LEDs togglen
}
// Frequenzkorrektur 512-416 plus 3 Takte fürs Laden von TCNT2?
ISR (TIMER2_OVF_vect)
{
TCNT2 = 99;
if(count36kHz) count36kHz--;
if(acs) acs--;
}
void Sleep(uint8_t pause) // 1/36000 Pause blockierend
{
count36kHz=pause;
while(count36kHz);
}
void Msleep(uint16_t pause) // 1/1000 Pause blockierend
{
while(pause--) Sleep(36);
}
Du hast recht, ich musste ebenfalls die Impulse auf 6 reduziert um den besten Kompromiss zu erhalten. Die Schrumpschläuche habe ich ebenfalls um 1 cm verlängert, um nicht zu viele Störungen zu empfangen. Weiters musste ich die Bee vorne höher legen um die Reflexionen des Fussbodens zu reduzieren. Die Empfindlichkeit ist immer noch sehr hoch, besonders die Differenz der Werte links und rechts beträgt bei mir etwa 20 Einheiten.
Aber im Grossen und Ganzen bin ich sehr zufrieden mit dem Ergebnis, ich werde versuchen ein Programm zu schreiben bei dem sich die Bee autonom im Raum bewegt.
Nochmals vielen Dank für deine Unterstützung, vielleicht hast du noch Lust die Geschichte in Bascom zu übersetzen?
To be continued...
Lesezeichen