PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Ultraschallsensor - Anfänger



Codingboy
29.09.2011, 00:07
Hallo,

ich habe mir vor kurzem einen uC gekauft und alles Mögliche programmiert was man mit einem Taster und einer LED nur tun kann.
Jetzt würde ich mir gerne einen Ultraschallsensor zur Entfernungmessung zulegen.
Relevante Entfernungen sind etwa 10cm bis 3m.
Ich weiß zum einen nicht, welchen Sensor ich nehmen soll. Gibt es nur in Reichweite Unterschiede oder noch andere?
Zum anderen weiß ich nicht, wie ich so einen Sensor ansteuern soll! Ich habe einen ATmega32 Mikrocontroller, also einen, der digitale Signale verarbeitet. Wie kann der Sensor nun also eine Entfernung zurückmelden? Über eine gewisse Zeit high-Pegel?

Ich hoffe auf eure Hilfe!

Gruß,
Codingboy

BMS
29.09.2011, 08:14
Hallo,

Ich habe einen ATmega32 Mikrocontroller, also einen, der digitale Signale verarbeitet. Wie kann der Sensor nun also eine Entfernung zurückmelden? Über eine gewisse Zeit high-Pegel?

Beim SRF05 wird der gemessene Abstand als Dauer des High-Pegels ausgegeben. Es gibt aber auch Sensoren mit Bussystemen wie I2C oder UART.
Hier gibt es eine Übersicht von den verschiedenen Ultraschallsensoren:
http://rn-wissen.de/index.php/Sensorarten#Ultraschall_Sensoren
Bei der Richtcharakteristik und der messbaren Entfernung unterscheiden sich die Sensoren kaum.
Grüße,
Bernhard

Codingboy
29.09.2011, 10:15
Leider gibt es nirgends im rn-netz ein Beispieö in c für soetwas.
Aber so wie ich es verstanden habe sollte folgender Pseudo code funktionieren:

setze Sensor als Output;
setze Sensor auf High-Pegel;
setze Sensor auf Low-Pegel;
setze Sensor als Input;
warte bis Input auf High-Pegel ist;
integer zähler = 0;
while (zahler<MAXWARTEZEIT && Input ist High)
{
zähler++;
}
integer vergangene Zeit = zähler*TAKTZEIT;
in tabelle nachsehen, welcher Entfernung diese Zeit entspricht;

Ist das so in etwa richtig?

das sollte zumindest für SRF05 mode 2 gelten

BMS
29.09.2011, 18:00
Hallo,
ja der Code sollte soweit passen.
Zur Sicherheit kannst du noch einen Widerstand in die Sensorleitung schalten (für den Fall dass durch einen Softwarefehler sowohl Sensor als auch Mikrocontroller den Pin auf Ausgang schalten->Kurzschluss). Also z.B. 100-500 Ohm.
Eine Tabelle zum Umrechnen brauchst du wirklich nicht. Das lässt sich linear umrechnen, also einfach den Inhalt von Zähler mit einer Zahl multiplizieren, das findet man durch Probieren.
Grüße,
Bernhard

Codingboy
29.09.2011, 18:06
Danke fürs Absegnen und den Tipp mit dem Wiederstand!

Chypsylon
01.10.2011, 14:12
Aber mit dem code blockierst du während der Messung den ganzen avr, besser währe eine messung mittels timer (und icp)

BMS
01.10.2011, 14:44
Aber mit dem code blockierst du während der Messung den ganzen avr, besser währe eine messung mittels timer (und icp)
Dein Einwand ist durchaus berechtigt. Aber um einzusteigen und dem Sensor überhaupt einmal einen Abstandswert zu entlocken, finde ich das durchaus praktikabel mit Polling. Wenn die Anwendung nicht zeitkritisch ist, kann man das notfalls auch so lassen.
Mit Timer ist es natürlich um einiges eleganter ;)
Grüße, Bernhard

Besserwessi
01.10.2011, 16:03
Beim Senden wird man in der Regel etwa mehr als 1 Puls senden müssen. Also das Abwechselnd high und low einige male wiederholen. So schlecht ist das mit dem Pollen nicht: bis der Puls zurück ist dauert es maximal etwa 30 ms ( 5 m Abstand), das ist nicht besonders lang.

