Zu Aufgabe von Tag 6: UDP Button Erweiterung
› Foren › Adventskalender › Zu Aufgabe von Tag 6: UDP Button Erweiterung
Schlagwörter: UDP Button
- Dieses Thema hat 4 Antworten und 2 Teilnehmer, und wurde zuletzt aktualisiert vor 9 Jahren von Raabinator.
-
AutorBeiträge
-
Dezember 10, 2015 um 02:10 Uhr #760StefanieMitglied
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
Dezember 10, 2015 um 09:26 Uhr #761RaabinatorMitgliedHallo 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.
Dezember 10, 2015 um 09:30 Uhr #762RaabinatorMitgliedNoch 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.Dezember 11, 2015 um 00:16 Uhr #790StefanieMitgliedVielen 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) }
Dezember 11, 2015 um 07:47 Uhr #791RaabinatorMitgliedHallo 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 ... }
- Diese Antwort wurde geändert vor 9 Jahren von Raabinator.
-
AutorBeiträge
- Du musst angemeldet sein, um auf dieses Thema antworten zu können.