Pages: [1]   Go Down
Author Topic: "pulseIn()" bremst Ablauf genau so wie "delay()"  (Read 1108 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
God Member
*****
Karma: 11
Posts: 599
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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
Logged


Offline Offline
Newbie
*
Karma: 0
Posts: 32
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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:
http://rcarduino.blogspot.ch/2012/01/how-to-read-rc-receiver-with.html
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.
Logged

Forum Moderator
BZ (I)
Offline Offline
Brattain Member
*****
Karma: 271
Posts: 21887
+39 349 2158303
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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

Offline Offline
Edison Member
*
Karma: 21
Posts: 1419
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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.
Logged

Forum Moderator
BZ (I)
Offline Offline
Brattain Member
*****
Karma: 271
Posts: 21887
+39 349 2158303
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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
Logged

Germany
Offline Offline
Faraday Member
**
Karma: 59
Posts: 3072
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Wenn du nicht warten willst, heisst die Funktion digitalRead   smiley-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
« Last Edit: October 11, 2012, 04:44:13 pm by michael_x » Logged

Germany, Osnabrück
Offline Offline
God Member
*****
Karma: 30
Posts: 659
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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.
Logged

Offline Offline
Full Member
***
Karma: 2
Posts: 213
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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.
Logged

It's not my fault when my Posts are full of Errors. This stupid autocorrection from my browser is set up for german grammar.

Forum Moderator
BZ (I)
Offline Offline
Brattain Member
*****
Karma: 271
Posts: 21887
+39 349 2158303
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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
Logged

Pages: [1]   Go Up
Jump to: