"pulseIn()" bremst Ablauf genau so wie "delay()"

Hallo,

in einem meiner Projekte wird aufgrund der Abfrage eines Ultraschallsensors der Befehl "pulseIn()" verwendet.

Kann es sein, dass dieser Befehl den zeitlichen Ablauf ebenso negativ beeinflusst wie die Verwendung von "delay()"?

Mir kommt es so vor, dass der Ablauf so lange blockiert ist, bis eine Rückmeldung kam.

Dass man ein Timeout einstellen kann weiss ich, wie man das Blockieren des Ablaufs verhindert leider nicht.

Gruß Chris

http://torrentula.to.funpic.de/dokumentation/pulsein/

"...wenn der übergebene Wert HIGH ist, wird gewartet bis der Pin auf HIGH gezogen wird, startet einen Timer und wenn der Pin wieder auf LOW fällt, stoppt der Timer und die Pulslänge in Mikrosekunden (µs) wird zurückgegeben..."

Ist so, der blockt.

Siehe auch hier:

PulseIn (a blocking polling approach)
PulseIn is a function available with the Arduino that implements an approach know as 'poling'. It essentially sits around waiting for something to happen, until something happens the rest of your code is blocked. This is okay for a simple lab exercise to read and print values from a receiver but it is a hopeless approach for a real world application. Fortunately there are better approaches that do not require a major learning curve.

ja, pulsein() blockiert die Programmabarbeitung wie delay().
Grüße Uwe

Man kann aber dem pulseIn() einen Timeout-Wert übergeben.
Siehe auch http://arduino.cc/en/Reference/PulseIn
Allerdings muss man dann im Programm auch damit umgehen, das ggf. kein Wert gemessen wurde.

mkl0815:
Man kann aber dem pulseIn() einen Timeout-Wert übergeben.
Siehe auch http://arduino.cc/en/Reference/PulseIn
Allerdings muss man dann im Programm auch damit umgehen, das ggf. kein Wert gemessen wurde.

Wußte das Chris72622 nicht schon?
Grüße Uwe

Wenn du nicht warten willst, heisst die Funktion digitalRead :wink:

static boolean prevState;
boolean curState = digitalRead(pin);
if (curState != prevState ) {
   prevState = curState;
   if (curState) {
   //  a change LOW -> HIGH has happened
   // store micros
   } else  {
   //  a change HIGH ->LOW has happened
   // calculate micros() - stored_micros
   }
}

oder so ähnlich ...

pulseIn() macht nur Sinn, wenn du sowieso warten willst.

Edit: Ziemlich genau, wenn loop() schnell ist. Wenn es noch genauer sein soll, musst du Interrupts nehmen

Wenn das Programm nicht gestoppt werden soll, dann arbeite mit Interrupts.

Die Arduinos haben zwei oder mehr Anschlüsse.

Ein Interrupt unterbricht ein Programm während des Ablaufs kurz, um eine Aktion durchzuführen. Anschließend läuft das Programm weiter. Die Unterbrechnung durch die Interruptrotine dauert meistens nur wenige µs.

PulseIn und ein Interupt sind zwei verschiedene Paar Schuhe.
Oder hast du gemeint er soll den pulseIn Befehl in der Interupt-Routine starten?
Das ginge, wenn man genau wüsste, wie viele millis() der Aufruf der ISR dauert, damit man die eigentliche PulsIn-Messung korrigieren kann.

Um eine genaue Messung zu haben genügt das polling eines Eingangs nicht. Die mögliche Auflösung hängt vom restliche Kode ab, wie oft der zuläßt daß die Eingangskontrollfunktion durchlaufen wird.
Eine Lösung ist der Interrupt. Beim der Steigenden flanke wird die millis()oder micros() - Zeit zwischen gespeichert und bei der fallenden auch wieder und ein Statusbit gesetzt (damit die Interruptfunktion klein bleibt). In der loop Schleife wird bei gesetztem Statusbit die Differenzzeit berechnet und das Statusbit rückgesetzt.

Grüße Uwe