Zu Aufgabe von Tag 6: UDP Button Erweiterung
› Forums › (Deutsch) Adventskalender › Zu Aufgabe von Tag 6: UDP Button Erweiterung
Tagged: UDP Button
- This topic has 4 replies, 2 voices, and was last updated 9 years ago by Raabinator.
-
AuthorPosts
-
December 10, 2015 at 02:10 #760StefanieMember
Hallo liebe alle,
Derzeit lässt sich die Led mittels Button ein und ausschalten. Je nachdem welcher Zustand LOW oder HIGH gewählt wurde. Habt ihr eine Idee, ich glaube ich habe schon irgendwo einmal was hier gelesen, dass man den Wert des Buttons über eine andere Variable zwischen speichert. Wie würdet Ihr das umsetzen?
Anbei simple Status Quo:
int led = 9;
int schalter = 5;void setup() {
pinMode(led,OUTPUT);
pinMode(schalter, INPUT);
digitalWrite(schalter, HIGH);
}void loop() {
digitalWrite(led,!digitalRead(schalter));}
LG
December 10, 2015 at 09:26 #761RaabinatorMemberHallo Stefanie.
Ich nehme an, du möchtest nur auf eine Zustandsänderung des Buttons reagieren. Momentan wird in jedem Durchlauf von
loop()
nur der aktuelle Zustand an die LED übertragen.
Um auf diese Schaltflanken zu reagieren, musst du dir den letzten Zustand des Button zwischenspeichern und dann diesen immer mit dem aktuellen Zustand des Button vergleichen.
Zunächst erzeugst zu dir überSetup()
eine sogenannte globale Variable:
int buttonZuletzt;
Am Ende vonsetup()
initialisierst du diese Variable mit dem Zustand des Button:
buttonZuletzt = digitalRead(schalter);
In loop() vergleichst du nun immer den Zustand mit dem in der Variablen. Hat er sich geändert, dann reagierst du darauf. Aber nicht vergessen, den dann neuen Zustand wieder merken.loop() { if(buttonZuletzt != digitalRead(schalter)) { // Änderung hat stattgefunden if(buttonZuletzt) { // buttonZuletzt war <>0, also nicht gedrückt (low-aktiv) // muss dann jetzt gedrückt sein digitalWrite(led, 1); // LED ein Serial.println("gedrückt"); buttonZuletzt = 0; // merken, dass jetzt gedrückt } else { // buttonZuletzt war =0, also gedrückt (low-aktiv) // muss dann jetzt nicht gedrückt sein digitalWrite(led, 0); // LED aus Serial.println("losgelassen"); buttonZuletzt = 1; // merken, dass nicht mehr gedrückt } delay(30); // zum entprelen verzögern (einfache Version) } }
Das
delay(30)
am Ende benötigst du, um dem Button Zeit zu geben (30ms), seinen Kontakt vollständig zu öffnen oder zu schließen. Dein Controller ist nämlich so schnell, dass er ohne mehrere Zustandswechsel erkennen würde, obwohl der Button nur einmal betätigt wurde.Ich hoffe, damit ist dir etwas geholfen.
December 10, 2015 at 09:30 #762RaabinatorMemberNoch eins. In deiner setup() solltest du
pinMode(schalter, INPUT);
gegen
pinMode(schalter, INPUT_PULLUP);
ersetzten, wenn du nicht einen externen Pull-Up Widerstand verwendest.
Ansonsten bekommst du keinen definierten Zustand und der Schalter reagiert evtl. willkürlich.December 11, 2015 at 00:16 #790StefanieMemberVielen Dank Raabinator,
habe es aufbauend auf deiner Idee so gelöst:
int led = 9; int schalter = 5; int buttonZuletzt = 0; int led_an = 0; void setup() { pinMode(led,OUTPUT); pinMode(schalter, INPUT_PULLUP); digitalWrite(schalter, HIGH); } void loop() { if((buttonZuletzt == 0) && (!digitalRead(schalter) == 1)) // ueberpruefe ob schalter gerade rising edge hat (betätigt wurde). { if(led_an == 1) { led_an = 0; } // toggle led_an else { led_an = 1; } } buttonZuletzt = !digitalRead(schalter); // speichere alten schalterzustand digitalWrite(led,led_an); // setze led entsprechend delay(30); // zum entprellen verzögern (einfache version) }
December 11, 2015 at 07:47 #791RaabinatorMemberHallo Stefanie,
Du wolltest also die LED mit dem Taster bei Druck Ein-/Ausschalten. Hab ich wohl falsch verstanden.
Eine Variable “toggeln” geht auch einfacher:led_an = !led_an;
Das späte Speichern des Schalterzustandes birgt die Gefahr, dass sich der Zustand gerade zwischen deiner Abfrage und dem Speichern ändert. Dann bekommst du einen Tastendruck nicht mit.
Dasdelay()
am Ende in der Hauptschleife verzögert das gesamte Programm. Solange es nichts anderes machen soll ist das OK.
Besser ist es, sich nach der Tastenänderung die aktuelle Zeit zu merken (millis()
) und vor erneuter Taster-Prüfung nachzusehen, ob bereits genug Zeit vergangen ist.Beispiel:
unsigned long lastTime = 0L; // merkt sich die Zeit der letzten Änderung int buttonZuletzt = 0; // letzter Zustand des Tasters int led_an = 0; // Zustand der LED #define VERZOEGERUNG 30L loop() { // ... Mein übriges Programm, das gerne nicht verzögert wäre ... if((millis() - lastTime) >= VERZOEGERUNG) // Genügend Zeit seit der letzten Änderung vergangen? { // ... ja, Taste auf Änderung prüfen und reagieren int buttonJetzt = digitalRead(schalter); // einmal merken, ist sicherer if(buttonJetzt != buttonZuletzt) { // Zustand geändert buttonZuletzt = buttonJetzt; // neuen Zustand merken lastTime = millis(); // Zeit der Änderung merken // ... Reaktion auf die Änderung if(!buttonJetzt) { // Gedrückt! led_an = !led_an; // toggeln digitalWrite(led,led_an); // setze led entsprechend } } } // ... noch mehr Programm, das gerne nicht verzögert wäre ... }
- This reply was modified 9 years ago by Raabinator.
-
AuthorPosts
- You must be logged in to reply to this topic.