Moinmoin,

Ich habe mir letzte Woche den Ultraschallaufsatz für den Asuro nach der Anleitung von Lutz Mager gebaut (das geht übrigens auch ganz gut ohne die offizelle Erweiterungsplatine).
Als ich mit der Hardware fertig war, wollte ich das natürlich gerne testen, und das Beispielprogramm hat direkt mal versagt. Grade zum Kalbibrieren des Potis ist es in der Urform reichlich ungeeignet. Also dachte ich mir: geb ich mir die Entfernungsdaten doch einfach per Infrarot aus. Gesagt getan - intToString und SerWrite reingekloppt und gestartet und... nix! Nach längerem Rumprobieren ist mir irgendwann mal aufgefallen, das für den Ultraschallsensor der interne Takt verstellt wird, und zwar direkt in der Init-Methode sowie bei jedem Ping.

Ich habe das jetzt so umgebaut, dass Ultraschall und IR gleichzeitig funktionieren ohne sich in die Quere zu kommen.

Code:
void localInit(void)
{
	// Change Oscillator-frequency of Timer 2
	// to 40kHz, no toggling of IO-pin:
	// bad@init: TCCR2 = (1 << WGM21) | (1 << CS20);
	// bad@init: OCR2 = 0x64;						// 40kHz @8MHz crystal
	

	ADCSRA = 0x00;						// ADC off
	// Analog comparator:
	ACSR = 0x02;						// Generate interrupt on falling edge
	ADMUX = 0x03;						// Multiplexer for comparator to
										// ADC pin 3
	SFIOR |= (1 << ACME);				// Enable muliplexing of comparator
	DDRD &= ~(1 << 6);					// Port D Pin 6 is input!
}


unsigned int ping(unsigned char length)
{
	unsigned int posmarker = 0;
	int pos;
	
	OCR2 = 0x64;										// 40kHz @8MHz crystal
	count72kHz = 0;
	TCCR2 = (1 << WGM21) | (1 << COM20) | (1 << CS20);	// Toggling of IO-Pin on
													
	
	// generate the Chirp
	while(count72kHz < length) {
		OCR2 = 0x64 + length / 2 - count72kHz;
	}
	
	//TCCR2 = (1 << WGM21) | (1 << CS20);				// Toggling of IO-Pin off
	TCCR2 = (1 << WGM21) | (1 << COM20) | (1 << CS20);	// This seems to work better
	
	OCR2 = 0x64;										// set frequency to 40kHz
	
	for(pos = 0; pos < 100; pos++) {
		Sleep(10);
		if((ACSR & (1 << ACI)) != 0) {
			if(posmarker == 0) { posmarker = pos; }
		}
		ACSR |= (1 << ACI);
	}
	OCR2  = 0x6E;										// reset crystal to 36kHz @8MHz
	
	return posmarker;
}
Einige der original Einstellungen sind noch als Kommentare vorhanden.

localInit() ruft man einmalig auf, ping(20) gibt einen Wert äquivalent zur Entfernung zum nächsten Hinderniss aus (hoffentlich) bzw 0 wenn keines erkannt worden ist. Ein Wert von 4-5 entspricht ca. 10 cm.

Da ich mit den Registern des Atmel nicht so vertraut bin, hoffe ich, dass das alles noch standardkomform ist!

Ich erreiche mit dem Ultraschall unter guten Bedingungen (Hinderniss groß und orthogonal zum asuro) eine Reichweite von ca. 2m.

Ich hoffe, ich kann ein paar Leuten mit dem Code Zeit und graue Haare ersparen!

Anmerkung: Mir ist aufgefallen, dass im Beispielcode nur auf eine Entfernung >12 überprüft wird, 0 aber nicht. Ist das nur bei mir so, dass der Wert 0 auftritt oder haben die das einfach vergessen?

Edit:
Ich sehe grade, dass "TCCR2 = (1 << WGM21) | (1 << COM20) | (1 << CS20);" in der ping-Methode doppelt steht. Das zweite kann man wahrscheinlich dann weglassen