Huhu, wieder mal eine Anfängerfrage aber das verwirrt mich leider
komplett.
Ich frage in meinem Code per "IF" einen Knopf ab. Direkt als erstes in
der "IF"-Abfrage kommt eine While-Schleife die etwas so lange ausführt
wie der Knopf gehalten wird.
Da das in meiner "größeren" Schaltung irgendwie nicht klappt habe ich
jetzt einen kleinen Beispielcode geschrieben der sich auf dieses Problem
fokusiert. Ich habe auf Serial.println() Befehle eingebaut dass ich am
Computer mit dem Serial Monitor das Problem nachvollziehen kann.
Und hier zeigt er eben auch an dass er erst in die "IF"-Abfrage springt
wenn ich den Knopf drücke, die While-Schleife allerdings komplett
überspringt und erst beim wohl nächsten Durchlauf der kompletten "loop"
Funktion meine While Schleife ausführt.
Meine Frage an die Profis ist nun: Warum?
Das ist mein kleines Testprogramm:
Die Meldungen Zeile 1 und 2 stammen vermutlich noch aus
der Zeit der Initialisierung wo der Pullup noch nicht
ausreichend wirkt (da sehr schwach).
Mach mal versuchshalber ein delay(500) am Ende von <void setup()>
Ich denke auch, dass es Tastenprellen sein könnte.
Die Ausgabe des ersten Serial.println() dauert so circa 20ms, manche
Schalter prellen so lange.
Ein delay(100) vor dem while könnte das verbessern.
- Tom
Pinkshell schrieb:> Ich denke auch, dass es Tastenprellen sein könnte.
Ein Prellen ist aber nicht reproduzierbar und würde jedes
Mal ein anderes Ergebnis bringen. Das wissen wir aber bisher
nicht.
mitlesa schrieb:> Die Meldungen Zeile 1 und 2 stammen vermutlich noch aus> der Zeit der Initialisierung wo der Pullup noch nicht> ausreichend wirkt (da sehr schwach).
Nun ja, der hat ca. 50kOhm, und ist so schnell an, so schnell kannst du
gar nicht gucken.
Wenn da natürlich ein paar Farad Kondensator am Knopf hängen, dann
wird’s tatsächlich etwas dauern.
@TO: zeig mal die Schaltung dazu.
Oliver
Oliver S. schrieb:> und ist so schnell an, so schnell kannst du gar nicht gucken.
Die Geschwindigkeit mit der ich schauen kann ist leider
nicht der Massstab für eine korrekte Funktion der Anordnung.
Kondenstatoren oder so habe ich nicht.
Arduino D12 <-> Taster <-> Masse
Arduino D5 <-> Vorwiderstand <-> LED <-> Masse
Also ganz einfach. War ja nur zum Testen wegen der While-Schleife.
Und die Serial Ausgabe habe ich immer gelöscht bevor ich es getestet
habe. Also da war auch nichts von der Initialisierung drin gehangen.
Aber vielen Dank an alle, das Problem ist gelöst.
Das Delay am Ende von der setup() Funktion hat irgendwie nichts
gebracht.
Aber das Delay eine Zeile über der While-Schleife hat funktioniert.
Jetzt sieht die Serial Ausgabe so aus wie gehofft.
(Wieder so wie vorher. Gelöscht und dann neu getestet)
Sandra D. schrieb:> Aber das Delay eine Zeile über der While-Schleife hat funktioniert.> Jetzt sieht die Serial Ausgabe so aus wie gehofft.
Gratuliere, du hast gerade am lebenden Objekt das Tastenprellen
nachgewiesen.
Mit dem Delay hast du das etwas entschärft, aber gut ist es deshalb noch
nicht. Denn ein Taster prellt auch beim Loslassen und wenn du
ausreichend viele Versuche machst, dann wirst du beobachten können, dass
beim Loslassen auch mal "Der Knopf wurde gedrückt" kommen wird.
Du müsstest eine ordentliche Tastenentprellung in SW implementieren,
z.B. derart, dass ein Tastenzustand z.B. viermal hintereinander im
Abstand von z.B 5ms den selben Wert haben muss, damit er als gültig
akzeptiert wird. Sowohl beim Drücken als auch beim Loslassen der Taste
ist das notwendig.
Einfachst kannst du auch nochmals ein Delay nach Verlassen der
while-Schleife einbringen.
Delays führen jedoch dazu, dass der Prozessor in der Zeit blockiert ist
und nichts anderes machen kann.
HildeK schrieb:> Denn ein Taster prellt auch beim Loslassen und wenn du> ausreichend viele Versuche machst, dann wirst du beobachten können, dass> beim Loslassen auch mal "Der Knopf wurde gedrückt" kommen wird.mitlesa schrieb:> Das wissen wir aber bisher nicht.
Will meinen der/die TO hätte dafür genauere Aussagen über den
Testvorgang abgeben müssen.
I am sorry aber das hier ist das falsche unter forum.
Projekte & code ist dafür da, fertige Projekte vorzustellen. Deine Frage
gehört eher in Mikrocontroller & Elektronik. Vielleicht kanns ein admin
ja verschieben.
Der ganze Ansatz wird Dir irgendwann auf die Füse fallen.
Wer es einfach und zuverlässig haben will, packt die Entprellung und
Flankenerkennung in einen Timerinterrupt. Dann braucht die Mainloop
nicht mehr CPU-Zeit mit Delays zu verplempern und die Tastenerkennung
wird nicht durch die Main Laufzeiten gestört.
Auch sieht die Mainloop viel aufgeräumter aus, d.h. man macht weniger
Fehler.
Peter D. schrieb:> Wer es einfach und zuverlässig haben will, packt die Entprellung und> Flankenerkennung in einen Timerinterrupt.
Grundsätzlich hast du recht.
Allerdings wird in der Arduino Welt da eher millis() für sowas
verwendet, denn der/ Timerinterrupt ist schon dafür belegt.
Bei mir sieht das dann so aus.
1
#include<CombiePin.h>
2
#include<CombieTimer.h>
3
#include<CombieTools.h>
4
5
usingTaster=Combie::Pin::InvInputPin<2>;// Taster gegen GND geschaltet
6
usingLed=Combie::Pin::OutputPin<13>;
7
8
Combie::Timer::EntprellTimerentprellen(20);// ms
9
Combie::Tools::ToggleSwitchflippflop;//
10
11
voidsetup()
12
{
13
Taster{}.initPullup();
14
Led{}.init();
15
}
16
17
voidloop()
18
{
19
Led{}=flippflop=entprellen=Taster{};
20
}
Wenn bedarf an den Libs besteht, rücke ich sie auch wohl raus, sollten
sich aber auch schon irgendwo hier im Forum finden lassen.
Für die Zeiten wird das im Arduino Beispiel "BlinkWithoutWelay"
vorgestellte Prinzip verwendet.
EAF schrieb:> Wenn bedarf an den Libs besteht
Ja, für jeden Mini-Scheiss sein eigenes System mit einer extra
Lib zukleistern statt sich selbst mal bemühen und eine kompakte
Lösung anpeilen.
mitlesa schrieb:> statt sich selbst mal bemühen
Meinst du mich damit?
Dann muss ich dich enttäuschen!
Das ist mein Kram. Meine Mühe.
mitlesa schrieb:> und eine kompakte Lösung anpeilen.
Ist sie.
Jeder Handwerker wird es kennen, den Gedanken:
> Wenn du irgendwas zum drittem mal tust, dann baue eine Schablone.
Und in der Arduino Welt sind das eben Libraries.
Es tut eben keine Not das Rad zum tausendsten mal neu zu erfinden. Erst
recht nicht wenn es schon ein passendes rundes gibt.
mitlesa schrieb:> Die Meldungen Zeile 1 und 2 stammen vermutlich noch aus> der Zeit der Initialisierung wo der Pullup noch nicht> ausreichend wirkt (da sehr schwach).
Das ist ein Ammenmärchen.
Wenn da keine meterlange Leitung am Pin hängt, dann "wirkt" der Pullup
sofort.
Denn nehmen wir einfach mal an, auf der Platine wären insgesamt 100pF
als parasitäre Leitungskapazität (ja, ich weiß, dass es viel weniger
ist...).
Und dann gehen wir von 50k Ohm Pullup aus (ja, ich weiß, dass es weniger
ist...), dann haben wir eine Zeitkonstante von t = 100E-12*50k = 5us.
Nach dieser Zeit erkennt der Eingang bei nicht betätigtem Taster sicher
"high".
Das, was zwischen pinMode(Knopf, INPUT_PULLUP); und der Tasterabfrage
kommt, dauert garantiert diese 5us (die zudem den absoluten Worst-Case
darstellen).
EAF schrieb:> Meinst du mich damit?
Nein, sondern den User der sich angesprochen fühlt.
EAF schrieb:> Ist sie.
Kompakte Lösung ist es wenn ein paar wenige Zeilen im eigennen
Programm reichen.
Deine "kompakte Lösung" ist es eine Library zu verwenden die
(vermutlich) noch eine Menge anderes Zeugs anbietet und damit
das eigene System zukleistert. Ausserdem wird der/die Anfänger(in)
nicht sinnvoll (wissend was das macht) damit umgehen können.
Also reines C&P-verhalten ohne Denk-/Verständnismöglichkeit.
mitlesa schrieb:> die> (vermutlich) noch eine Menge anderes Zeugs anbietet und damit> das eigene System zukleistert.
Es ist nur das interessant, was wirklich in den Code kompiliert wird.
Das "kleistern" existiert nur in deiner Fantasie