Beleuchtete Taster

Hallo,

meine TonUINO-Box funktioniert schon mal einwandfrei. Ich stehe nur vor einem kleinen „Problem“ zudem ich leider nichts hilfreiches noch gefunden habe.
Meine Taster sind mit LED-Umrandung und ich würde diese gerne nur Zeit gesteuert leuchten lassen, teilweise klappt es zwar (nach dem Start und dann beim ersten Drücker, danach schaltet sich die Beleuchtung nicht aus sondern erst nach einem weiteren Tastendruck nach der Leuchtdauer).
Bin leider nur Hobbyprogrammierer :grimacing:.

Mein Code in der Funktion readButtons():

  if (digitalRead(buttonPause) == LOW || digitalRead(buttonUp) == LOW ||
      digitalRead(buttonDown) == LOW) {
        oldtime=millis();
        digitalWrite(buttonPauseLight,HIGH);
        digitalWrite(buttonUpLight,HIGH);
        digitalWrite(buttonDownLight,HIGH);
  }
  if(millis()>(oldtime+lightTime)){
        digitalWrite(buttonPauseLight,LOW);
        digitalWrite(buttonUpLight,LOW);
        digitalWrite(buttonDownLight,LOW);
   }

oldtime wird dabei Global mit 0 initialisiert und lightTime mit der Zeit die die Taster leuchten sollen definiert.

Meine Taster: Taster

Danke schon mal für eure Unterstützung.

Beste Grüße
Christian

Für mich sieht es danach aus das du Taster mit mechanischer raste hast. Also Verbindung im Taster bleibt bestehen bis du ihn noch Mal drückst. Der toggelt zwischen den Zuständen immer verbunden und immer unterbrochen mit jedem drücken. Wir sonst eingesetzt als ein Schalter, mit Statusanzeige.

Danke für deinen Input, das kann ich aber leider ausschließen. Die die ich bestellt habe sind mit momentary reset.

Grüße
Christian

Einfach mal mit einem Multimeter durchmessen. Ansonsten halt mal sowas in den Code reinschreiben wie

if ((digitalRead(buttonPauseLight) == LOW) { Serial.println(„gedrückt“); delay(100); }

Achtung: Das ist wirklich nur zur Debugging-Zwecken, da die 100ms den Durchlauf ziemlich langsam machen. Handelt es sich um einen Schalter, so wird die Ausgabe auf Serial anfangen, wenn du gedrückt hast und erst enden, wenn du wieder drückst. Bei einem Taster hört es wieder auf, wenn du nicht mehr drückst.

Noch kurz was zu deinem Code: Die zweite If-Bedingung wird bei jedem Schleifendurchlauf durchlaufen wenn lightTime abgelaufen ist. Also auch dann, wenn die Lichter schon (lange) wieder ausgeschaltet sind. Das führt zu keinem Fehler, aber macht den Code halt langsamer. Ich würde an deiner Stelle in der zweiten If-Anweisung oldTime wieder auf 0 zurücksetzen und die If-Anweisung erweitern auf

if((millis()>(oldtime+lightTime)) && oldTime>0)

Weiterhin ist wahrscheinlich, dass beide Zustände nicht parallel in einem Durchlauf auftreten können. Hier ist es besser, wenn du in der zweiten Anweisung statt mit if besser mit else if arbeitest. Weil dann wird der zweite Anweisungsblock nicht mehr durchlaufen, wenn der erste schon gegriffen hat. Wie gesagt: Es ist nicht falsch mit zwei if, aber es wird effizienter, wenn man es mit if / else if macht. Geht natürlich nicht immer.

Danke für deine Tipps, ich habe meinen Code wie empfohlen nachgebessert. Problem bestand leider weiter. Der Tipp mit Serial.println() war aber Gold wert. Ich habe mir so ziemlich alles ausgeben lassen meiner Werte und da ist mir aufgefallen, dass in meiner Variable lightTime komplett was anderes gespeichert war als ich definiert habe. Also wenn ich die Zeit mit zB 1000“mal“60“mal“3 angegeben habe (damit ich hinten nur meine Minuten angeben müsste) klappte es nicht, mit dem direkten Wert 180000 angegeben klappt es interessanterweise.
Herzlichen Dank für die Unterstützung.

Grüße
Christian

Welchen Datentyp hat lightTime?

Wenn du aus der 1000 eine 1000.0 machst sollte es auch gehen. Andernfalls führt er die Multiplikation mit integer Werten aus, die wahrscheinlich nur bis 65000 und ein paar zerquetscht gehen, wobei es zu einem Überlauf kommt.

Wenn es ein int ist dann geht es sogar nur bis ~32000.

Am besten einmal nachsehen, welchen Variablentyp millis() liefert und den gleichen Typ nehmen.

Ein Wechsel auf float ist eine ganz schlechte Idee, das kostet mehr als 10 man so viel Rechenzeit.

Schlechte Angewohnheit von der PC-Programmierung :innocent:
Da ist Rechenleistung egal ^^
Edit:
Millis ist vom Typ unsigned long.
Wenn du die 1000 als 1000L schreibst sollte die Berechnung auch gehen. Laut arduino Referenz läuft die Funktion Millis erst nach ca. 50 Tagen über (springt dann wieder auf Null und zählt von neuem hoch)

@TheSealion Ich war beim unsigned int, aber literale sind ja alle signed :see_no_evil:

1 „Gefällt mir“

wenn jetzt aber schon für unsigned long berechnet wird, warum dann nicht auch mit unsigned long rechnen?
also dan direkt lightTime = 1000UL * 60UL * (unsigned long)minuten

Ich habe auch beleuchtbare Tasten. Bevor ich das Rad neu erfinde: Kannst du bitte deine Änderungen am Code zur Verfügung stelllen? Ich möchte einfach nur bei jeder gedrückten Taste über je einen Ausgang mit der Tastenbeleuchtung ein optisches Feedback für paar 100ms geben.

So wie ich den Code verstehe - und das tu ich nicht wirklich - kann man das nicht an einer Stelle zentral einbauen, sondern muss die ganzen einzelnen Funtionen anpassen um dort jeweils einen digitalWrite abzusetzen, oder?

Mal kurz OFFTOPIC: Welche beleuchteten Taster verwendet ihr bzw. könnt ihr empfehlen?

Das allereinfachste wäre, wenn du in der void loop() einbaust:

if(pauseButton.isPressed()) {
    digitalWrite(buttonPauseLight,HIGH);
else {
    digitalWrite(buttonPauseLight,LOW);
}

Damit leuchtet der Schalter immer, wenn die entsprechende Taste gedrückt ist. Um das Licht verzögert auszuschalten musst du halt den Code aus dem ersten Post mit einbauen, dann gehen die nach der durch lightTime definierten Zeit aus. War es das, was du bauen wolltest?

Ich würde noch eine State Variable einbauen. So dass nicht dauerhaft digitalwrite() feuert, sondern nur bei Änderung.

1 „Gefällt mir“

Ich fand die ganz gut https://www.amazon.de/gp/aw/d/B01N11BDX9