Liebe Community,
ich habe folgendes Problem:
ich habe an meinen Arduino einige LEDs angeschlossen, welche über die
PWM-Ausgänge eine bestimmte "Licht-Routine" durchlaufen, also in einer
bestimmten Reihenfolge ein- bzw. ausgedimmt werden.
Nun habe ich noch einen Taster an den Interrupt-Port angeschlossen, mit
welchem das "Lichtspiel" gestartet bzw. beendet werden soll. Dazu ändert
der Interrupt immer den Wert einer boolschen Variable.
In der Lichtspiel-Methode wird mittels mehrerer Schleifen immer das
Licht auf- bzw. abgedimmt. Als Schleifenbedingung habe ich mit
reingeschrieben, dass die boolsche Variable auf true gesetzt sein muss.
Also so:
for(blue = 0; blue <= 255 && play; blue++) {
// Boolsche Variable play == true, if lights should be on
analogWrite(bluePin, blue);
delay(del);
}
Diese Schleifen kommen nun mehrfach nacheinander für die einzelnen
Lichter. Am Ende folgt eine Abschaltung aller eventuell noch leuchtender
LEDs falls die play-Variable FALSE ist, das Lichtspiel also aus sein
soll.
Allerdings prellt der Taster (habe einen 22nF Kondensator als
Hardware-Entprellung angeschlossen) immer noch relativ häufig nach und
stellt somit die play-Variable z.B. auf FALSE (Schleife wird verlassen)
und gleich wieder auf TRUE (nächste Schleife wird sofort wieder
betreten, obwohl ja eigentlich das Lichtspiel ausgeschaltet werden
soll).
Ich habe auch schon versucht in der Interrupt-Methode einen delay
einzubauen, damit die Interrupt-Methode die gesamte Prelldauer
überdeckt. Jedoch habe ich das Gefühl, dass einfach während die
Interrupt-Methode ausgeführt wird, durch das Prellen sofort wieder ein
Interrupt ausgelöst wird, also der Delay keine Auswirkung hat.
Habt ihr einen Vorschlag für mich, wie ich das lösen kann? Bin absoluter
Anfänger.
Oder allgemeiner formuliert: Wie kann ich eine längere Routine (hier das
Lichtspiel) durch einen Tastendruck sofort unterbrechen (hier der
Interrupt) und bei erneutem Druck von vorne starten lassen.
Vielen lieben Dank,
Ein Anfänger
Hier hast Du eun Beispiel, wie es gemacht werden kann:
http://www.mino-elektronik.de/power_at90s/powerat90s.htm
Als Anfänger wirst Du es vermutlich nicht verstehen und alle Anderen
hier werden Dir sagen, das ist Murks, das darf man nicht.
Mach etwas daraus!
Hast du dir die Mühe gemacht a) die Suche zu verwenden und/oder b) mal
zu googeln? Das Thema ist hier schon im Detail behandelt worden und sehr
gut zusammengefasst in einem Artikel nachzulesen.
Eric B. schrieb:> http://www.mikrocontroller.net/articles/Entprellung
Eric hat dich schon auf den richtigen Weg gebracht.
Hättest du die Suche verwendet, hättest du diesen Thread (von vor 10
Tagen!) gefunden Beitrag "Tastenentprellen während externen Interrupt - ATmega16". Dort
hat jemand genau das selbe Problem (Taster am Interrupt entprellen).
Hilft vielleicht noch mehr zum Verstehen.
Nicht entmutigen lassen und dran bleiben :-)
Gruß Max
Ich habe jetzt versucht den Interrupt zu umgehen und einfach mittels
Timer und regelmäßige Polling einen Tastendruck zu erkennen. Allerdings
scheint dass ein Problem zu verursachen.
Ich bin folgendermaßen vorgegangen:
Der Timer löst alle 10ms eine Methode aus, welche guckt ob die Taste
gedrückt worden ist. Wenn das 5x hintereinander der Fall ist (also 50ms
lang) dann wird das als Tastendruck interpretiert und eine boolsche
Variable auf true gesetzt.
Ansonsten habe ich meine "Lichtspiel"-Methode identisch gelassen. Doch
leider funktioniert es immer noch nicht.
Hier ein vereinfachtes Code-Beispiel:
1
#include<TimerOne.h>
2
3
intredPin=9,bluePin=10,greenPin=11;// PWM-Pins für zu dimmende LEDs
if(!play){// Lichter ausschalten falls Ausschalten gedrückt wurde
61
analogWrite(redPin,0);
62
analogWrite(bluePin,0);
63
analogWrite(greenPin,0);
64
}
65
Serial.print("Play: ");// Debug info
66
Serial.println(play);
67
}
Meiner Ansicht nach müssten jetzt beim Start alle Lichter aus sein, da
play = false ist und somit alle Lichter aus bleiben. Mit dem ersten
Knopfdruck wird die Play-Variable auf true gesetzt und dadurch werden
die Schleifen durchlaufen. Somit sollten die Lichter nacheinander
eingedimmt und schließlich wieder ausgedimmt werden usw.
Bei erneutem Tastendruck, müsste play dann wieder auf false gesetzt
werden und damit die Schleifen alle nicht mehr betreten werden und die
Lichter ausgeschalten werden.
Leider passiert aber gar nichts davon. In der Realität beginnen die LEDs
sich stockend ein- und auszuschalten (nicht-fließender Übergang) und
manche Tastendrucke werden einfach, andere mehrfach registriert.
Außerdem kommt es zu diesen komischen Ereignissen:
// Debug info
Play: 0
Play: 0
Play: 0
PBay: 1 // play wird vor dem Änderungsbefehl schon auf true gesetzt!?
Before - Play: 1
After - Play: 0
Play: 0
Play: 0
Play: 0
Obwohl die Variable play sich nur in der buttonPolling()-Methode
verändern kann, scheint sie sich schon kurz vor dem play = !play zu
ändern und wird dann durch den eigentlichen Änderungsbefehl wieder
zurück auf den ursprünglichen Wert gesetzt, denn play vor dem Polling
hatte...
Ohne den Timer und das Polling funktioniert die LED-Abfolge aber
einwandfrei. Lichter werden langsam aus und wieder ein gedimmt.
Kann mir jemand weiterhelfen? Gerne auch mit einem komplett anderen Weg
dieses Problem zu lösen.
Verstehe einfach nicht woran das liegen könnte..
Vielen Dank schon mal im Voraus!
Was meinst du wohl, wie lange eine serielle Schnittstelle mit 9600 Baud
zum Senden eines einzelnen Zeichens brauchen könnte? Und wie viele
versendest du? Wie lange dauert also dieser kurze Interrupt (Interrupt =
Unterbrechung der "normalen" Arbeit!!!).
Für jede Hausfrau ist klar: wenn der Postbote klingelt und du
vertratscht dich mit dem für eine halbe Stunde an der Tür, dann ist es
kein Wunder, wenn die Milch überkocht...
Die Milch ist deine Hauptschleife, der Postbote die Unterbrechung.
Du solltest im Interrupt nur ein Flag setzen, und das in der
Haupschleife auswerten. Kann natürlich sein, dass du dann deine
Hauptschleife ein wenig umbauen musst...
BTW: bitte verwende die C-Tags um deinen Quelltext.
Das Entprellen ist nur die halbe Miete. Du mußt noch den Flankenwechsel
von losgelassen nach gedrückt erkennen.
Außerdem ist es zuverlässiger, auch das Loslassen zu entprellen, also
beide Flanken.