Zähler zählt nicht zuverlässig

Hallo zusammen

Für die schule müssen wir ein kleines RC-Auto autonom fahren lassen mit einem Arduino Uno. Um die strecke korrekt zufahren, zähle ich die Radumdrehungen. Dafür verwende ich folgenden Hall-Sensor:

Mein Programm zählt wenn ich das Rad selber langsam drehe korrekt mit, wenn ich allerdings mein Auto fahren lassen, zählt es nicht mehr korrekt, bis gar nicht mehr.

Mein Zählerprogramm sieht folgendermaßen aus:

// read the pushbutton input pin:
buttonState = digitalRead(buttonPin);

// compare the buttonState to its previous state
if (buttonState != lastButtonState) {
// if the state has changed, increment the counter
if (buttonState == HIGH) {
// if the current state is HIGH then the button went from off to on:
Counter++;
Serial.println("on");
Serial.print("number of button pushes: ");
Serial.println(Counter);
}
// Delay a little bit to avoid bouncing
delay(50);

Ich habe das ganze im Voidloop mehrmals zur Sicherheit, dass es richtig zählt in jeder If Bedingung unten noch eingefügt. Nichts desto trotz zählt es nicht korrekt.

Hat jemand eine Idee wie ich das hin bekomme, dass der Zähler immer zählt auch während dem er in anderen If Bedingungen ist?

(deleted)

silas1:
Hat jemand eine Idee wie ich das hin bekomme, dass der Zähler immer zählt auch während dem er in anderen If Bedingungen ist?

Von was sprichst Du?
Zählen geht ggfls. mit Interrupts besser. Wie Du das machst, ist mir noch nicht ganz klar.
Hallsensoren bouncen nicht; bring mal den ganzen Code.

Peter-CAD-HST:
die Variable lastButtonState wird nach dem erfolgreichen Vergleich nicht neu gesetzt .

Das würd ich nicht mal sagen - der Code ist unvollständig - die Funktion ist so wie sie da oben dargestellt ist nicht abgeschlossen.

Das ist mein ganzes Programm

Programm_verbesserung_V2_nach_Test1.ino (14.9 KB)

Hallo Peter

Wie meinst du das mit dem neu setzen?

Wenn zu jedem Impuls eine Meldung auf Serial ausgegeben wird, dann bremst das die Zählerei ganz drastisch!

Das delay() bremst ebenfalls bzw. führt dazu, daß kurze Impulse (bei schneller Fahrt) nicht erkannt werden. Beim Hallsensor das delay() einfach weglassen.

silas1:
Das ist mein ganzes Programm

Hi,
ich hab mal kurz drüber gesehen, da sind handwerklich einige Veränderungen notwendig.
Mehrfach benutzt Du delay(1000) - Das ist eine ganze Sekunde!

Das geht nicht.
Du musst jederzeit das Fahrzeug stoppen, wenn sich da was in den Weg stellt. - Ja, ich weiss, das bei so einem Schulprojekt die Versuchsstrecke eigentlich ohne zufällige Barrikaden gebaut werden. Zumindest bei LEGO-League war es bisher so. :wink:

Trotzdem solltest Du das von Anfang an richtig machen - sonst macht das keinen Sinn. Und führt dann noch dazu, das Du Dir was angewöhnst, was Du ganz schwer los wirst.

Als erstes teile Deinen Sketch in einzelne Funktionen auf - nicht alles hintereinander im loop.
Dann beschreobe in den Kommentaren was da passieren soll.
Sowas hier: Serial.print ("back left"); // read the pushbutton input pin: ist was vollkommen sinnfreies.

Das da irgendwo ein button geöesen wird, gibt der Code her - was passiert da und warum? Schlußendlich ist ein guter Kommentar auch, wenn Du schreibst was Du (für ein Ergebnis, eine Aktion) erwartest.

In dem ganzen Code finde ich keine Angabe zu einem Hallsensor.
Es gibt wohl zwei Sensoren - da errate ich aber, das es sich um SR04 handelt.

Ich denke, wenn Du ausmistest, wird das schon funktionieren.
Gegenfrage: Mit welcher maximalen Umdrehungszahl pro Sekunde rechnest Du?

Hallo my_xy_projekt

Erstmals besten Dank für deine super Hilfe, ich werde mir das ganze zu herzen nehmen.
Das bezüglich der Sekunde, habe ich bisher so drin, weil mir die Kurve sonst nicht reicht. da die Strecke bereits vorgegeben ist. Aber mal sehen ob ich das auch anders machen kann.

Ich weiss nicht wie viel umdrehung in der sekunde ich rechnen soll, denn das grosse Problem ohne last hab ich so etwa 6-7 Radumdrehung in der sekunde und auf dem boden so etwa 3. Wieso meinst du?

Moin,

silas1:
Das bezüglich der Sekunde, habe ich bisher so drin, weil mir die Kurve sonst nicht reicht. da die Strecke bereits vorgegeben ist. Aber mal sehen ob ich das auch anders machen kann.

Für eine Sekunde eine Aktion zu machen und dann nicht mehr, ist nicht das Problem.
Was problematisch ist, ist das verharren an dieser Stelle und den Rest des Codes bis zum Ablauf dieser Zeit nicht weiter zu beachten.

Unter Datei - Beispiele - 01 Basic ist das Blnik-Beispiel. Das ist eigentlich genau das, was Du derzeit mit dem dela() machst.
Unter Datei - Beispiele - 02 Digital findest Du BlinkwithoutDelay. Und das ist das, was daraus werden soll.

Umd das genauer zu verdeutlichen, kanst Du im Setup jeweils ein Serial.begin(9600); setzen und im loop vor die letzte schliessende } eine Zeile einfügen:
Serial.print("Ausgabe ");

Beobachte, was während der leuchtenden LED passiert :wink:

Ich weiss nicht wie viel umdrehung in der sekunde ich rechnen soll, denn das grosse Problem ohne last hab ich so etwa 6-7 Radumdrehung in der sekunde und auf dem boden so etwa 3. Wieso meinst du?

Es kam mir darauf an, zu erfahren, welche Zeit denn bleibt um die Erkennung einer Umdrehung zu tätigen.
Bei 10 Ups sind das 1000/10=100ms für eine Umdrehung.
Das schafft der Arduino locker - aber nur ohne delays.
Sonst wäre es ggfls. erforderlich geworden mit interrupts zu arbeiten.

Wie ich schon anmerkte, wenn Du mit Hallsensoren arbeitest, braucht es kein debounce-delay, da ist das erste Sparpotential.

Und weil Du schon mit einem sehr umfangreichen Code gekommen bist, freue ich mich auf die Änderungen der Erläuterungen/Kommentare sowie die eine oder andere Verbesserung und dann schaun wa mal.
Das wird!