Also: Wenn man in sein Projekt ein oder mehrere Taster einbauen möchte muss man diese alle einlesen und entprellen.
Ich handhabe das mittlerweile so, dass ich in meiner loop() irgendwo eine Funktion habe, welche entprellt und bei falling edge signal eine variable auf true setzt.
Im restlichen Programm muss ich nur diese Variable abfragen und anschließend wieder auf low setzten. Damit bleibt mein Code leserlich.
So weit so gut.
Jetzt kam mir gerade aber ein gewaltiger Geistesblitz:
Statt für jeden Taster eine "lastDebounceTime" Variable zu nutzen lese ich jetzt die Taster nur alle paar Millisekunden ein, damit bekomme ich das Prellen nicht mit.
Also schnell programmiert und siehe da läuft wie Butter:
Serenifly:
Wenn es darum geht dass du duplizierten Code vermeidest heißt die Lösung "objektorientierte Programmierung"
"Objektorientierte Programmierung" aha, interessant, das habe ich ja schon getan.
Aber wie meinst du das mit der vermeidung von dupliziertem Code?
Mir ging es bei dem Sketch zum Teil darum um das immer gleiche "drumrum" wo anders hin zu verschieben. Wenn man einen Taster ausliest will man ja zu 90% immer nur eine Aktion machen wenn er gedrückt wurde.
Verzweifler:
Aber wie meinst du das mit der vermeidung von dupliziertem Code?
Weil du eventuell mehrere Taster auslesen willst. Dann verpackt man die Variablen und die Funktion in ein Objekt. Jeder Taster hat dann seine eigenen Daten. Ohne dass man mehr Code schreiben muss
Ouuu, das muss ich mir anschauen. Aber funktionieren tuts.
Zwecks millis() überlauf, ich habe immer meine Variante genommen, allerdings hab ich auch noch nie was so lange laufen lassen, dass das vorkam.
Was ich mich aber wunder:
unsigned long läuft bei 4.294.967.295 über.
wenn ich eine Variable aber bei 4.294.967.290 habe, also 5 ms davor,
und ich zähle 10 dazu habe ich doch 5
Oder nicht?
Ja. Genau deshalb ist die Addition da auch schlecht. Eine Substraktion passt dagegen, da das Ergebnis in den aller meisten Fällen größer als die Intervall-Zeit ist
Ich habe das millis-Problem mal an einem unsigned Char nachgebildet (ja, ich hätte auch byte nehmen können, ich wollte aber auf das unsigned hinweisen). Das dauert halt nicht so lange. Die erzwungenen Typecasts müssen sein, da der Compiler sonst in int rechnet.
Da kann man das gut sehen.
Richtig!
Wenn du addierst, hast du 2 Überläufe!
Der Millis Überlauf und der Überlauf bei der Addition.
Welche du beide kompensieren musst.
Das bedarf besonderer Aufmerksamkeit
Subtrahierst du, dann hast du nur einen Überlauf und einen Unterlauf, welche sich gegenseitig, ohne jeden Mehraufwand kompensieren.
Das geht automatisch und völlig schmerzfrei.
fakeMillis = (millis() / 50) % 256;
Dein fakeMillis kann Werte von 0 bis 255 annehmen.
nextX = fakeMillis + 50;
49 = 255 + 50
Ein Überlauf, wie es klarer und deutlicher nicht geht.
Ja klar, theoretisch und sonst auch soll er überlaufen.
Aber das passiert nicht, obwohl es überhaupt gar nicht sein kann. Unglaublich aber es ist so.
Wer das nicht glauben kann soll einfach kurz meinen Sketch kurz probieren und sich das im Seriellen Monitor ansehen. Erster Wert ist "fakeMillis" und der zweite das nicht überlaufende "nextX"
Verzweifler:
Also Code umschreiben und mal an OOP rantasten.
Auch wenn es schöne, fertige Bibliotheken dafür gibt, habe ich das mal basierend auf einer Vorlage von combie als Ausgangspunkt weiterer Überlegungen getan:
schön das du dir die Mühe machst agmue. Ich würde diese Ansammlung von Daten und Methoden in eine class stecken statt in struct. Ist zwar eigentlich egal und vielleicht auch eine Glaubensfrage, weil gleich, aber class ist standardmäßig privat, struct public. struct würde ich persönlich nur für Datensammlung verwenden die zusammengehören. Noch eine persönliche Meinung. Wer solche struct und class schreiben kann, der sollte es gleich in eine Lib "auslagern", sonst müllt man sich sich das Hauptprogramm mit Codezeilen zu was wiederum den Überblick trübt. Wie gesagt ist nur meine eigene Meinung.