Hallo, Ich bin ein Microkontroller Neuling ^^ und verzweifle gerade etwas. Suche schon seit ein paar Stunden, aber so richtig will mein Programm nicht funktionieren. Ich möchte mit einem Taster zwei blinkende LEDs Ein- und Ausschalten lassen. Nur leider hängt er immer in der Schleife fest! Wäre nett wenn ihr mir helfen könntet ;) int LED1=7; int LED2=8; int Taster1=5; boolean Tasterstatus1=LOW; int Taster2=6; int Tasterstatus2=LOW; int freq=0; boolean merker1=LOW; void setup () { pinMode(LED1, OUTPUT); pinMode(Taster1, INPUT); } void loop () { Tasterstatus1=digitalRead(Taster1); if (Tasterstatus1!=merker1) { if (Tasterstatus1==HIGH) { merker1=!merker1; delay(300); } if (merker1==HIGH) { digitalWrite(LED1,HIGH); delay(1000); digitalWrite(LED1,LOW); digitalWrite(LED2,HIGH); delay(1000); digitalWrite(LED2,LOW); } } } Ich möchte erst einmal nicht entprellen oder sonst etwas ^^ das programm soll nur Funktionieren
Ich verstehe nicht genau, was du erreichen möchtest, aber das "Hängen" kommt wohl von deinem merker1. Den änderst du an einer Stelle, die nur aufgerufen wird, wenn Tasterstatus1==HIGH UND merker1 != Tasterstatus ist. Also: Änderung nur, wenn merker LOW und Taster HIGH. Also schaltest du den merker einmal auf High, und dann nie wieder. Tipp: Schau dir das BlinkWithoutDelay - Beispiel an. und gib deinen Variablen schönere Namen als merker1 - zum Beispiel letzterTasterstatus.
Scuruba schrieb: > if (Tasterstatus1!=merker1) > { > if (Tasterstatus1==HIGH) > { > merker1=!merker1; Dein Merker ändert sich nur ein einziges mal, und danach nie wieder. > Ich möchte erst einmal nicht entprellen oder sonst etwas ^^ das programm > soll nur Funktionieren Mechanische Taster musst Du immer entprellen, sonst funktionieren sie nicht. Im Zweifelsfall setze ein kurzes delay(5); an das Ende der loop-Funktion. Weiterhin müßtest Du bei "interaktiven Programmen", die "blitzschnell auf Benutzereingaben reagieren" sollen, darauf achten, dass Du "delay()" und jede Art von "Busy Waitung" in Deinem Programm vermeiden müßtest. Probiere mal:
1 | int LED1=7; |
2 | int LED2=8; |
3 | int Taster1=5; |
4 | |
5 | void setup() { |
6 | pinMode(Taster1, INPUT); |
7 | pinMode(LED1, OUTPUT); |
8 | pinMode(LED2, OUTPUT); |
9 | } |
10 | |
11 | |
12 | boolean lastButtonState; |
13 | boolean blinkState; |
14 | void loop() { |
15 | boolean buttonState = digitalRead(Taster1); |
16 | if (buttonState!=lastButtonState && buttonState==HIGH) blinkState=!blinkState; |
17 | lastButtonState=buttonState; |
18 | if (blinkState) |
19 | { |
20 | digitalWrite(LED1,(millis()/1000)%2); |
21 | digitalWrite(LED2,(millis()/1000)%2); |
22 | } |
23 | else |
24 | { |
25 | digitalWrite(LED1,LOW); |
26 | digitalWrite(LED2,LOW); |
27 | } |
28 | delay(5); |
29 | } |
Denn wenn Du in einem Programm zweimal nacheinander delay(1000); machst, ohne dass die Eingabetaste gedrückt wird, kannst Du ja unter Umständen bis zu zwei Sekunden lang auf den Taster drücken "ohne dass etwas passiert". Und wenn Du den Taster während eines dalay-Aufrufst drückst und wieder losläßt, reagiert Dein Programm überhaupt nicht auf den Tastendruck, weil es ihn verpasst hat. Im übrigen: Hast Du beim Basteln eigentlich viel Spass am Verdrahten von PullDown-Widerständen an Tastern? Falls nicht: Die Atmega-Controller haben auch eingebaute PullUp-Widerstände, die Du aktivieren könntest, dann reicht ein Taster und es wird kein externer Pull-Widerstand in der Schaltung benötigt. Nur die Schaltlogik vertauscht sich dann, also ein unbetätiger Taster gibt dann HIGH und ein gedrückter Taster LOW.
Danke erst einmal Jürgen für deine schnelle Hilfe! > if (blinkState) > { > digitalWrite(LED1,(millis()/1000)%2); > digitalWrite(LED2,(millis()/1000)%2); Ein bisschen hast du mich falsch verstanden ^^ Ich möchte die LEDs abwechselnd blinken lassen? Geht sowas auch mit millis oder muss ich dafür ein delay benutzen? Hab jetzt auch noch mal geschaut und so wie ich das sehe müsste ich damit ich die nachteile des delays nicht habe das ganze in einen Interrupt laufen lasen. > Im übrigen: Hast Du beim Basteln eigentlich viel Spass am Verdrahten von > PullDown-Widerständen an Tastern? Falls nicht: Die Atmega-Controller > haben auch eingebaute PullUp-Widerstände, die Du aktivieren könntest, > dann reicht ein Taster und es wird kein externer Pull-Widerstand in der > Schaltung benötigt. Nur die Schaltlogik vertauscht sich dann, also ein > unbetätiger Taster gibt dann HIGH und ein gedrückter Taster LOW. Pull Down Wiederstände hab ich eingebaut :) Habe einen Arduino MEGA Und hat jemand vielleicht einen guten Tipp wo ich mir die Grundlagen gut anschauen kann?
Scuruba schrieb: > Ich möchte mit einem Taster zwei blinkende LEDs Ein- und Ausschalten > lassen. Du könntest natürlich auch die Stromversorgung aus- und wieder einschalten...Im Endergebnis das gleich :-)
Ich habs jetzt so gelöst! Elegant ist es glaube ich nicht aber es funktioniert :D
1 | int LED1=7; |
2 | int LED2=8; |
3 | int Taster1=5; |
4 | boolean LEDstat1; |
5 | boolean LEDstat2=HIGH; |
6 | unsigned long previousMillis=0; |
7 | unsigned long interval = 1000; |
8 | |
9 | void setup() { |
10 | pinMode(Taster1, INPUT); |
11 | pinMode(LED1, OUTPUT); |
12 | pinMode(LED2, OUTPUT); |
13 | }
|
14 | |
15 | |
16 | boolean lastButtonState; |
17 | boolean blinkState; |
18 | void loop() { |
19 | boolean buttonState = digitalRead(Taster1); |
20 | if (buttonState!=lastButtonState && buttonState==HIGH) blinkState=!blinkState; |
21 | lastButtonState=buttonState; |
22 | if (blinkState) |
23 | {
|
24 | if (millis() - previousMillis > interval) |
25 | {
|
26 | previousMillis = millis(); // aktuelle Zeit abspeichern |
27 | LEDstat1 = !LEDstat1;// LED Zustand wecheln. |
28 | LEDstat2 = !LEDstat2; |
29 | digitalWrite(LED1, LEDstat1);// Wert auf den Ausgang schreiben |
30 | digitalWrite(LED2, LEDstat2); |
31 | }
|
32 | delay(5); |
33 | }
|
34 | else
|
35 | {
|
36 | digitalWrite(LED1,LOW); |
37 | digitalWrite(LED2,LOW); |
38 | }
|
39 | }
|
:
Bearbeitet durch User
Scuruba schrieb: > Ich habs jetzt so gelöst! > Elegant ist es glaube ich nicht Doch, das ist genau das, was man auf einem Arduino macht, wenn man zeitabhängige Dinge erldigt. Das hier
1 | ...
|
2 | if (millis() - previousMillis > interval) |
3 | {
|
4 | previousMillis = millis(); // aktuelle Zeit abspeichern |
5 | ...
|
ist genau die richtige Technik dazu.
Scuruba schrieb: > aber es funktioniert :D einzig der
1 | delay(5); |
gehört ganz ans Ende der loop(). Sein Zweck ist es, der Funktion loop() eine längere Dauer zu geben, im Beispiel mindestens 5 Millisekunden. Dies willst du deshalb so haben, weil die Sparvariante der Tastenerkennung (nicht abwertend gemeint) sensitiv darauf ist, dass sie nicht zu oft aufgerufen werden darf, weil sonst Tastenpreller durchkommen. Und das willst du immer haben, unabhängig davon, ob die LEDs blinken oder nicht. Also darf auch die für das Entprellen alles entscheidende Verzögerung nicht einfach unter den Tisch fallen. Die Dinge hier
1 | boolean buttonState = digitalRead(Taster1); |
2 | |
3 | if (buttonState != lastButtonState && buttonState == HIGH) |
4 | blinkState=!blinkState; |
5 | lastButtonState=buttonState; |
6 | |
7 | |
8 | ....
|
9 | |
10 | delay(5); |
11 | }
|
gehören zusammen. Man könnte auch den delay vorziehen, unmittelbar nach der Tastenerkennung oder davor, damit man nicht aus den Augen verliert, dass sie Teil desselben 'Verfahrens' sind.
1 | void loop() |
2 | {
|
3 | boolean buttonState = digitalRead(Taster1); |
4 | |
5 | delay(5); |
6 | if (buttonState != lastButtonState && buttonState == HIGH) |
7 | blinkState=!blinkState; |
8 | lastButtonState=buttonState; |
9 | |
10 | ....
|
11 | // blinkState auswerten und entsprechende Reaktionen einleiten
|
12 | ....
|
13 | }
|
Karl Heinz schrieb: > gehören zusammen. Man könnte auch den delay vorziehen .... man könnte natürlich die Tastenabfrage nach dem Vorbild der anderen Zeitsteuerung genauso auf eine Ausführung alle 10 oder 15 Millisekunden (*) umstellen und so den delay komplett loswerden. Und ich denke, das solltest du auch unbedingt tun. Denn delay ist selten die Lösung für ein Problem, oft aber die Ursache. Daher will man in einem Programm keine delay haben. Wie man sie loswird, die Technik mit dem Zeitvergleich, weißt du ja schon. Also ran ans Werk und auch diesen delay eliminiert! (*) Edit: Wobei die 10 bis 15 Millisekunden nicht in Stein gemeisselt sind. Selbst wenn du erstklassige Taster hast und dich nur darauf konzentrierst, den Taster so schnell du kannst zu drücken und wieder loszulassen, wirst du es kaum schaffen, diesen Vorgang in weniger als ein paar Hunderstel Sekunden hinzukriegen. Ein normale Benutzer, der nicht auf Geschwindigkeitsrekord aus ist, wird selbst wenn er seinem Gefühl nach schnell auf die Tasten drückt, selten in weniger als 1 Zehntel Sekunde die Taste drücken und wieder loslassen. D.h. die 15 Millisekunden sind insofern kein Beinbruch, als auch mit 100 Millisekunden die wenigsten Benutzer jemals von einer derart 'seltenen' Tastenabfrage etwas mitkriegen oder davon beeinträchtigt werden.
:
Bearbeitet durch User
Beitrag #7241219 wurde von einem Moderator gelöscht.
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.