Zeitmessung mit 2 Lichtschranken (pulseIn)

Hey,

HILFE
ich habe eine Frage bezüglich des Programmcodes zur Ermittlung einer Geschwindigkeit.
Die Zeit soll hierbei mit der Geschwindigkeit auf einem Monitor angezeigt werden.
Die Zeit soll zwischen zwei Lichtschranken gemessen werden mit pulseIn.
Ich komme nicht weiter mit der Messung der Zeit.
Wie benutze ich den Befehl pulseIn richtig?
Ich wäre Ihnen sehr dankbar wenn Sie mir helfen und mir eine kurze Erklärung dazu abgeben könnten.

Gruß

Dieter

Hier ist mein Anfang, es ist nicht viel:

#include <LiquidCrystal.h>

LiquidCrystal lcd(5, 4, 3, 2, 1, 0);

int Lichtunten=6;
int Lichtoben=7;
int geschwindigkeitmessen=0;
int Zeit=0;
int start=0;

void setup()
{
lcd.begin(16, 2);
pinMode(Lichtunten,INPUT);
pinMode(Lichtoben,INPUT);
}

void loop()
{
lcd.setCursor(0, 0);
lcd.print(“Geschwindigkeit:”);
lcd.setCursor(17, 1);
lcd.print(geschwindigkeitmessen);
geschwindigkeitmessen = (0,6/Zeit)*10^-6;

}

pulsein dürfte der falsche Ansatz sein, da blockierend.
Wenn die 1 Lichtschranke auslöst Zeit merken (millis() oder micros(), wenn die zweite Lichtschranke auslöst aktuelle Zeit - gemerkte Zeit.

Ps. setze deinen Sketch bitte in CodeTags (<>)

mir sind gerade noch ein paar Dinge aufgefallen

int Lichtunten=6; // besser const int verwenden int Lichtoben=7; //besser const int verwenden int geschwindigkeitmessen=0; //float wird warscheinlich besser funktionieren int Zeit=0;// drauf achten, dass die Zeit in ein int passt int start=0;// drauf achten, dass die Zeit in ein int passt

geschwindigkeitmessen = (0,6/Zeit)*10^-6;

Hier sind die meisten Fehler :wink:

float geschwindigkeitmessen = (Zeit != 0) ? (0.6/Zeit)*1e-6 : -1.0 ;

Die Sache mit (bedingung)[b] ? [/b](wert_bei_true)[b] : [/b](wert_bei_false) ;
könnte man natürlich auch in einem if erledigen, Hauptsache man teilt nicht durch 0

Dieter85:
Wie benutze ich den Befehl pulseIn richtig?
Ich wäre Ihnen sehr dankbar wenn Sie mir helfen und mir eine kurze Erklärung dazu abgeben könnten.

Die Arduino pulseIn-Funktion ist in dem skizzierten Anwendungsfall völlig unbrauchbar.

Die einzig sinnvolle Benutzung besteht darin pulseIn nicht zu benutzen!

Grund:

  • die pulseIn-Funktion blockiert den abgefragten Pin während der Abfrage
  • maximal kann daher eine einzige Lichtschranke abgefragt werden, aber das auch nur dann, wenn es im Sketch erwünscht ist, den Programmablauf standardmäßig sekundenweise zu blockieren und das Programm beim Funktionsaufruf anzuhalten

Korrekt wäre die Verwendung einer Logik für eine “Finite State Machine” (Zustandsautomat) mit verschiedenen Zuständen wie:

  • Bereit zur Zeitmessung, Uhr steht auf 0:00,000
  • Statusänderung an der Start-Lichtschranke: Zeitmessung startet und läuft ab jetzt
  • Statusänderung an der Stopp-Lichtsc hranke: Zeitmessung stoppt und zeigt die Endzeit

pulseIn() ist eine reine Bullshit- und Debug-Funktion die für sämtliche RealWorld-Anwendungen strikt zu meiden ist.

Die Arduino-Core-Library enthält viele solche Bullshit- und Debug-Funktion, die für das Debugging von Single-Tasks praktisch sein können, z.B.“delay()” oder “pulseIn()”, die aber bei Verwendung in "richtigen Programmen dazu führen, dass die Programmlogik bereits vom Ansatz her gar nicht funktionieren kann.

Da es nur um 1 Geschwindigkeitsmessung geht, und keine Anforderung sichtbar ist, während der Messung noch was anderes zu machen, wäre pulseIn hier durchaus verwendbar.

Der Sinn der Arduino-Umgebung ist, einfache Sachen noch einfacher zu machen (was einen bei komplexeren Anforderungen dann eher behindert :wink: )

ardubu:
Wenn die 1 Lichtschranke auslöst Zeit merken (millis() oder micros(), wenn die zweite Lichtschranke auslöst aktuelle Zeit - gemerkte Zeit.

Ps. setze deinen Sketch bitte in CodeTags (<>)

Das sollte allerdings einfacher zu realisieren sein als die Verwendung der “bullshit” - Funktion pulseIn. :wink:

michael_x: Da es nur um 1 Geschwindigkeitsmessung geht, und keine Anforderung sichtbar ist, während der Messung noch was anderes zu machen, wäre pulseIn hier durchaus verwendbar.

Ich kann die Pins von zwei Lichtschranken sehen, stehen ja oben und die Anforderung ist für mich völlig klar.

int Lichtunten=6;
int Lichtoben=7;
void setup() 
{
...
  pinMode(Lichtunten,INPUT);
  pinMode(Lichtoben,INPUT);
}

Die Anforderung scheint ganz offensichtlich zu sein, die Dauer zwischen dem Auslösen der Start-Lichtschranke und dem Auslösen der Stopp-Lichtschranke zu messen.

Da pulseIn() nur einen Impuls an einem einzigen Pin messen kann, kommt diese Funktion dafür schon alleine deshalb nicht in Frage, weil tatsächlich an zwi Pins die Dauer von zwei State-Changes gemessen werden soll, das kann pulseIn() so nicht mal testweise zu Debug-Zwecken leisten. Es wird eine andere Programm-Logik as "Finite State Machine" benötigt, und auf eine StateChange-Detection ändert sich der Zustand zwischen: - Stoppuhr steht bei 0:00,000 - Stoppuhr läuft - Stoppuhr bleibt bei der Endzeit stehen

Falls der TO mal ein State-Change-Detection Beispiel durcharbeiten möchte, die IDE bringt ein Beispielprogramm dafür mit, einfach vom IDE-Hauptmenü aus aufrufen: Datei - Beispiele - 02.Digital - StateChangeDetection

Wenn er das doppelt für beide Lichtschranken realisiert, sollte er einwandfreie Start-/Stoppsignale bekommen, zu denen er sich dann ggf. nur noch den Stand des millis() Zählers merken braucht und die Differenz ist die gestoppte Zeit.

Ich stimme euch beiden ja zu, ohne pulseIn sollte es einfacher gehen.

Ohne die Hardware ist es auch sinnlos, ins Blaue ein pulseIn Beispiel zu schreiben, nur um zu zeigen, dass es gehen würde, für die zweite Lichtschranke blödsinnigerweise pulseIn zu verwenden.

Hallo,

Einfach mit millis ? Start (LS1) = current millis Stop (LS2) = current millis Wegzeit = Stop-Start (umrechnen auf den gewünschten Anzeigenwert ).

mfg Martin