INFO: Dieses Forum nutzt Cookies...
Cookies sind für den Betrieb des Forums unverzichtbar. Mit der Nutzung des Forums erklärst Du dich damit einverstanden, dass wir Cookies verwenden.

Es wird in jedem Fall ein Cookie gesetzt um diesen Hinweis nicht mehr zu erhalten. Desweiteren setzen wir Google Adsense und Google Analytics ein.

Antwort schreiben 
 
Themabewertung:
  • 0 Bewertungen - 0 im Durchschnitt
  • 1
  • 2
  • 3
  • 4
  • 5
Leds blinken lassen mit if-Abfrage und millis
21.10.2015, 12:18 (Dieser Beitrag wurde zuletzt bearbeitet: 21.10.2015 13:55 von ferdi.)
Beitrag #1
Leds blinken lassen mit if-Abfrage und millis
Hallo liebe Arduino-Gemeinde,

ich beschäftige mich erst seit kurzem mit dem Arduino, habe mir aber schon relativ viel im Internet zusammen gesucht und auch teilweise selbst zusammengereimt(zumindest Bon ich dieser Meinung). Allerdings bin ich gerade an einem Punkt an dem ich das was ich will nicht so hinkriege. Ich hoffe ihr könnt mir ein bisschen weiterhelfen und noch die ein oder andere Frage beantworten.

Also folgende Ausgangslage für mein Projekt "Midi-Controller":

Ich habe einen Mega2560 an dem momentan 4Taster (an digitalPin 2,3,4 & 5) und 4Leds (an digitalPin 26,27,28 & 29) angeschlossen sind.

und das soll passieren:

jeder Taster soll einen MIDI-NoteOn bzw. MIDI-NoteOff Befehl für eine bestimmte Note erzeugen.
Zusätzlich soll die zugehörige Led zu jedem Taster (also Led1 bei betätigen des Taster1, usw) für eine bestimmte (im Sketch definierte Zeit) leuchten.
Außerdem darf immer nur eine Led leuchten. Wenn also Led1 gerade auf HIGH ist und beispielsweise Taster3 gedrückt wird muss Led1 auf LOW wechseln.
Und noch ein weiteres Kriterium: Die Zeit die eine Led leuchtet soll bei erneuter Tasterbetätigung wieder bei 0 anfangen (also wenn die Zeit für Led1 auf 5Sekunden eingestellt ist, bereits leuchtet und beispielsweise nach 3Sekunden Taster1 erneut gedrückt wird soll es ab dem erneuten Tastendruck 5Sekunden dauern bis Led1 auf LOW wechselt).

Soweit so gut. Bis dahin habe ich alles selber hingekriegt.
Das ist der dazugehörige Sketch:

Code:
//Button1 + LED1
int Button1 = LOW;
int Button1Alt = LOW;
int Led1 = 26;

//Button2 + Led2
int Button2 = LOW;
int Button2Alt = LOW;
int Led2 = 27;

//Button3 + Led3
int Button3 = LOW;
int Button3Alt = LOW;
int Led3 = 28;

//Button4 + Led4
int Button4 = LOW;
int Button4Alt = LOW;
int Led4 = 29;



unsigned long previousMillisLed1 = 0;
unsigned long previousMillisLed2 = 0;
unsigned long previousMillisLed3 = 0;
unsigned long previousMillisLed4 = 0;
unsigned long ZeitLed1 = 1000;
unsigned long ZeitLed2 = 2000;
unsigned long ZeitLed3 = 5000;
unsigned long ZeitLed4 = 10000;




void setup()
{
  Serial.begin(9600);
  pinMode(2, INPUT);  //Button1
  pinMode(Led1, OUTPUT); //Led1
  pinMode(3, INPUT);  //Button2
  pinMode(Led2, OUTPUT); //Led2
  pinMode(4, INPUT);  //Button3
  pinMode(Led3, OUTPUT); //Led3
  pinMode(5, INPUT);  //Button4
  pinMode(Led4, OUTPUT); //Led4
}

