Hallo,
Ich habe mir zu Weihnachten einen Funduino Mega2560 geschenkt und mach jetzt meine ersten Versuche.
Die Idee war es die Eingaben an einem Taster zu zählen.
Die weiße LED soll dauerhaft leuchten. (funktioniert)
Die rote LED soll leuchten wenn der Taster gerückt ist. (funktioniert)
Die grüne LED soll leuchten wenn der Taster nicht gerückt ist. (funktioniert)
Die gelbe LED soll nach jedem 10mal Tasterdrücken leuchten. (Hier liegt das Problem)
Teilweise leuchtet die gelbe LED schon nach dem 8 oder neunten mal Tastendrücken.
Ich denke, dass sich der Funduino nicht verzählen wird und das Problem im Code liegt.
CODE:
int LEDweiss = 6;
int LEDrot = 5;
int LEDgruen = 4;
int LEDgelb = 3;
int taster = 7;
int zaehler = 0;
int myCode[3] = {1000, 2000, 1000};
int mySignal[sizeof(myCode)];
boolean tasterstatus = LOW;
unsigned long myTime = 0;
void setup()
{
pinMode(LEDweiss, OUTPUT);
pinMode(LEDrot, OUTPUT);
pinMode(LEDgruen, OUTPUT);
pinMode(LEDgelb, OUTPUT);
pinMode(taster, INPUT);
}
void loop()
{
digitalWrite(LEDweiss, HIGH);
//digitalWrite(LEDgelb, LOW);
tasterstatus = digitalRead(taster);
delay(25);
switch (tasterstatus)
{
case HIGH:
zaehler++;
delay(25);
while (tasterstatus == HIGH)
{
digitalWrite(LEDrot, HIGH);
digitalWrite(LEDgruen, LOW);
tasterstatus = digitalRead(taster);
}
break;
case LOW:
delay(25);
while (tasterstatus == LOW)
{
digitalWrite(LEDgruen, HIGH);
digitalWrite(LEDrot, LOW);
tasterstatus = digitalRead(taster);
}
break;
}
if (zaehler == 10)
{
digitalWrite(LEDgelb, HIGH);
zaehler = 0;
}
else
{
digitalWrite(LEDgelb, LOW);
}
}
Taster "prellen" beim drücken. "Prellen" bedeutet, das er ganz schnell Kontakt bzw. keinen Kontakt hat. Der µC ist so schnell, das er dieses prellen erkennt. Und erkennt durch dein vermeintlichen einmal drücken, mehrere Tastvorgänge.
Du kannst dies verhindern, das du die Abfrage nach dem erstmaligen auslösen, erst nach einer verstrichenen Zeit wieder auswertest.
Google einfach mal nach Taster entprellen, da gibt es massig Anleitungen dafür.
Edit: Bei dir im Sketch hast du ein delay(25); was das Taster Entprellen übernehmen soll. Erhöhe dies mal leicht, z.B. auf 50. Er sollte sich jetzt weniger oft verzählen. Aber du blockierst damit in jeden Loop Durchlauf deinen µC um genau diese Zeit, was später dir auf die Füße fallen wird.
Danke für eure schnellen antworten.
Ich hatte eigentlich versucht das Problem durch die Delays in der Abfrage zu beheben. ich werde mir wohl mal das Thema mit dem entprellen anschauen.
Eigentlich nicht.
Was Dir auf die Füsse fällt ist NICHT das prellen der Taste.
Dir fällt auf die Füsse, das Du die nicht schnell genug los lässt.
Ich habs mal für Dich durchkommentiert:
int LEDweiss = 6;
int LEDrot = 5;
int LEDgruen = 4;
int LEDgelb = 3;
int taster = 7;
int zaehler = 0;
int myCode[3] = {1000, 2000, 1000};
int mySignal[sizeof(myCode)];
boolean tasterstatus = LOW;
unsigned long myTime = 0;
void setup()
{
pinMode(LEDweiss, OUTPUT);
pinMode(LEDrot, OUTPUT);
pinMode(LEDgruen, OUTPUT);
pinMode(LEDgelb, OUTPUT);
pinMode(taster, INPUT);
}
void loop()
{
digitalWrite(LEDweiss, HIGH);
//digitalWrite(LEDgelb, LOW);
tasterstatus = digitalRead(taster); // lese den Status 8Hier ist zeile 26
delay(25); // warte
switch (tasterstatus) // verzweige anhand Status
{
case HIGH: // taste gedrückt?
zaehler++; // inkrement zaehler
delay(25); // warte erneut
while (tasterstatus == HIGH) // Schleife solange Status gesetzt
{
digitalWrite(LEDrot, HIGH);
digitalWrite(LEDgruen, LOW);
tasterstatus = digitalRead(taster); // lese den Status - und fang an von vorn...
}
break;
case LOW: // taste nicht gedrückt
delay(25); // pause
while (tasterstatus == LOW) // schleife solange Taste nicht gedrückt
{
digitalWrite(LEDgruen, HIGH);
digitalWrite(LEDrot, LOW);
tasterstatus = digitalRead(taster); // - aahhh hier wird die Taste gedrückt
// Ab hier fehlt es an einer Pausenzeit.
// ist die Taste gedrückt, geht es innerhalb microsekunde wieder nach oben
// in die Zeile 26
}
break;
}
if (zaehler == 10)
{
digitalWrite(LEDgelb, HIGH);
zaehler = 0;
}
else
{
digitalWrite(LEDgelb, LOW);
}
}
Und da ich oben angefangen habe, ist mir das aufgefallen:
Das wird Deine nächste Baustelle.
Nachdem Du Deine Werte, die sich nicht ändern, als const deklariert hast
Besser wäre es, den Taster im loop nur einmal abzufragen und eine Flankenerkennung einzubauen. Dann brauchst Du jedenfalls nur ein delay() (wenn man das mit dem Entprellen erstmal so lässt) und Du lernst, wie man eine Flankenerkennung macht. Das braucht man nämlich später sehr oft
Genaugesagt gefällt mir while nicht. Du blockierst den Sketch solange der Taster gedrückt ist und dann später solange er losgelassen ist.
Der richtige Ansatz ist Flankenerkennung. ( LOW zu HIGH -l bzw HIGH zu LOW Wechsel) EIn Flankenwechsel erfolgt bei Betätigen bzw loslassen des Tasters. Und in diesem Moment braucht es eine Entprellung (kurzes delay() oder mit millis() Dann kannst Du auch Aktionen starten wie zB den Zähler erhöhen.
Es könnte auch heissen, er soll erstmal blinkwithoutdelay nehmen oder alle anderen Beispiele durchspielen.
Erfolglos das Ding in die Ecke geschmissen frustriert mehr als ein delay...
Also erstmal nicht mal ne Handvoll LED's an/aus machen...
Ja, vielleicht auch nicht alles auf einmal. Zum Entprellen kann man erstmal ruhig bei dem delay() bleiben. Für die Flankenerkennung muss man an deinem Sketch gar nicht so viel ändern. Eher viel weglassen - vor allem die while-Schleifen
int LEDweiss = 6;
int LEDrot = 5;
int LEDgruen = 4;
int LEDgelb = 3;
int taster = 7;
int zaehler = 0;
int myCode[3] = {1000, 2000, 1000};
int mySignal[sizeof(myCode)];
boolean tasterstatus = LOW;
boolean lastTasterstatus = LOW;
unsigned long myTime = 0;
void setup()
{
pinMode(LEDweiss, OUTPUT);
pinMode(LEDrot, OUTPUT);
pinMode(LEDgruen, OUTPUT);
pinMode(LEDgelb, OUTPUT);
pinMode(taster, INPUT);
}
void loop()
{
digitalWrite(LEDweiss, HIGH);
//digitalWrite(LEDgelb, LOW);
tasterstatus = digitalRead(taster);
delay(25);
switch (tasterstatus)
{
case HIGH:
digitalWrite(LEDrot, HIGH);
digitalWrite(LEDgruen, LOW);
if ( lastTasterstatus == LOW ) {
if ( ++zaehler > 10 ) zaehler = 1;
}
break;
case LOW:
digitalWrite(LEDgruen, HIGH);
digitalWrite(LEDrot, LOW);
break;
}
lastTasterstatus = tasterstatus;
if (zaehler == 10)
{
digitalWrite(LEDgelb, HIGH);
}
else
{
digitalWrite(LEDgelb, LOW);
}
}