Forum: Mikrocontroller und Digitale Elektronik HC-SR04 Ultraschalldistanzsensor an ATmega32


von Sandro L. (sandro_l)


Angehängte Dateien:

Lesenswert?

Hallo,

Ich muss für eine Projektarbeit einen Ultraschalldistanzsensor des Typs 
HC-SR04 
(http://www.hobbyking.com/hobbyking/store/uploads/684736734X7478X3.pdf) 
auslesen.

Um eine Messung zu starten, muss man mindestens ein 10µs Signal auf den 
Trigger-Pin des Moduls geben. Danach sollte ein Signal auf dem Echo-Pin 
zurückgegeben werden.

Ich habe hier mal den C-Code, den ich dazu geschrieben habe. Nur wird 
die Messung nicht gestartet und es kommt kein Signal auf dem Echo-Pin.

Das Modul muss funktionieren, da ich es bereits erfolgreich bei meinem 
Quadrocopter benutzt habe. Um einen Defekt ganz auszuschliessen, habe 
ich auch ein anderes Exemplar probiert.
1
#include <avr/io.h>
2
#include <avr/interrupt.h>
3
4
#define F_CPU 8000000UL
5
6
#define ULTRASONIC_SENSOR_QUANTITY 1
7
8
#define ULTRASONIC_STATE_TRIGGER 1
9
#define ULTRASONIC_STATE_WAITING 2
10
#define ULTRASONIC_STATE_ECHO 3
11
12
volatile uint16_t Ultrasonic_distance[ULTRASONIC_SENSOR_QUANTITY];
13
volatile uint8_t Ultrasonic_current_sensor;
14
volatile uint16_t Ultrasonic_counter;
15
volatile uint8_t Ultrasonic_state;
16
17
int main(void)
18
{
19
    DDRB = (1<<PB0) | (1<<PB1) | (1<<PB2) | (1<<PB3);
20
    PORTB = (1<<PB4);
21
    
22
    PORTB |= (1<<PB0);
23
24
    Ultrasonic_init();
25
        
26
    sei();
27
    
28
    while(1)
29
    {
30
        asm("nop");
31
    }
32
    return 0;
33
}
34
35
void Ultrasonic_init()
36
{
37
    DDRC |= (1<<PC2); /* Trigger output */
38
    
39
    PORTD |= (1<<PD2);
40
    
41
    Ultrasonic_current_sensor = 0;
42
    Ultrasonic_counter = 0;
43
    Ultrasonic_state = ULTRASONIC_STATE_TRIGGER;
44
    
45
    /* config INT0 */
46
    MCUCR |= (1<<ISC00);
47
    GICR |= (1<<INT0);
48
    
49
    /* config Timer/Counter 0 
50
     * Prescaler: 8 (1 step = 1 µs)
51
     */
52
    TCCR0 = (1<<CS01);
53
    TIMSK |= (1<<TOIE0) | (1<<OCIE0);
54
    
55
    PORTC |= (1<<PC2);
56
    TCNT0 = 0;
57
    OCR0 = 10;
58
}
59
60
/* interrupt routines */
61
62
ISR(TIMER0_OVF_vect)
63
{
64
    Ultrasonic_counter += 256;
65
}
66
67
ISR(TIMER0_COMP_vect)
68
{
69
    if(Ultrasonic_state == ULTRASONIC_STATE_TRIGGER)
70
    {
71
        PORTC &= ~(1<<PC2);
72
        Ultrasonic_state = ULTRASONIC_STATE_WAITING;
73
        PORTB |= (1<<PB1);
74
    }
75
}
76
77
/* on any logical change at PD2 */
78
ISR(INT0_vect)
79
{
80
    
81
    PORTB |= (1<<PB2); /* Die LED sollte eingeschaltet werden, sobald ein Signal kommt. */
82
}

Hat jemand eine Idee, warum es nicht funktioniert?

Vielen Dank im Voraus.

: Bearbeitet durch User
von Sebastian W. (wangnick)


Lesenswert?

Hallo Sandro,

versuch doch mal, den Trigger-Ausgang zunächst eine Weile auf low zu 
stellen. Ich meine mich zu erinnern dass der SR04 auch die steigende 
Trigger-Flanke braucht, nicht nur die fallende, um die Messung 
auszulösen ...

LG, Sebastian

PS: Gute Problembeschreibung!

von Sandro L. (sandro_l)


Lesenswert?

Ich habe vor der drittletzten Codezeile der Funktion Ultrasonic_init() 
folgendes hinzugefügt:
1
PORTC &= ~(1<<PC2);
2
_delay_us(10);
Natürlich habe ich "#include <util/delay.h>" zu Beginn der Datei 
eingefügt.

Hat leider immer noch das selbe Ergebnis.
Ich habe auch noch versucht, das Triggersignal nur mit der _delay_us() 
Funktion, also ohne Timer, zu bilden. Funktioniert aber auch nicht.

von chris (Gast)


Lesenswert?

wie siehts denn mit der stromversorgung aus und den leitungswegen zu 
modul hin?

wenn du den der trigger mal länger als 10µs auf entsprechndes level 
ziehst und mal misst ob am pin überhaupt was ankommt.

OSZI vorhanden?

von Sandro L. (sandro_l)


Lesenswert?

chris schrieb:
> wie siehts denn mit der stromversorgung aus und den leitungswegen zu
> modul hin?

Das Modul habe ich über das mitgeliferte Kabel (ca. 17 cm) 
angeschlossen.

> wenn du den der trigger mal länger als 10µs auf entsprechndes level
> ziehst und mal misst ob am pin überhaupt was ankommt.

Ich habe mal den Pin einfach auf 1 gesetzt und die Spannung gemessen. 
Wie erwartet war sie 5V. Ich habe auch an den anderen Ausgängen des Port 
C gemessen, die ich auf 0 gesetzt habe. Komischerweise sind dort nicht 
alle auf 0V, sondern auch ein paar, bei denen ich auch nach mehrmaligem 
Messen 5V gemessen habe. Der Durchgangsprüfer hat keine Lötbrücke zu VCC 
gemeldet.
Kann es sein, dass ein ganzer Port kaputt ist? Scheinbar kann ich an 
diesem Port den Status nicht ändern.

> OSZI vorhanden?

Hab ich extra heute Nachmittag aufgetrieben :)