void loop()
{
  Button1 = digitalRead(2);
  delay(10);

  if (Button1 == HIGH && Button1Alt == LOW)
  {
    MIDIsenden(144,36,127);
    StatusLeds(HIGH, LOW, LOW, LOW);
    Button1Alt = Button1;
  }
  if (millis()-previousMillisLed1 > ZeitLed1)
  {
    previousMillisLed1 = millis();
    digitalWrite(Led1, LOW);
    Button1Alt = Button1;
  }
  if (Button1 == LOW && Button1Alt == HIGH)
  {
    MIDIsenden(144,36,0);
    previousMillisLed1 = millis();
    Button1Alt = Button1;
  }


  Button2 = digitalRead(3);
  delay(10);

  if (Button2 == HIGH && Button2Alt == LOW)
  {
    MIDIsenden(144,38,127);
    StatusLeds(LOW, HIGH, LOW, LOW);
    Button2Alt = Button2;
  }
  if (millis()-previousMillisLed2 > ZeitLed2)
    {
      digitalWrite(Led2, LOW);
      previousMillisLed2 = millis();
      Button2Alt = Button2;
    }
  if (Button2 == LOW && Button2Alt == HIGH)
  {
    MIDIsenden(144,38,0);
    previousMillisLed2 = millis();  
    Button2Alt = Button2;
  }


  Button3 = digitalRead(4);
  delay(10);

  if (Button3 == HIGH && Button3Alt == LOW)
  {
    MIDIsenden(144,40,127);
    StatusLeds(LOW, LOW, HIGH, LOW);
    Button3Alt = Button3;
  }
  if (millis()-previousMillisLed3 > ZeitLed3)
    {
      digitalWrite(Led3, LOW);
      previousMillisLed3 = millis();
      Button3Alt = Button3;
    }
  if (Button3 == LOW && Button3Alt == HIGH)
  {
    MIDIsenden(144,40,0);
    previousMillisLed3 = millis();
    Button3Alt = Button3;
  }


  Button4 = digitalRead(5);
  delay(10);

  if (Button4 == HIGH && Button4Alt == LOW)
  {
    MIDIsenden(144,42,127);
    StatusLeds(LOW, LOW, LOW, HIGH);
    Button4Alt = Button4;
  }
  if (millis()-previousMillisLed4 > ZeitLed4)
    {
      digitalWrite(Led4, LOW);
      previousMillisLed4 = millis();
      Button4Alt = Button4;
    }
  if (Button4 == LOW && Button4Alt == HIGH)
  {
    MIDIsenden(144,42,0);  
    previousMillisLed4 = millis();
    Button4Alt = Button4;
  }
}

void MIDIsenden(int statusByte, int dataByte1, int dataByte2)
{
  Serial.write(statusByte);  // NoteOn Kanal1
  Serial.write(dataByte1);  //  Note
  Serial.write(dataByte2);   // Anschlagsstärke
}

void StatusLeds(int statusLed1, int statusLed2, int statusLed3, int statusLed4)
{
  digitalWrite(Led1, statusLed1);
  digitalWrite(Led2, statusLed2);
  digitalWrite(Led3, statusLed3);
  digitalWrite(Led4, statusLed4);
}

So jetzt zu dem Teil an dem ich festsitze:
Ich möchte, dass nach Ablauf der voreingestellten Zeit, die eine Led leuchtet, die jeweilige Led noch für 10Sekunden blinkt (quasi als Warnhinweis dass die Led demnächst auf LOW geht).
Für mein Verständnis müsste ich also zwischen dem Teil

Code:
if (Button1 == HIGH && Button1Alt == LOW)
  {
    MIDIsenden(144,36,127);
    StatusLeds(HIGH, LOW, LOW, LOW);
    Button1Alt = Button1;
  }

und

Code:
if (millis()-previousMillisLed1 > ZeitLed1)
  {
    previousMillisLed1 = millis();
    digitalWrite(Led1, LOW);
    Button1Alt = Button1;
  }
  if (Button1 == LOW && Button1Alt == HIGH)
  {
    MIDIsenden(144,36,0);
    previousMillisLed1 = millis();
    Button1Alt = Button1;
  }

eine weitere if-Abfrage einfügen. Ich hab schon einiges ausprobiert (mit zusätzlichen unsigned longs etc.) aber habs nicht geschafft zum gewünschten Ergebnis zu kommen.
Entweder blinkt die Led dann permanent nach Ablauf der Zeit oder ist permanent an oder blinkt gar nicht….
Für den ein oder anderen Tipp wäre ich wirklich dankbar.

