TEL12AT
18.04.2015, 17:20
Hey Leute,
ich bin gerade dabei das Ultraschallmodul von ARX auszutesten. Das ganze funktioniert aber noch nicht.
Hat jemand schon einmal den Bausatz erfolgreich verwendet mit den bereitgestellten Funktionen aus der Asuro-Bib?
Ich habe nämlich die Vermutung, dass das ultrasonic-Modul noch nicht ganz ausgereift ist.
void InitUltrasonics(void)
{
// Change Oscillator-frequency of Timer 2
// to 40kHz, no toggling of IO-pin:
cli();
#if defined(__AVR_ATmega168__)
// fast PWM, set OC2A on compare match, clear OC2A at bottom, clk/1
TCCR2A = _BV(WGM21);
TCCR2B = _BV(CS20);
// interrupt on timer overflow
TIMSK2 &= ~_BV(TOIE2);
TIMSK2 |= _BV(OCIE2A);
#else
TCCR2 = _BV(WGM21) | _BV(CS20);
TIMSK &= ~_BV(TOIE2);
TIMSK |= _BV(OCIE2); // OCIE2: Timer/Counter2 Output Compare Match Interrupt Enable
#endif
// 40kHz carrier/timer
OCR2 = 100;
ADCSRA = 0; // deactivate ADC
ACSR |= _BV(ACIS1); // Comparator Interrupt on Falling Output Edge
ADMUX = 0x03; // connect ADC3-input with comparator
#if defined(__AVR_ATmega168__)
ADCSRB |= _BV(ACME); // connect ADC multiplexer to comparator
#else
SFIOR |= _BV(ACME); // connect ADC multiplexer to comparator
#endif
DDRD &= ~_BV(6); // use Port D Pin 6 as input (AIN0)
sei();
}
Diese Funktion verwende ich für die Initialisierung. Bevor diese aufgerufen wird, wird noch die normale Init() Funktion ausgeführt.
Mit der InitUltrasonics() will man doch den CTC-Mode aktivieren ohne Prescaler um auf 40kHz zu kommen und diese Frequenz mit dem Register OCR2 während dem Chirp verändern.
Aber so wie die Register momentan gesetzt werden, wird kein CTC-Mode aktiviert oder? Das TCCR2 Register wurde doch schon durch die "normale" Init() Funktion auf PWM gesetzt. Jetzt müsste man doch zuert einmal das komplette Register auf 0 setzen und dann die Bits für CTC-Mode setzen oder? Außerdem kann das mit der Zeitmessung also Sleep() doch auch nicht mehr funktionieren wenn die Frequenz auf 40 KHz bzw. 20 KHz umgestellt wurde ( weil doch jeder Compare Match den Counter hochzählt)? Wie kommt man dann bei der Distanzberechnung auf 72?? Vielleicht könnt ihr ja etwas Licht ins Dunkle bringen. Das wäre echt nett :)
Chirp Funktion:
int Chirp(void)
{
unsigned int sleeptime = 0, dist = 0;
InitUltrasonics();
// chirpen:
count36kHz = 0;
while(count36kHz != 20) {
OCR2 = 100 + 20 / 2 - count36kHz;
}
#if defined(__AVR_ATmega168__)
TCCR2A = _BV(WGM21);
TCCR2B = _BV(CS20);
#else
TCCR2 = _BV(WGM21) | _BV(CS20);
#endif
OCR2 = 100;
// analyse echoes:
while(TRUE) {
Sleep(1);
sleeptime++;
if((ACSR & _BV(ACI))) {
dist = (unsigned int) ((long) ((344L * ((sleeptime * 1000L) / 72L) / 10000L) / 2L));
ACSR |= _BV(ACI);
break;
}
ACSR |= _BV(ACI);
if(sleeptime > 3500) {
return -1;
}
}
RestoreAsuro();
return dist;
}
Interrupt Service Routine für Compare Match
#if defined(__AVR_ATmega168__)
SIGNAL(TIMER2_COMPA_vect)
#else
SIGNAL(TIMER2_COMP_vect)
#endif
{
count36kHz++;
if (!count36kHz)
timebase ++;
}
ich bin gerade dabei das Ultraschallmodul von ARX auszutesten. Das ganze funktioniert aber noch nicht.
Hat jemand schon einmal den Bausatz erfolgreich verwendet mit den bereitgestellten Funktionen aus der Asuro-Bib?
Ich habe nämlich die Vermutung, dass das ultrasonic-Modul noch nicht ganz ausgereift ist.
void InitUltrasonics(void)
{
// Change Oscillator-frequency of Timer 2
// to 40kHz, no toggling of IO-pin:
cli();
#if defined(__AVR_ATmega168__)
// fast PWM, set OC2A on compare match, clear OC2A at bottom, clk/1
TCCR2A = _BV(WGM21);
TCCR2B = _BV(CS20);
// interrupt on timer overflow
TIMSK2 &= ~_BV(TOIE2);
TIMSK2 |= _BV(OCIE2A);
#else
TCCR2 = _BV(WGM21) | _BV(CS20);
TIMSK &= ~_BV(TOIE2);
TIMSK |= _BV(OCIE2); // OCIE2: Timer/Counter2 Output Compare Match Interrupt Enable
#endif
// 40kHz carrier/timer
OCR2 = 100;
ADCSRA = 0; // deactivate ADC
ACSR |= _BV(ACIS1); // Comparator Interrupt on Falling Output Edge
ADMUX = 0x03; // connect ADC3-input with comparator
#if defined(__AVR_ATmega168__)
ADCSRB |= _BV(ACME); // connect ADC multiplexer to comparator
#else
SFIOR |= _BV(ACME); // connect ADC multiplexer to comparator
#endif
DDRD &= ~_BV(6); // use Port D Pin 6 as input (AIN0)
sei();
}
Diese Funktion verwende ich für die Initialisierung. Bevor diese aufgerufen wird, wird noch die normale Init() Funktion ausgeführt.
Mit der InitUltrasonics() will man doch den CTC-Mode aktivieren ohne Prescaler um auf 40kHz zu kommen und diese Frequenz mit dem Register OCR2 während dem Chirp verändern.
Aber so wie die Register momentan gesetzt werden, wird kein CTC-Mode aktiviert oder? Das TCCR2 Register wurde doch schon durch die "normale" Init() Funktion auf PWM gesetzt. Jetzt müsste man doch zuert einmal das komplette Register auf 0 setzen und dann die Bits für CTC-Mode setzen oder? Außerdem kann das mit der Zeitmessung also Sleep() doch auch nicht mehr funktionieren wenn die Frequenz auf 40 KHz bzw. 20 KHz umgestellt wurde ( weil doch jeder Compare Match den Counter hochzählt)? Wie kommt man dann bei der Distanzberechnung auf 72?? Vielleicht könnt ihr ja etwas Licht ins Dunkle bringen. Das wäre echt nett :)
Chirp Funktion:
int Chirp(void)
{
unsigned int sleeptime = 0, dist = 0;
InitUltrasonics();
// chirpen:
count36kHz = 0;
while(count36kHz != 20) {
OCR2 = 100 + 20 / 2 - count36kHz;
}
#if defined(__AVR_ATmega168__)
TCCR2A = _BV(WGM21);
TCCR2B = _BV(CS20);
#else
TCCR2 = _BV(WGM21) | _BV(CS20);
#endif
OCR2 = 100;
// analyse echoes:
while(TRUE) {
Sleep(1);
sleeptime++;
if((ACSR & _BV(ACI))) {
dist = (unsigned int) ((long) ((344L * ((sleeptime * 1000L) / 72L) / 10000L) / 2L));
ACSR |= _BV(ACI);
break;
}
ACSR |= _BV(ACI);
if(sleeptime > 3500) {
return -1;
}
}
RestoreAsuro();
return dist;
}
Interrupt Service Routine für Compare Match
#if defined(__AVR_ATmega168__)
SIGNAL(TIMER2_COMPA_vect)
#else
SIGNAL(TIMER2_COMP_vect)
#endif
{
count36kHz++;
if (!count36kHz)
timebase ++;
}