Verständnisfrage zur PulseIn() Funktion

Servus Community,

ich stehe gerade auf dem Schlauch. Ich habe einen Ultraschallsensor der nach 10us High auf dem Trigger-Pin ein Burst-Signal abschickt und der Echo-Pin dieses registrieren soll und davon nimmt man dann die Zeit. Soweit so gut und es funktioniert auch aber irgendwie passt die Beschreibung der PulseIn-Function einfach nicht.

Da steht doch eindeutig, dass die Zeit gemessen wird, bei der der Pin auf einem State bleibt. Bspw. er ist auf Low bekommt ein Signal --> geht auf High --> wie lange bleibt er auf High.

Das würde aber absolut keinen Sinn ergeben. Denn egal wie viele Signale ich sende, treffen diese in ebenso kurzer Zeit gleichzeitig wieder ein. Ob ich 1m oder 3m entfernt wäre spielt dabei keine Rolle.

Da es aber funktioniert gehe ich davon aus, dass die Beschreibung nicht ganz korrekt ist. Kann es sein, dass mit dem Aufruf der Funktion ein Timer gestartet wird und dieser beendet wird, sobald ein Echo empfangen wird?

const int trigPin = 9;
const int echoPin = 10;
long duration;
int distance;

void setup() {
pinMode(trigPin, OUTPUT);
pinMode(echoPin, INPUT);
Serial.begin(9600);
}
void loop() {
// Clears the trigPin
digitalWrite(trigPin, LOW);
delayMicroseconds(2);
digitalWrite(trigPin, HIGH);
delayMicroseconds(10);
digitalWrite(trigPin, LOW);
duration = pulseIn(echoPin, HIGH);
distance= duration*0.034/2;

Stephan_Berlin:
Das würde aber absolut keinen Sinn ergeben. Denn egal wie viele Signale ich sende, treffen diese in ebenso kurzer Zeit gleichzeitig wieder ein. Ob ich 1m oder 3m entfernt wäre spielt dabei keine Rolle.

Was hat denn die Häufigkeit der 'Signale' (was auch immer du damit meinst) mit deren Laufzeit zu tun?

Das war etwas unglücklich formuliert.

Ich sende 8 US-Signale. (bspw. im Abstand von 10us)
Echo wartet auf den Empfang via PulseIn geht auf High und wartet bis kein Pulse mehr kommt. (Zeitmessung laut dem Arudino Wiki)
Aber die Zeit die damit gemessen werden würde, wäre immer die gleiche, egal ob das Objekt 1m oder 3m weit weg ist. Ich würde immer die Zeit erhalten, in deren Abstand ich die Signale geschickt habe, oder nicht?

Also entweder ich übersetze das gänzlich falsch oder das ist nicht die korrekte Funktionsweise der PulseIn Funktion.

Habe gerade im englischen Forum hier die gleiche Frage gefunden :smiley: Anscheinend ist die Beschreibung im Wiki wirklich irreführend.

http://forum.arduino.cc/index.php?topic=323616.0

Schau dir mal den Verlauf der Signale Trigger und Echo an, dann wirst du sehen, dass pulseIn() korrekt beschrieben ist.

Dass ein Burst gesendet wird, verheimlicht dir der US-Modul.

Das Ausgangssignal vom Sensor geht HIGH wenn der Ultraschall ausgesendet wird und geht LOW wenn das Echo zurückkommt. Die Dauer des Zurückkommen des Echo hängt vom Abstand des Hindernis, das die Echos zurückschickt ab.

Grüße Uwe

Wenn Whandall das genauso sieht, wäre ich dankbar, wenn er zeigen könnte, welche Linie was ist :slight_smile:
Sonst hätte ich gedacht, die obere Linie sei der Trigger, und der Abstand zwischen Trigger und der Flanke 0-1 der zweiten Linie sei die gemessene Entfernung...

1 Zeile Trigger, 2 Zeile Echo.

Ganz oben hast du die Zeitbasis, den blauen Marker habe ich auf den zu messenden Puls gelegt.

Whandall:
1 Zeile Trigger, 2 Zeile Echo.

Ganz oben hast du die Zeitbasis, den blauen Marker habe ich auf den zu messenden Puls gelegt.

Danke für die Bestätigung. Die Breite des Echo ist erstmal egal, und hängt von Reflexionen ab. Abstand zwichen Trigger und Echo ist die Entfernung und kann mit pulseIn gemessen werden.

Nein.

Gemessen wird die Zeit, die die zweite Zeile HIGH ist.

Der Pin heisst Echo, er stellt nicht das Echo dar, sondern einen Puls in der Breite bis das Echo eintrifft.

Oh, dann müsste die Enfernung also mitpulseIn(EchoPin, HIGH); gemessen werden, und man hat etwas Zeit, bevor der Wechsel 0 -> 1 kommt ? !

https://www.arduino.cc/en/Reference/PulseIn:
pulseIn(pin, HIGH); waits for the pin to go HIGH, starts timing, then waits for the pin to go LOW and stops timing

So ist es.

Der US Modul muss den Burst senden und warten bis der am Empfänger vorbei ist,
er kann dann erst mit der Messung loslegen.

Vielen Dank für euren Einsatz. Ehrlich gesagt verwirrt mich das jetzt noch mehr.

Whandall:
Nein.

Gemessen wird die Zeit, die die zweite Zeile HIGH ist.

Der Pin heisst Echo, er stellt nicht das Echo dar, sondern einen Puls in der Breite bis das Echo eintrifft.

Das bedeutet, dass die Funktion PulseIn() den Echo-Pin auf High setzt und dieser zurückgesetzt wird, sobald das "Echo" tatsächlich eintrifft? Welches davon, das erste, zweite ... Signal des Bursts?

Whandall:
So ist es.

Der US Modul muss den Burst senden und warten bis der am Empfänger vorbei ist,
er kann dann erst mit der Messung loslegen.

Das wirft mich wieder total aus der Bahn aber ich versuchs mal.

  1. Trigger auf High für kurze Zeit --> Burst-Signal geht raus
  2. kurze Pause?
  3. PulseIn() startet --> Messung der Zeit von Echo-Low bis Echo-High-End --> die Hälfte davon wäre die Entfernung

Könntest du das bitte nochmal Ettapenweise auflisten? Du hast das vollständig verstanden aber anscheinend stelle ich mir hier ziemlich blöd an :confused:

In meinen Augen will ich doch eigentlich die Zeit messen in der Echo-Low ist, da zum Zeitpunkt von High das Signal erfolgreich reflektiert wurde.

Das bedeutet, dass die Funktion PulseIn() den Echo-Pin auf High setzt

Nein!
pulseIn() setzt keine Pins.
Wozu auch?

Du hast die PulseIn Funktion falsch verstanden

Sie benötigt 2 Signalwechsel, dein US-Modul bringt aber nur einen Signalwechsel.

Funktion und Sensor passen nicht zusammen. PulseIn misst vom ersten bis zum zweiten Wechsel des Zustandes. Du bekommst aber beim Start keinen Zustandswechsel des US-Moduls. Erst nach dem das Echo ankommt, wechselt es. Dir fehlt das Startsignal

Deswegen deine Verwirrung. Die Beschreibung der Funktion stimmt schon. Die Angabe High oder LOW bezieht sich drauf, ob er eine positive oder negative Flanke zum starten nimmt. bei HIGH wird also eine Positive Flanke zum starten benutzt (wechsel von LOW auf HIGH). Der Aufruf selbst startet die Zeitmessung eben NICHT. Und da die Funktion wartend ist, wird mit einem Timeout verhindert das dein programm stehen bleibt. Und für Timeout wird die Zeit Null zurück gegeben. Da es nicht möglich ist NULL Zeit zu messen, es wird mindestens 1 gemessen, weis man das was nicht passt. Muss also im Ergebniss die Null abfragen und als Fehler auswerten.

Betrachte den Modul doch einfach als Black-Box.

Mit dem Trigger startest du (was auch immer) und die Länge des nächsten High-Pulses (auf Echo) liefert das Ergebnis.
Wieviele US-Impulse mit welcher Frequenz ausgegeben werden ist doch eher nebensächlich.

Sobald der Modul irgendetwas nach seinem Sendeversuch empfängt, beendet er den Puls.

Das macht es etwas schwieriger mehrere Module gleichzeitig, oder einen sehr oft hintereinander zu benutzen,
man muss die Echos (auch die reflektierten) abwarten.

chefin:
Sie benötigt 2 Signalwechsel, dein US-Modul bringt aber nur einen Signalwechsel.

Stimmt nicht, schau dir den Analyzer Output an.

Hier ist eine Grafik der Abläufe drin http://www.micropik.com/PDF/HCSR04.pdf.

Whandall:
Betrachte den Modul doch einfach als Black-Box.

Mit dem Trigger startest du (was auch immer) und die Länge des nächsten High-Pulses (auf Echo) liefert das Ergebnis.
Wieviele US-Impulse mit welcher Frequenz ausgegeben werden ist doch eher nebensächlich.

Sobald der Modul irgendetwas nach seinem Sendeversuch empfängt, beendet er den Puls.

Das macht es etwas schwieriger mehrere Module gleichzeitig, oder einen sehr oft hintereinander zu benutzen,
man muss die Echos (auch die reflektierten) abwarten.

Stimmt nicht, schau dir den Analyzer Output an.

Ich versteh nicht was nicht stimmen soll?

PulseIn braucht 2 Signalwechsel, den Positiven zum Starten und den negativen zum Stoppen.

Macht das US-Modul einen Highimpuls in der Länge von "Senden aus" bis "Echo empfangen"?

Dann allerding hätte ich den Echo-Impuls falsch verstanden, dachte der bringt einfach HIGH sobald er Echo empfangen hat. Da ich aber auch mit einer fertigen Lib arbeite die ich nicht weiter angeschaut habe, war mir das Timing eigentlich egal

chefin:
Ich versteh nicht was nicht stimmen soll?

Kein Problem...

chefin:
Sie benötigt 2 Signalwechsel, dein US-Modul bringt aber nur einen Signalwechsel.

Funktion und Sensor passen nicht zusammen. PulseIn misst vom ersten bis zum zweiten Wechsel des Zustandes. Du bekommst aber beim Start keinen Zustandswechsel des US-Moduls. ... Dir fehlt das Startsignal

Das ist falsch.
Funktion und Sensor passen sehr gut zusammen.
(wenn man mal von der Blockade absieht)

chefin:
Muss also im Ergebniss die Null abfragen und als Fehler auswerten.

Das ist richtig.

chefin:
PulseIn braucht 2 Signalwechsel, den Positiven zum Starten und den negativen zum Stoppen.

Und die hat es auch.

Hej Whandall

und was genau sind dei Signalwechsel? Ich steig da immer noch nicht durch.
Was löst High und was löst denn jetzt low aus? Anscheinend bin ich nicht der Einzige der Probleme hat das Ganze zu verstehen.

Nehme ich mir deine oder diese Grafik hier http://www.micropik.com/PDF/HCSR04.pdf, dann bleibt die Frage, was genau PulseIn nun misst. Ich schicke 8 US Signale auf den Weg und pausiere kurz danach. Wahrscheinlich ist es egal ob 8 verschickt werden oder nur 1, oder?

Echo registriert das zurückkommende Signal. Wann aber startet jetzt die eigentliche Messung und bei welchem der "8-Burst-Signale" endet es.

  1. Burst raus, kurz Pause, Echo zurückkommenden US und startet die Messung bis alle Signale eingetroffen sind. --> Problem: Die Signale treffen im gleichen Abstand ein, wie sie abgesendet wurden. Die Distanz würde bei diesem Fall keine Rolle spielen.
  2. Burst raus, kurz Pause, Zeitmessung startet bis Echo empfangen wird. --> Alle 8 Echos oder reicht bereits einer? Dann müsste man die Differenz für das Aussenden der Signale bei der Fehlerrechnung berücksichtigen.

Edit:

Whandall:
Dass ein Burst gesendet wird, verheimlicht dir der US-Modul.

Whandall:
Der Pin heisst Echo, er stellt nicht das Echo dar, sondern einen Puls in der Breite bis das Echo eintrifft.

Nach den beiden Zitaten von dir, ist es Fall 2. Der Pulse ist demnach die Zeit vom Aussenden bis Empfangen des Signals. An 2 Punkten rätsel ich nun noch.

  1. Das Senden des Bursts dauert bspw. 10us. Wird die Messung nach dem Empfang der 1us des Signals gestoppt oder nach dem kompletten Signal.
  2. Wenn ich vor dem PulseIn() einen Delay einbaue, der kleiner ist als die einfache Distanz, misst er immer noch korrekt. Da das wahrscheinlich unverständlich ist folgendes Zahlenbeispiel:

c = 340m/s, s = ca. 16cm --> t = 0,47ms bzw. 470us. (Hin und zurück wären also ca. 1ms)

400us Delay vor PulseIn --> Messung stimmt weiterhin
500us Delay vor PulseIn --> Rückgabe 0, also Messung nicht erfolgreich

Wie kann das sein? Also entweder die Messungen sollte erst fehlschlagen, wenn der Delay größer ist als die Strecke hin und zurück (1ms), da dann kein Ende der Messung detektiert werden kann oder die Messung müsste eine falsche Entfernung/Zeit liefern, egal welches Delay ich einstelle (ob 100us oder 400us etc.).

Edit²

  1. noch offen
  2. Anscheinend geklärt. Hier steht:

Das Modul sendet darauf nach ca. 250µs ein 40 kHz Burst-Signal für die Dauer von 200µs. Danach geht der
Ausgang (Echo, Pin 3) sofort auf H-Pegel und das Modul wartet auf den Empfang des Echos. Wird dieses
detektiert fällt der Ausgang auf L-Pegel.

Das erklärt das Phänomen. Wäre mir sicherlich schneller aufgefallen, wenn ich nicht vom Schreibtisch zur Wand (16cm) gemessen hätte und das exakt in dem gleichen Zeitraum liegt. Demnach unterbricht man anscheinend das Setzen des Echo-Pins auf High, wenn man länger als 450/500us Delay nach dem Trigger einbaut --> ergo Falschmessung.