von Albert M. (Firma: Bastler aus Mönchengladbach) (albertm) Benutzerseite


Lesenswert?

Ich habe jetzt keine Lust ins Datenblatt zu sehen, aber kann es sein 
dass Du die JTAG Fuses auf default stehen hast und Du genau diese Pins 
benutzt? Wenn ja - dann JTAG Fuses disablen um das JTAG Interface 
abzuschalten.

: Bearbeitet durch User
von chris (Gast)


Lesenswert?

sollte es nicht am jtag liegen nochmal den triggerimpuls prüfen

>    PORTC |= (1<<PC2);
heißt PC2 = 1
>    TCNT0 = 0;
>    OCR0 = 10;
....
....
>ISR(TIMER0_COMP_vect)
>{
>    if(Ultrasonic_state == ULTRASONIC_STATE_TRIGGER)
>    {
>       PORTC &= ~(1<<PC2);
heißt PC2 = 0
>        Ultrasonic_state = ULTRASONIC_STATE_WAITING;
>        PORTB |= (1<<PB1);
>    }
>}
......

http://kt-elektronic.de/wawi11/artikeldaten/sen-hr_sr4-
1/ultraschallmodul_beschreibung_3.pdf

entsprechende pdf sagt, das dass ding mit ein L/H Impulse ausgelöst 
wird.

von Sandro L. (sandro_l)


Lesenswert?

Wow, vielen Dank für den Tipp mit dem JTAG-Fusebit! Dieses war wirklich 
gesetzt und hat diese Probleme verursacht.

Jetzt funktioniert es einwandfrei.

@chris: Das Triggersignal muss laut Datenblatt, welches ich beim ersten 
Beitrag gepostet habe, folgendermassen sein:
"1.Adopt IO trigger through supplying at least 10us sequence of high 
level signal."

Das Triggersignal ist also schon richtig. Es gibt wahrscheinlich 
unterschiedliche Versionen, die das verschieden handhaben.

Vielen Dank für die vielen Tipps und die schnelle Hilfe.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.