PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : C-Code für SRF05 gesucht



Banzai
07.05.2007, 23:50
Hallo Leutz,

nachdem ich mich überzeugt habe, dass mein SRF05 unter BÄHSCOM funktioniert, wollte ich das mal in C umsetzen.
Ich scheitere aber anscheinend an der Umschalterei beim Auslösen und Messen auf einem Pin.


/*PSEUDOCODE*/
/* SRF05 an PB2 */

void doUltra()
{
static int counter = 0;

DDRB |= (1<<PB2); // Ausgang
PORTB |= (1<<PB2); // High
/* Messvorgang? */
_delay_us(20); /* min 10µs sind gefordert */

PORTB &= ~(1<<PB2); // Low
DDRB &= ~(1<<PB2); // Eingang
PORTB |= (1<<PB2); // High (interner Pullup?) */

while( PINB & (1<<PB2) ); // auf Signal warten????

while(!(PINB & (1<<PB2)) // Zählen wielange High
counter++;

return counter;
}

Jedenfalls hängt sich die Funktion in der while-Schleife auf, anscheinend kommt kein Signal (auch wenn das Ding 20cm vor einer Wand steht!).
Das jetzt hier keine Zeit gemessen wird, sei mal vernachlässigt.

Hat jemand einen fertigen Code dafür? Wäre für jeden Tipp dankbar.

thx4answer

Banzai

robo junior
08.05.2007, 13:25
hast deine while-Bedingungen falsch gesetzt. Zuerst wartest du ja solange der Pin low ist. Also

while(!(PINB & (1<<PB2));
Dann wartest du solange der Pin high ist:

while(PINB & (1<<PB2));

Außerdem würde ich das messen der Signallänge mit einem Timer machen. Einfach zwischen den beiden Schleifen den Timer auf 0 setzen und nach der zweiten Schleife den Timerstand auslesen. (musst natürlich den Prescaler so anpassen, dass das zur Signallänge passt und wahrscheinlich einen 16bit Timer benutzen)

den Pullup an deinem Eingang kannst du weglassen (keine Ahnung obs einen Unterschied macht wenn du ihn anmachst, ich habs jedenfalls ohne gemacht und das funktioniert ohne Probleme.)

Banzai
08.05.2007, 15:08
Hallo robojr.,

die while-Bedingungen hatte ich natürlich schon hin- und hergetauscht, der einzige Effekt war, dass die Funktion dann halt später bzw. früher hing.

Das mit dem Zeitmessen wollte ich über einen 1µs-Interrupt mit Timer0 (den 16bit Timer1 brauch ich für was anderes) machen, der allerdings macht keine 1µs (Thema in einem anderen Thread https://www.roboternetz.de/phpBB2/viewtopic.php?t=30147 ). Der wäre dann auch noch für einen Tick-Counter und vieles mehr zuständig.

Das 'Zurücksetzen' des Pins hatte ich auch schon mal weggelassen, was keinen Änderung brachte.

Hast du nicht einen Code-Schnipsel für mich bzw. eine autarke Methode für den SRF05, wenn es bei dir funktioniert? Wäre super.... =D> =D>

thx

Banzai

robo junior
08.05.2007, 15:13
uint16_t getAbstand(uint8_t sensor) { //Ultrschallsensoren abfragen
uint8_t tmp_sreg;
tmp_sreg = SREG;
cli();
uint16_t ergebnis;

DDRC |= sensor; //Ausgang high
PORTC |= sensor;
_delay_us(20);
PORTC &= ~sensor; //Pin auf Eingang setzen
DDRC &= ~sensor;
while(!(PINC & sensor)); //auf Sensorantwort warten
TCNT1 = 0; //Counter Register auf 0 setzen
while(PINC & sensor); //warten bis Signalende

ergebnis=TCNT1; //Signallänge auslesen
ergebnis=ergebnis*20; //Abstand berechnen
SREG=tmp_sreg;
return (uint16_t) ergebnis/29;
}


der Timer 1 läuft mit Prescaler 64, die Ergebnisse sind dann in mm.