Frage2:
Ist es möglich den Code an manchen Stellen noch zu kürzen/zusammenzufassen?
Der ist ja jetzt schon relativ lang und bis jetzt sind nur 4Taster und 4Leds angeschlossen. Im fertigen Projekt sollen es dann jeweils 25 werden. Dazu kommen dann noch einige Fader und ich weis noch nicht was noch alles. Da dann den Überblick zu behalten wird wohl relativ schwer.

Frage3 zum entprellen der Taster:
Momentan löse ich das ja für jeden Taster über ein Delay von 10Millisekunden.
Ab und an kommt es aber vor, dass das ganze nicht einwandfrei funktioniert und eine Led nur kurz aufblitzt oder nicht die gewünschte Zeit leuchtet. Gibt es da eine andere bzw. bessere Möglichkeit?
Und was ist wenn ich dann mal wirklich 25Taster angeschlossen habe? dann summiert sich das Delay ja (oder?). Kann das dann zu Problemen führen?

Dann noch 2allgemeine Fragen:
- zum richtigen Widerstand bei Tastern: Wenn man sich diverse Anleitungen oder Tutorials anschaut heißt es mal man soll den Taster mit einem 1K Widerstand auf Ground legen, mal mit einem 10K. Was ist richtig und macht es überhaupt einen Unterschied?
- und noch zu den digitalen Ausgängen des Mega2560:
Soweit ich das verstanden habe sind die Pins 0,1,13 und 14 bis 21 mit festen Funktionen belegt. Heißt das ich kann diese Pins nicht frei verwenden und beispielsweise einen Taster anschließen?

So das waren jetzt wohl ziemlich viele Fragen und mir ist auch durchaus bewusst, dass mein Projekt für einen Einsteiger sehr hoch gegriffen ist. Aber man wächst ja bekanntlich an seinen Aufgaben ;-)

Ich hoffe ihr könnt und wollt mir die ein oder andere Frage beantworten.
Ich sag auf jeden Fall schonmal vielen Dank!!!!
Alle Beiträge dieses Benutzers finden
Diese Nachricht in einer Antwort zitieren
21.10.2015, 13:07
Beitrag #2
RE: Leds blinken lassen mit if-Abfrage und millis
Dadurch, dass du diesen Code einfach reinkopierst, ist das sehr unübersichtlich, da keine Formatierung vorhanden.

Bitte setze den Sketch in Code-Tags hier "formatiert" rein.

Was mir aber dennoch aufgefallen ist, du hast die Pins für deine Button1 bist Button4 nicht deklariert.

I2C = weniger ist mehr: weniger Kabel, mehr Probleme. Cool
Alle Beiträge dieses Benutzers finden
Diese Nachricht in einer Antwort zitieren
21.10.2015, 13:15 (Dieser Beitrag wurde zuletzt bearbeitet: 21.10.2015 13:53 von ferdi.)
Beitrag #3
RE: Leds blinken lassen mit if-Abfrage und millis
Code:
//Button1 + LED1
int Button1 = LOW;
int Button1Alt = LOW;
int Led1 = 26;
Alle Beiträge dieses Benutzers finden
Diese Nachricht in einer Antwort zitieren
21.10.2015, 13:17 (Dieser Beitrag wurde zuletzt bearbeitet: 21.10.2015 13:18 von hotsystems.)
Beitrag #4
RE: Leds blinken lassen mit if-Abfrage und millis
(21.10.2015 13:15)ferdi schrieb:  "int Button4 = LOW;
int Button4Alt = LOW;
int Led4 = 29;"

Diese (Button) hast du aber keinem Port/Pin zugewiesen.
Und ändere das bitte mit dem Code, so kann man das bei der Länge schlecht lesen.

I2C = weniger ist mehr: weniger Kabel, mehr Probleme. Cool
Alle Beiträge dieses Benutzers finden
Diese Nachricht in einer Antwort zitieren
21.10.2015, 13:20
Beitrag #5
RE: Leds blinken lassen mit if-Abfrage und millis
Sorry der letzte Beitrag war ein Versehen.
ich dachte der Code wird richtig angezeigt wenn ich ihn in < > setzte. Muss ich ihn in Anführungszeichen setzen? Habs noch nicht gecheckt ;-)

