ich weiß nicht ganz, wie ich den Thread benennen soll, weil die ganze Sache recht banal klingt, aber ich stehe irgendwie auf dem Schlauch.
Ich möchte einen Drehschalter mit vier Schalterpositionen auslesen (keinen Eincoder), das klappt auch wie es soll. Für jede der Positionen soll eine LED beim Einschalten kurz aufblinken, allerdings abhängig von der Drehrichtung. Hier liegt auch mein Problem, denn in meinem Script blinken die LEDs zwar entsprechend auf, wenn ich die nächste Schalterstellung anwähle, aber eben auch beim "Abwählen" der Position.
So soll das Ganze eigentlich funktionieren:
Wechsel von Pos. 0 (aus) auf Pos 1 soll Blinkimpuls an ledPin 40 auslösen
Wechsel von Pos 1 auf Pos 2 soll Impuls an ledPin 41 auslösen
Wechsel von Pos 2 auf Pos 3 soll Impuls an ledPin 41 auslösen
Wechsel von Pos 3 auf Pos 2 soll Impuls an ledPin 41 auslösen
Wechsel von Pos 2 auf Pos 1 soll Impuls an ledPin 41 auslösen
Wechsel von Pos 1 auf Pos 0 (aus) soll Impuls an ledPin 40 auslösen
Ich befinde mich schon geistig in einer Endlosschleife - ist sicher relativ banal, aber ich bekomme einfach nicht den "Dreh" raus, im wahrsten Sinne des Wortes.
Mein Script hängt dran, für jeden Denkanstoß oder Verbesserungsvorschlag bin ich sehr dankbar
Hierbei habe ich jeden Eingang per 10kOhm Pullup gegen GND gezogen.
Ich glaube auch nicht, dass es am Schalter liegt, sondern eher an meinem Code, denn die Schaltzustände werden ja richtig erkannt.
Wenn du den Schalter drehst werden ja mehrere Kontakte nacheinander geschlossen. Es ist daher wahrscheinlich vernünftiger den letzten geschlossenen Kontakt abzuspeichern und nicht die Zustände für jeden Kontakt einzeln. Dann vergleichst du den aktuellen Kontakt mit dem vorherigem Kontakt. Das geht über einen Integer/Byte.
vielen Dank für deine Empfehlung! Ich hab das jetzt so umgesetzt wie ich denke und es funktioniert auch fast so wie es soll.
Lediglich ein Problem habe ich dabei, nämlich den Zustand, wenn "stateSwitch 1" auf LOW steht. Hierfür wird ja kein "currentContact"-Wert generiert, der ja eigentlich dann "0" sein soll. Ergo blinkt ledPin 40 nicht auf, wenn ich von 1 auf 0 schalte.
Über ein "else currentContact = 0;" am Ende der Schalterabfrage löse ich das ja nicht, denn sonst springt "currentContact" ja auch bei den anderen Schaltpositionen immer auf 0?!
Ich habe den aktuellen Code nochmal angehängt, wahrscheinlich entdeckt ihr da sofort meinen Denkfehler. Ich tue mich echt schwer damit.
machst. Dann kannst du doch unterscheiden ob die Schalterstellung noch auf "0" steht oder wieder zurück gedreht wurde auf "0".
Heinz, danke für die Antwort, die das Problem leider nicht löst, denn damit gebe ich dem "currentContact" ja nur einen anderen Wert. Die Blinkabfrage sucht aber nach einem Wert, der den Zustand AUS beschreibt, jedoch NUR von Schaltposition 1.
Scherheinz:
Oder du machst das ganze über Flankenauswertung, dann bräuchtest du auch weniger Vergleiche
Öhm, das übersteigt meine Fähigkeiten bei weitem. Da muss ich erst nochmal recherchieren.
VG Chris
Stimmt, allerdings blinkt dann auch ledPin 40, wenn von Pos 1 auf 2 geschaltet wird, weil ja auch in diesem Fall der currentContact von 1 auf 0 springt...
Genau da liegt mein Problem.
ja weil im Umschaltmoment alle Eingänge LOW sind. Der Kontakt 1 öffnet schon bevor Kontakt 2 geschlossen wird, also für einen kurzen Moment das gleiche wie AUS. Das müssen wir nur noch überbrückt bekommen.
Das könnte man z.b. über eine Zeit machen. Heißt dein currentContact wird erst gesetzt wenn ein Eingang eine Zeit lang belegt wurde.
Wie zeitkritisch ist denn deine Anwendung?
Wahrscheinlich nicht sehr zeitkritisch, hierbei ist die Zuverlässigkeit wichtiger als die Geschwindigkeit. Also kürzestens innerhalb einer Sekunde durch alle vier Positionen 0 - 3.
Das funktioniert leider auch nicht, es ändert sich nichts am Ablauf, weil ja der Schalterstate immer schon vor der Zeitabfrage auf AUS springt.
Ziemlich tricky, das Ganze.
Wie schon gesagt, frage nicht die Zustände der Kontakte ab, sondern die Flanken. Und auch nur die Einschalt-Flanke und nicht die Ausschalt-Flanke. Dann hast du genau ein Ereignis für jeden Kontakt-Wechsel.
Jedenfalls wenn man das Prellen mal ignoriert. Die Kontakte müssten dann entprellt werden. Das kann man aber auch mit der Bounce Library erschlagen. Die macht auch die Flankenerkennung für dich. Ist zwar eigentlich für Taster gedacht, aber ich denke das sollte auch für Schalter funktionieren.
Das mit der Flankenauswertung hat geklappt, jetzt funktioniert es auf dem Breadboard. Nun muss ich noch das Entprellen umsetzen.
Mein Fehler mit dem Drehschalter-Link, den habe ich auf die Schnelle rausgesucht. Er hat trotzdem keinen separaten AUS-Anschluss, sonst wäre es in der Tat viel leichter gewesen.
Zum Entprellen:
Geht auch einfach Hardwaremässig.
Nimm einen 10K Ohm Pullup und schalte parallel dazu einen 100nf.
Das braucht du halt dann für jeden Schalter.
Funktioniert bei mir absolut zuverlässig.
Ansonsten wie schon angesprochen via Software Bounce Lib.