BMS
01.10.2011, 18:54
Beim Senden wird man in der Regel etwa mehr als 1 Puls senden müssen. Also das Abwechselnd high und low einige male wiederholen. So schlecht ist das mit dem Pollen nicht: bis der Puls zurück ist dauert es maximal etwa 30 ms ( 5 m Abstand), das ist nicht besonders lang.
Also bei mir hat es gereicht, einen Puls zu senden. Allerdings hab ich am Sensor noch einen Pull-up/down(weiß nicht mehr?) Widerstand gebraucht, weil der Anschluss ja kurzzeitig hochohmig ist wenn der Mikrocontroller auf Eingang schaltet und der Sensor den Anschluss noch nicht "übernommen" hat.
Nach einer Messung sollte man auch noch eine kurze Zeit warten, damit das Echo verhallt. Vor allem wenn mehrere solcher Sensoren verwendet werden, muss man darauf achten, da es sonst zu Fehlmessungen kommen kann.
Grüße,
Bernhard

Codingboy
01.10.2011, 20:50
Also zeitkritisch ist es vorerst nicht.
Könnte aber irgendwann mal so eingesetzt werden. Wie soll das also mit TIMER gehen? Wäre nett wenn jemand 3 Zeilen Code schreibt oder link zu nem Beispiel.
Danke schon mal!!!

Chypsylon
02.10.2011, 16:38
Also zeitkritisch ist es vorerst nicht.
Könnte aber irgendwann mal so eingesetzt werden. Wie soll das also mit TIMER gehen? Wäre nett wenn jemand 3 Zeilen Code schreibt oder link zu nem Beispiel.
Danke schon mal!!!
Bitte ;)

Auf drei Zeilen gehts sich zwar nicht ganz aus aber ich hab noch code für einen HC-SR04 (http://marsohod.org/index.php/downloads/doc_download/77---hc-sr04) (nachbau des SRF-04) herumfliegen gehabt. Das ganze ist für einen atmega32 mit 16MHz ausgelegt, wenn du einen andere Taktfrequenz hast musst du evt den Prescaler und die Rechnung anpassen...


/******
01082011
atmega32@16MHZ
******/

#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>
#include <stdlib.h>

#include <lcd.h>
#include <lib_main.h>
#include <taster.h>


volatile uint16_t timestamp_last = 0;
volatile uint16_t zeit = 0;

void trig(void)
{
PORTC |= (1<<PC5);//Trig high
_delay_us(12);
PORTC &= ~(1<<PC5);//TRIG auf low
}



ISR(TIMER1_CAPT_vect)
{
//Wenn steigende Flanke
if(TCCR1B & (1<<ICES1))
{
//Flankenerkennung auf fallend
TCCR1B ^= (1<<ICES1);
//aktuelen timer-wert speichern
timestamp_last = ICR1;
}
//fallende Flanke
else
{
//Flankenerkennung auf steigend
TCCR1B ^= (1<<ICES1);
//Laufzeit = aktueller timerwert - vorheriger timerwert
zeit = ICR1 - timestamp_last;
}

}


int main(void)
{
DDRC |= (1 << PC5);//Trig als Ausgang
PORTC &= ~(1<<PC5);//TRIG auf low

DDRD &= ~(1<<PD6);//Echo als Eingang
PORTD &= ~(1<<PD6);//ECHO pullup AUS

lcd_init(LCD_DISP_ON);

lcd_puts("US Test");
lcd_gotoxy(0,1);

//Timer konfigurieren
TCCR1A = 0; // normal mode, keine PWM Ausgänge
//Noise Canceler aktivieren, Flankenerkennung auf steigende, Prescaler auf 64
TCCR1B |= (1<<ICNC1) | (1<<ICES1) | (1<<CS11) |(1<<CS10);

//ICP Interrupt aktivieren
TIMSK |= (1<<TICIE1);

//Globale Interrupts aktivieren
sei();
while(1)
{
//Entfernung aus Laufzeit berechnen
zeit = (zeit*4)/58;

lcd_puts(" ");
lcd_gotoxy(0,1);
lcd_put_uint16(zeit);
lcd_gotoxy(0,1);
//Messung auslösen
trig();
_delay_ms(50);
}

return 0;
}

Codingboy
04.10.2011, 17:31
Ups, das sieht wirklich nach etwas mehr aus...
Danke!