Sind die Pins für die Buttons nicht automatisch dadurch deklariert, dass ich im loop "Button1 = digitalRead(2)" "Button2 = digitalRead(3)" etc. stehen habe?
Alle Beiträge dieses Benutzers finden
Diese Nachricht in einer Antwort zitieren
21.10.2015, 13:36
Beitrag #6
RE: Leds blinken lassen mit if-Abfrage und millis
(21.10.2015 12:18)ferdi schrieb:  Ich hoffe ihr könnt mir ein bisschen weiterhelfen und noch die ein oder andere Frage beantworten.
Klar...

Zitat:Das ist der dazugehörige Sketch:
Könntest Du Coding in Zukunft in code-Tags setzen? Dazu das Coding in "[ code ]" und "[ /code ]" (ohne Blanks und Anführungszeichen) einschließen? Außerdem wäre eine gescheite Formatierung auch gut, also Einrückungen und so.

Zitat:So jetzt zu dem Teil an dem ich festsitze:
Ich möchte, dass nach Ablauf der voreingestellten Zeit, die eine Led leuchtet, die jeweilige Led noch für 10Sekunden blinkt (quasi als Warnhinweis dass die Led demnächst auf LOW geht).
Das könntest Du jetzt auch noch in Dein Spaghetticoding reinbasteln, aber dann wird's echt unübersichtlich. Vorher sollten wir erst einmal ein paar Grundlagen schaffen.

Zitat: Entweder blinkt die Led dann permanent nach Ablauf der Zeit oder ist permanent an oder blinkt gar nicht….
Für den ein oder anderen Tipp wäre ich wirklich dankbar.
Du brauchst sowas wie einen Zustands-Automaten. D.h. Du musst Dir für die aktive LED jeweils merken, in welchem Zustand sie ist und darauf entsprechend in einer "Handler"-Funktion reagieren. ...aber das kommt später.

Zitat:Ist es möglich den Code an manchen Stellen noch zu kürzen/zusammenzufassen?
Der ist ja jetzt schon relativ lang und bis jetzt sind nur 4Taster und 4Leds angeschlossen. Im fertigen Projekt sollen es dann jeweils 25 werden.
Dazu solltest Du Dich mal mit zwei Themen beschäftigen: Arrays und Funktionen: https://www.arduino.cc/en/Reference/Array und https://www.arduino.cc/en/Reference/FunctionDeclaration
Spiele damit mal ein bisschen rum. Mit den Arrays kannst Du die Anzahl der Tasten, LEDs etc. in den Griff bekommen und mit den Funktionen kannst Du Dein Coding strukturieren. Im Prinzip macht man immer dann eine Funktion, wenn man zweimal irgendwo fast dasselbe Coding stehen hat.

Code:
Momentan löse ich das ja für jeden Taster über ein Delay von 10Millisekunden.
Ab und an kommt es aber vor, dass das ganze nicht einwandfrei funktioniert und eine Led nur kurz aufblitzt oder nicht die gewünschte Zeit leuchtet. Gibt es da eine andere bzw. bessere Möglichkeit?
Delay zum Entprellen ist nicht sinnvoll. Ich frage mich immer wieder, wer das erfunden hat. Im Prinzip merkt man sich für jeden Taster die Zeit (millis) des letzten Tastendrucks. Immer dann, wenn ein Tastendruck (LOW-HIGH oder HIGH-LOW, je nachdem wie man den Taster angeschlossen hat) festgestellt wird, wird die Zeit neu gesetzt. Nur wenn seit dem letzten Tastendruck mindestens 50ms (oder so) vergangen sind, wird es als tatsächlicher Tastendruck prozessiert.

Zitat:Und was ist wenn ich dann mal wirklich 25Taster angeschlossen habe? dann summiert sich das Delay ja (oder?). Kann das dann zu Problemen führen?
Vergiss am besten, dass es delay gibt. Zumindest in Deinem Anwendungsfall sehe ich nicht, dass es irgendwo sinnvoll sein könnte.

