Hallo,
ich möchte mit dem AtMega8 den Ultraschallsensor HC-SR04 auswerten
(http://kt-elektronic.de/wawi11/artikeldaten/sen-hr_sr4-e1/ultraschallmodul_beschreibung_3.pdf).
Dabei muss man laut Datenblatt mindestens 10µs lang einen H-Pegel auf
den Trigger geben und dann wartet man bis der Echo Pin auf H-Pegel geht
und zählt wie lange der H-Pegel bestehen bleibt. Dieser Wert ist dann
proportional zum Abstand.
Mein Programm sieht folgendermaßen bisher aus:
1
#include<avr/io.h>
2
#include"lcd-routines.h"
3
#include<stdint.h>
4
#include<stdlib.h>
5
#include<util/delay.h>
6
#include<avr/interrupt.h>
7
#include<stdbool.h>
8
9
#define F_CPU 12000000;
10
11
12
volatileuint16_tzeitwert;
13
14
15
ISR(TIMER0_OVF_vect)
16
{
17
zeitwert+=1;
18
}
19
20
21
intmain(void)
22
{
23
lcd_init();
24
lcd_setcursor(0,1);
25
lcd_string("Zeit:");
26
27
DDRB=(1<<DDB2)|(0<<DDB1);
28
29
boolflanke_pos;
30
boolflanke_neg;
31
flanke_pos=0;
32
flanke_neg=0;
33
34
zeitwert=0;
35
charBuffer[20];
36
37
// 16-Bit-Timer
38
//TCCR1B = (1<<CS11); // CTC-Mode; Prescaler 8
39
//TCCR1A = (0<<COM1A1) | (0<<COM1A0); // OC1 wird nicht angesteuert
40
//TCCR1A |= (0<<WGM11) | (0<<WGM10); // Der Timer arbeitet als normaler Timer
Wollte das zuerst mit dem 16-Bit Timer machen, aber ich hab gedacht, den
habe ich nicht zum laufen bekommen. Jedoch scheint mir mittlerweile das
Problem am Sensor, bzw. an der Erkennung des Echo-Signals zu liegen.
Ich warte eben, bis der Echo auf H-Pegel ansteigt, setze dann den Timer
zurück und warte bis das Echosignal wieder auf L-Pegel fällt. Und
schreibe das dann auf das Display.
Er scheint aber gar nicht über die zwei Schleifen hinauszukommen, da auf
dem Display bisher nur "Zeit:" steht.
Hm okay, ich kanns mir glaub schon fast selber denken.
Die Eingangspins werden wahrscheinlich nur immer nach einem Zyklus neu
abgefragt, oder?
Dann kann PB1 ja nie auf H-Pegel kommen, zumindest nicht im Programm.
Hat jemand einen besseren Lösungsvorschlag?
Hat keiner einen Ansatz?
Hab es jetzt nochmal etwas anders probiert und zwar mit
Flankenauswertung, bringt aber auch keine Verbesserung, das LCD zeigt
wie vorher nur "Zeit:" an.
1
/*
2
* Ultraschallsensor.c
3
*
4
* Created: 20.04.2014 14:36:27
5
* Author: Stefan
6
*/
7
8
#include<avr/io.h>
9
#include"lcd-routines.h"
10
#include<stdint.h>
11
#include<stdlib.h>
12
#include<util/delay.h>
13
#include<avr/interrupt.h>
14
#include<stdbool.h>
15
16
#define F_CPU 12000000;
17
18
19
volatileuint16_tzeitwert;
20
21
22
ISR(TIMER0_OVF_vect)
23
{
24
zeitwert+=1;
25
}
26
27
28
intmain(void)
29
{
30
lcd_init();
31
lcd_setcursor(0,1);
32
lcd_string("Zeit:");
33
34
DDRB=(1<<DDB2)|(0<<DDB1);
35
36
boolflanke_pos;
37
boolflanke_neg;
38
flanke_pos=0;
39
flanke_neg=0;
40
41
zeitwert=0;
42
charBuffer[20];
43
44
// 16-Bit-Timer
45
//TCCR1B = (1<<CS11); // CTC-Mode; Prescaler 8
46
//TCCR1A = (0<<COM1A1) | (0<<COM1A0); // OC1 wird nicht angesteuert
47
//TCCR1A |= (0<<WGM11) | (0<<WGM10); // Der Timer arbeitet als normaler Timer
Bei Darisus GmbH gibt es ein engl.-sprach. Datenblatt im Menü 'Aktionen'
oder 'Arduino\Boards' unter Artikel HC-SR04. Einiges steht da etwas
anders drin, als unter o.g. Link. Z.B. soll die Laufzeit eines
Messzyklus 50ms, besser 60ms betragen. Findet der Sensor kein Objekt,
dann liegt am Echo-Pin ein 38ms langer High-Pegel an (sonst kürzer).
Dein Code ist für mich schwierig, da ich keine AVRs in C programmiere.
Ich versuche es in Assembler. Das HC-SR04 werde ich mir für meinen
ATmega8 mal besorgen. Wie ist die Hierachie bei der Auswertung der
logischen Ausdrücke in den if-Anweisungen? Fehlen noch Klammern?
Danke für den Einwand, hätte da gar nicht dran gedacht.
Weiß leider nicht genau wie die Priorisierung bei C ist, also habe ich
es mal getestet:
1
...
2
if(((PINB&0x01)==1)&&!flanke_pos)
3
...
4
5
if(((PINB&0x01)==0)&&flanke_neg)
6
...
Leider bringt das auch keine Änderung.
Die Laufzeit des Messzyklus dürfte bei mir ja keine Rolle spielen, da er
sowieso erst wieder eine Messung ausführt, wenn ein Messwert ermittelt
wurde.
Hat denn sonst keiner einen Ansatz?
Hallo Robotico,
1. Der Echo-Ausgang des HC-SR04 kann beim Senden des Trigger-Impulses
u.U. immer noch auf H-Pegel sein. In diesem Fall dauert es von der
H-L-Flanke auf dem Trigger-Eingang bis zum L-Pegel des Echo-Ausgangs so
4.5us. Du solltest an dieser Stelle also ein kleine Verzögerung
einbauen.
2. Wenn der HC-SR04 kein Ultraschallecho empfängt, so bleibt bei manchen
Varianten des HC-SR04 der Echo-Ausgang einfach bis auf weiteres auf
H-Pegel. Für diesen Fall (und für den Fall, dass Echo gar nicht auf
H-Pegel geht) solltest du Timeouts vorsehen.
3. Zwei Messungen sollten einen Abstand von so 60ms nicht
unterschreiten, damit die erste Schallwelle sicher verebbt ist und die
zweite Messung nicht verfälscht.
LG, Sebastian
Hallo Sebastian,
danke für deine Antwort!
1. Aber am Echo-Ausgang ist doch im normalen Zustand immer L-Pegel, nur
zwischen Aussenden und Detektieren des Ultraschalls geht das Echo-Signal
auf H-Pegel. Somit kann bei einer HL-Flanke am Trigger-Eingang ja
eigentlich das Echo-Signal nicht auf H sein, oder?
2. Von Timeouts habe ich noch nichts gehört, da muss ich mich mal schlau
machen. Danke!
3. Dadurch dass ich ja aber eine Messung erst nach Detektieren des
Signals wieder starte, also bei HL-Flanke des Echos, sollte das ja
eigentlich kein Problem machen, oder?
Robotico schrieb:> 1. Aber am Echo-Ausgang ist doch im normalen Zustand immer L-Pegel, nur> zwischen Aussenden und Detektieren des Ultraschalls geht das Echo-Signal> auf H-Pegel. Somit kann bei einer HL-Flanke am Trigger-Eingang ja> eigentlich das Echo-Signal nicht auf H sein, oder?
Eigentlich ja, aber uneigentlich passiert es doch. Bei mir zumindest
manchmal (ich messe jede Minute den Pegel im Öltank per HC-SR04).
> 2. Von Timeouts habe ich noch nichts gehört, da muss ich mich mal schlau> machen. Danke!
Bitte nicht falsch verstehen. Du solltest einfach mögliche Fehlerfälle
abfangen, bei denen an den pins gar nichts passiert, und nach einer
gewissen Zeit abbrechen und neu anfangen.
Robotico schrieb:> 3. Dadurch dass ich ja aber eine Messung erst nach Detektieren des> Signals wieder starte, also bei HL-Flanke des Echos, sollte das ja> eigentlich kein Problem machen, oder?
Nein, es macht ein Problem. Das Ultraschallecho kann ja von mehreren
Zielen in verschiedenen Distanzen reflektiert werden, und dann sind beim
Eintreffen des ersten Echos immer noch andere Echos auf dem Weg zurück
zum HC-SR04. Diese würden dann nach dem Senden des nächsten Impulses
empfangen und fälschlich als Reflektion dessen interpretiert werden.
LG, Sebastian
Okay vielen Dank für deine Hilfe, dann versuche ich das mal umzusetzen.
Aber noch etwas:
Habe gerade zum ersten Mal wirklich den AVR Simulator getestet und
irgendwie scheint der bei mir auch in das erste IF zu springen, wenn PB1
gar nicht 1 ist, was ja eigentlich überhaupt nicht sein kann. Außerdem
interpretiert der die IF-Verzweigung irgendwie als Schleife und macht
das immer und immer wieder, alles was nach dem ersten IF steht wird
weder ausgeführt noch geprüft. Das Problem wird bestimmt bei mir liegen,
aber ist das Problem und die zugehörige Lösung bekannt?
Moin....habe auch ein ähnliches Problem beim auswerten des Sensors!
Versuche mir den Abstand auf einem LCD anzeigen zu lassen...funktioniert
aber nicht, da TCNT0 mir fast immer konstant das selbe raus gibt, obwohl
ich den Abstand verändere. Der Wert ändert sich nur minimal.
Stimmt da vielleicht was in der Funktion nicht?
Da das Programm um einiges größer ist, hab ich nur den Teil für die
Abstandsmessung ausgeschnitten...
Peter schrieb:> Moin....habe auch ein ähnliches Problem beim auswerten des Sensors!> Versuche mir den Abstand auf einem LCD anzeigen zu lassen...funktioniert> aber nicht, da TCNT0 mir fast immer konstant das selbe raus gibt, obwohl> ich den Abstand verändere. Der Wert ändert sich nur minimal.> Stimmt da vielleicht was in der Funktion nicht?
Das Datenblatt spricht von einem 10 Mykro-Sekunden langen Trigger Puls.
Nicht Millisekunden.
> Da das Programm um einiges größer ist, hab ich nur den Teil für die> Abstandsmessung ausgeschnitten...
Ganz starke Idee, den Ausschnitt als Bild anzuhängen. Da kann man sich
so wunderbar auf Codestellen beziehen.
Karl Heinz schrieb:> Peter schrieb:>> Moin....habe auch ein ähnliches Problem beim auswerten des Sensors!>> Versuche mir den Abstand auf einem LCD anzeigen zu lassen...funktioniert>> aber nicht, da TCNT0 mir fast immer konstant das selbe raus gibt, obwohl>> ich den Abstand verändere. Der Wert ändert sich nur minimal.>> Stimmt da vielleicht was in der Funktion nicht?>> Das Datenblatt spricht von einem 10 Mykro-Sekunden langen Trigger Puls.> Nicht Millisekunden.
Und auch den Teil beachten
1
You can calculate the range through the time interval between
2
sending trigger signal and receiving echo signal.
d.h. was dich interessiert ist die Zeit die vergeht, gemessen von deinem
Puls, bis du am Empfänger das Echo siehst. Die Länge des Echo-Pulses
hingegen ist NICHT die gewünschte Information.
Peter schrieb:> Mit der Formel (TCNT0*ps*ss*100)/(F_CPU*2); wollte ich mir den Abstand> in cm ausgeben lassen.
Das ändert aber immer noch nichts daran, dass nicht die LÄnge des
Echopulses die Entfernungsinformation enthält, sondern die Zeit die
vergeht, von der Auslösung des US-Pulses bis das Echo eintrifft!
Also
* _delay_us(10) anstatt _delay_ms(10)
* die Zeit beginnt zu laufen nachdem du den Puls rausgeblasen hast und
endet damit, dass der Eingangspin von 0 auf 1 wechselt. WIe lange der
Pin dann auf 1 bleibt interessiert keinen.
Es kann höchstens jetzt noch sein, dass du nach dem Aussenden des Pulses
eine kleine Zeit warten musst, bis du den Eingang das erst mal abfrägst,
weil der Empfänger ja logischerweise nicht nur das Echo empfängt,
sondern ganz schwach auch auf den eigentlichen Sendepuls regieren
könnte, Inwiefern der Hersteller da vorgesorgt hat, weiss ich aber
nicht. Im Datenblatt ist dazu nichts erwähnt.
Die Zeit hab ich umgestellt.
Naja ich möchte den Abstand raus bekommen. Daher muss ich ja die Zeit
des Echo-Impulses messen. Denn umso größer der Abstand desto länger ist
Echo auf eins oder?
Karl Heinz schrieb:> * die Zeit beginnt zu laufen nachdem du den Puls rausgeblasen hast und> endet damit, dass der Eingangspin von 0 auf 1 wechselt. WIe lange der> Pin dann auf 1 bleibt interessiert keinen.
Den nehme ich zurück.
Da scheinen mehrere Beschreibungen im Umlauf zu sein und ich bin da
einer Zweit-Quelle aufgesessen.
In einer anderen Beschreibung
https://docs.google.com/document/d/1Y-yZnNhMYy7rwhAgyL_pfa39RsB-x2qR4vP8saG73rE/edit
ist es so beschrieben, wie du es implementiert hast. Die Pulslänge ist
proportional der Distanz.
Hier
http://www.micropik.com/PDF/HCSR04.pdf
ist es anders rum beschrieben: Die zeitliche LÄnge vom Puls bis zum
Einsetzen des Echos ist die Distanz.
Peter schrieb:> Aber Danke für die schnelle Antwort, ich werde es gleich mal> ausprobieren.
Wie wäre es, wenn du statt rumzuprobieren mal zu einem Oszi, DSO, LA
oder was es sonst noch für angemessene Werkzeuge gibt, greifst, um
überhaupt erstmal zu klären, was der Sensor so von sich gibt?