Hallo
Willkommen im RN-Forum. Eine hübsche Nuss gibst du uns hier in deinem ersten Beitrag zum Knacken. Ich kann deine Fragen nur "theoretisch" beantworten, weil ich das Ultraschall-Modul nicht besitzen. Aber ich kann mal den Anfang machen:
TCCR2 = _BV(WGM21) | _BV(CS20); // Timer 2 im CTC-Mode, Takt ohne Prescaler, Normal port operation, OC2 disconnected? (siehe Edit)
TIMSK &= ~_BV(TOIE2); // Overflow-Interrupt aus
TIMSK |= _BV(OCIE2); // Compare-Interrupt einschalten
Durch das "=" in "TCCR2 =" wird das alte Setup von TCCR2 überschrieben. count36kHz wird in der neuen CTC-ISR hochgezählt, die Zeitbasis für sleep() ist nun aber 80kHz und nicht 36kHz. Wie genau die 40kHz an den OC2 kommen kann ich im Moment noch nicht sagen. Der Pin sollte bei 80kHz (8MHz/100) wohl getoggelt werden (COM 21:20 = 0:1), im TCCR2 wird OC2 aber auf "nicht verbunden" gesetzt (COM 21:20 = 0:0). Das sollten wir wohl noch klären...
count36kHz = 0;
while(count36kHz != 20) {
OCR2 = 100 + 20 / 2 - count36kHz;
}
Das erzeugt 10 Impulse mit ansteigender Frequenz von OCR2=110 bis OCR2=90. Das erscheint mir im Moment noch etwas fragwürdig, vielleicht klärt sich das im Verlaufe dieses Threads.
Nun zur Auswertung. Der ADC wird ausgeschaltet, der AC wird aktiviert. ACME in ADCSRB wird gesetzt, deshalb wird nicht mit AIN1 sondern mit PC3 (ADMUX=3, vermutlich Eingang vom Ultraschall anstelle von Liniensensor T9) verglichen. Vergleichspin AIN0 ist der Pin der LineLED PD6, der wird im Setup auf Eingang gesetzt, möglicherweise ist der aber vom Ultraschallmodul mit einer Referenzspannung versorgt:
ADCSRA = 0; // deactivate ADC
ACSR |= _BV(ACIS1); // Comparator Interrupt on Falling Output Edge
ADMUX = 0x03; // connect ADC3-input with comparator
SFIOR |= _BV(ACME); // connect ADC multiplexer to comparator
DDRD &= ~_BV(6); // use Port D Pin 6 as input (AIN0)
Nach dem Senden des Ultraschall-Signals wartet der asuro auf ein Echo. Gemessen wird die Laufzeit des Signals, erkennbar am gesetzten ACI-Bit in ACSR mit if((ACSR & _BV(ACI))). Und hier kommen wir dann auch zur ominösen Formel:
dist = (unsigned int) ((long) ((344L * ((sleeptime * 1000L) / 72L) / 10000L) / 2L));
344 soll wohl die Schallgeschwindigkeit in Luft sein, 72 ist möglicherweise ein Überrest der 72kHz Urlibrary. Der Rest ist wohl das Ergebniss einiger Versuche. Da sleeptime in der while(TRUE)-Schleife völlig unabhängig von irgendwelchen Timer-Ticks erhöht wird, kann man die Einheit pro Sekunde wohl nur mit dem Asemblerlisting des kompilierten Programms erahnen. Aber nur so kann die Laufzeit mit möglichst hoher Auflösung gemessen werden.
Das count36kHz deutet darauf hin, dass zumindest eine neuere Version der Library (so ab V2.3 ca.) verwendet werden sollte. Meine Ausführungen beziehen sich auf den Mega8 und sind ohne Gewähr, denn ich habe keine praktische Erfahrungen mit dem Ultraschall-Modul.
Gruß
mic
Edit: OC2 ist wohl gar nicht verbunden, das TCCR2 wird ja im Setup für das Ultraschall mit COM21:20 = 0:0 geladen! Seltsam..
Edit2: Ich bin echt aus der Übung:
Sleep(1);
sleeptime++;
So wird sleeptime mit dem Timer syncronisiert. Dann gibt die Formel vielleicht auch Sinn. Die 72 sollte dann wohl 80 sein, /2 kommt noch dazu, weil es sonst nicht passt...
Lesezeichen