Zitat:- zum richtigen Widerstand bei Tastern: Wenn man sich diverse Anleitungen oder Tutorials anschaut heißt es mal man soll den Taster mit einem 1K Widerstand auf Ground legen, mal mit einem 10K. Was ist richtig und macht es überhaupt einen Unterschied?
Vergiss diese Anleitungen. Für Taster am Arduino braucht man keine Widerstände. Schließe Taster grundsätzlich gegen Masse an. D.h. der Taster verbindet Masse mit dem Input-Pin. Dann wird am Pin mit pinMode(pin,INPUT_PULLUP) der interne Pullup-Widerstand eingeschaltet. D.h. normalerweise ist der Pin auf HIGH, wenn er gedrückt wird ist er LOW. Im Programm musst Du halt die Logik umdrehen. (Was als HIGH oder LOW bezeichnet wird ist eh willkürlich.)

Zitat:Soweit ich das verstanden habe sind die Pins 0,1,13 und 14 bis 21 mit festen Funktionen belegt. Heißt das ich kann diese Pins nicht frei verwenden und beispielsweise einen Taster anschließen?
Man kann schon, versuche es aber zu vermeiden. Speziell bei 0 und 1 kann es Probleme geben, da das auch die serielle Schnittstelle ist, über die Du Programme hochlädst und Dir ggf. eine Debug-Ausgabe erzeugst.

Gruß,
Thorsten

Falls ich mit einer Antwort helfen konnte, wuerde ich mich freuen, ein paar Fotos oder auch ein kleines Filmchen des zugehoerigen Projekts zu sehen.
Alle Beiträge dieses Benutzers finden
Diese Nachricht in einer Antwort zitieren
21.10.2015, 13:54
Beitrag #7
RE: Leds blinken lassen mit if-Abfrage und millis
(21.10.2015 13:20)ferdi schrieb:  Sind die Pins für die Buttons nicht automatisch dadurch deklariert, dass ich im loop "Button1 = digitalRead(2)" "Button2 = digitalRead(3)" etc. stehen habe?
Ja, sorry, das habe ich übersehen. Wenn du den Code richtig reinsetzt, so wie Thorsten beschrieben hat, wird er auch besser lesbar.

I2C = weniger ist mehr: weniger Kabel, mehr Probleme. Cool
Alle Beiträge dieses Benutzers finden
Diese Nachricht in einer Antwort zitieren
21.10.2015, 13:56
Beitrag #8
RE: Leds blinken lassen mit if-Abfrage und millis
Ok habs endlich überrissen. Also jetzt oben aktualisiert ;-)
Alle Beiträge dieses Benutzers finden
Diese Nachricht in einer Antwort zitieren
Antwort schreiben 


Möglicherweise verwandte Themen...
Thema: Verfasser Antworten: Ansichten: Letzter Beitrag
  Pulsierende LEDs KBLc 4 187 20.10.2016 22:35
Letzter Beitrag: hotsystems
  Problem mit Delay und Millis funnyzocker 1 459 26.06.2016 09:54
Letzter Beitrag: hotsystems
  tip für Qellcode nur 1mal ablaufen lassen himbeersirup 4 351 19.05.2016 11:51
Letzter Beitrag: himbeersirup
  Mehrere Abläufe gleichteitig mit "Millis" MarkusSpielt 3 669 11.04.2016 18:23
Letzter Beitrag: MarkusSpielt
  Programme lassen sich nicht auf das Gemma Board downloaden! Jack Sparrow 13 564 08.04.2016 10:01
Letzter Beitrag: hotsystems
  WS2812 Helligkeit einzelner LEDs steuern mavericklp 3 660 11.03.2016 09:32
Letzter Beitrag: torsten_156
  Lampe mit Key leuchten lassen FCraftLP 1 474 05.03.2016 11:44
Letzter Beitrag: hotsystems
  Problem bei Temperatur/volt Ampere Abfrage LCD Flimmern nuernie66 9 647 04.03.2016 19:25
Letzter Beitrag: hotsystems
  IRemote probleme mit abfrage schnutzkurt 18 1.153 20.02.2016 01:30
Letzter Beitrag: SkobyMobil
  Mit dem Pin 8 und 9 vom Yun werden zwei LED wechselseitig blinken über http arduinofan 1 551 08.12.2015 15:03
Letzter Beitrag: arduinofan

Gehe zu:


Benutzer, die gerade dieses Thema anschauen: 1 Gast/Gäste