Backlight der LCD nach (x) Sekunden deaktivieren

Ich möchte das Backlight der LCD (I2C) nachdem 5 - 10 Sekunden keine Taste gedrückt wurde deaktivieren.
Ist das so einfach möglich?
In Zeile 95 musste ich das Backlight aktivieren. Das war vom Ersteller des Sketches nicht vorgesehen. Aber ohne diesen Eintrag sieht man ja nichts auf der LCD.

/*----------[ Dosierpumpe Version 4.12 )----------

    Softwareversion 9.12 | Copyright 2016
             By Stefan Schepperle
            stefan@schepperle.info

  -----------[ ATMega 328      [Arduino] )----------*/


/*-----[ Bibliotheken einlesen )-----*/
#include <DS3232RTC.h>
#include <Time.h>
#include <EEPROM.h>
#include <Wire.h>
#define ADDR_RTCDS3231 0x68
#include <LiquidCrystal_I2C.h>

LiquidCrystal_I2C lcd(0x3f, 20, 4); // set the LCD address to 0x27 for a 20 chars and 4 line display

byte decToBcd(byte val) {
  return ( (val / 10 * 16) + (val % 10) );
}
byte bcdToDec(byte val)  {
  return ( (val / 16 * 10) + (val % 16) );
}


/*-----[ Variablen deklarieren )-----*/
const int tasterm  = 12;     // Taster Mitte
const int tastero  = 11;     // Taster oben
const int tasterl  = 10;     // Taster links
const int tasteru =  9;     // Taster unten
const int tasterr =  8;     // Taster rechts

int pumpe1  =  7;     // Pumpe 1 Ausgang
int pumpe2  =  6;     // Pumpe 2 Ausgang
int pumpe3  =  5;     // Pumpe 3 Ausgang

int pumpschutz1 = 0;
int pumpschutz2 = 0;
int pumpschutz3 = 0;

int x = 1; int y = 0;
long pumpleistung1; long pumpleistung2; long pumpleistung3;

int pumpe1_time_h = EEPROM.read(3); int pumpe2_time_h = EEPROM.read(4); int pumpe3_time_h = EEPROM.read(5);
int pumpe1_time_m = EEPROM.read(6); int pumpe2_time_m = EEPROM.read(7); int pumpe3_time_m = EEPROM.read(8);
int pumpe1_ml = EEPROM.read(0); int pumpe2_ml = EEPROM.read(1); int pumpe3_ml = EEPROM.read(2);
int pumpe1_ml_s = EEPROM.read(9); int pumpe2_ml_s = EEPROM.read(10); int pumpe3_ml_s = EEPROM.read(11);


int Std = 0; int Min = 0; int Tag = 1; int Mon = 1; int Jahr = 2000;

char pause_hour = 0; char pause_min = 0; char pause_day = 0; char pause_month = 0;

/*-----[ Zeitmodul DS3231 einlesen und aktivieren )-----*/
void setDS3231time(int second, int minute, int hour, int ndofweek, int dday, int dmonth, int dyear)
{
  Wire.beginTransmission(ADDR_RTCDS3231);
  Wire.write(0);
  Wire.write(decToBcd(second));   // Sekunden setzen
  Wire.write(decToBcd(minute));   // Minuten setzen
  Wire.write(decToBcd(hour));     // Stunden setzen
  Wire.write(decToBcd(ndofweek)); // Wochentag setzen
  Wire.write(decToBcd(dday));     // Tag setzen
  Wire.write(decToBcd(dmonth));   // Monat setzen
  Wire.write(decToBcd(dyear));    // Jahr Setzen
  //Wire.endTransmission();
}

/*-----[ Einstellungen einlesen )-----*/
void setup(void)
{
  Serial.begin(9600);
  setSyncProvider(RTC.get);   // Funktion zum RTC Modul
  if (timeStatus() != timeSet)
    Serial.println("Zum synchronisieren mit dem RTC Modul");
  else
    Serial.println("Zeit und Datum wurden gespeichert");

  // Ausgänge festlegen
  pinMode(pumpe1, OUTPUT); digitalWrite(pumpe1, HIGH);
  pinMode(pumpe2, OUTPUT); digitalWrite(pumpe2, HIGH);
  pinMode(pumpe3, OUTPUT); digitalWrite(pumpe3, HIGH);

  // Eingänge Festlegen
  pinMode(tasterm, INPUT);
  pinMode(tastero, INPUT);
  pinMode(tasterl, INPUT);
  pinMode(tasteru, INPUT);
  pinMode(tasterr, INPUT);

  lcd.begin(20, 4);        // LCD Inizialisieren
  lcd.backlight();        // Backlight dauerhaft an

  /*-----[ Bildschirm aufbauen )-----*/
  lcd.setCursor(0, 1);
  lcd.print("-Arduino-");
  lcd.setCursor(2, 2);
  lcd.print("Aqua Dosierpumpe");
  lcd.setCursor(0, 3);
  lcd.print(" ~ Setup      o Info");
}

void loop() {
  if (hour() < 10) { // wenn kleiner 10 schreibe eine 0 davor
    lcd.setCursor(0, 0); lcd.print("0"); pause_hour = 1;
  }
  else pause_hour = 0;

  if (minute() < 10) { // wenn kleiner 10 schreibe eine 0 davor
    lcd.setCursor(3, 0); lcd.print("0"); pause_min = 4;
  }
  else pause_min = 3;

  if (day() < 10) { // wenn kleiner 10 schreibe eine 0 davor
    lcd.setCursor(10, 0); lcd.print("0"); pause_day = 11;
  }
  else pause_day = 10;

  if (month() < 10) { // wenn kleiner 10 schreibe eine 0 davor
    lcd.setCursor(13, 0); lcd.print("0"); pause_month = 14;
  }
  else pause_month = 13;
  lcd.setCursor(5, 0); lcd.print(" ");
  lcd.setCursor(pause_hour, 0); //Start at character 4 on line 0
  lcd.print(hour()); lcd.print(":");
  lcd.setCursor(pause_min, 0); lcd.print(minute());
  lcd.setCursor(pause_day, 0); lcd.print(day()); lcd.print(".");
  lcd.setCursor(pause_month, 0); lcd.print(month()); lcd.print("."); lcd.print(year());

  if (digitalRead(tasterr) == HIGH)hauptmenue(1);
  if (digitalRead(tasterm) == HIGH)uebersicht(1) ;

  // Ermittung wann und wielange gepumpt werden muss
  pumpleistung1 = 1020.0 / (pumpe1_ml_s / 100.0); pumpleistung2 = 1020.0 / (pumpe2_ml_s / 100.0); pumpleistung3 = 1020.0 / (pumpe3_ml_s / 100.0);

  if (pumpschutz1 == 0) {
    if (hour() == pumpe1_time_h && minute() == pumpe1_time_m) {
      pumpschutz1 = 1;
      digitalWrite(pumpe1, LOW);
      delay (pumpleistung1 * pumpe1_ml);
      digitalWrite(pumpe1, HIGH);
    }
  }
  if (minute() + 1 == pumpe1_time_m) {
    pumpschutz1 = 0;
  }

  if (pumpschutz2 == 0) {
    if (hour() == pumpe2_time_h && minute() == pumpe2_time_m) {
      pumpschutz2 = 1;
      digitalWrite(pumpe2, LOW);
      delay (pumpleistung2 * pumpe2_ml);
      digitalWrite(pumpe2, HIGH);
    }
  }
  if (minute() + 1 == pumpe2_time_m) {
    pumpschutz2 = 0;
  }

  if (pumpschutz3 == 0) {
    if (hour() == pumpe3_time_h && minute() == pumpe3_time_m) {
      pumpschutz3 = 1;
      digitalWrite(pumpe3, LOW);
      delay (pumpleistung3 * pumpe3_ml);
      digitalWrite(pumpe3, HIGH);
    }
  }
  if (minute() + 1 == pumpe3_time_m) {
    pumpschutz3 = 0;
  }


}

Hi

‘So’ ist Es nicht möglich - Du deaktivierst in dem Sketch ja Nichts.
Auch lässt sich der Sketch nicht kompilieren, ‘hauptmenue’ gibt Es schlicht nicht.

Entweder übernehmen die Funktionen hauptmenue() und uebersicht() die Kontrolle so lange, bis Du darin fertig bist (kein schöner Ansatz), oder mir fehlt ein Aufruf in der loop(), Der Sich um das Menü kümmert.

Aktuell benutzt Du delay - wo das Auge hinschaut.
SO kannst Du während der Wartezeit, daß die Pumpe wieder ausgeschaltet werden soll, NICHT machen, außer warten.
Schaue Dir das Beispiel ‘Blink_without_delay’ in der IDE an und schreibe Deinen Code auf millis(); um.
Verlager ALLE Funktionalitäten Deiner loop() in weitere Funktionen, Die aber immer nur ‘einen Schritt’ machen und dann die Kontrolle wieder abgeben.
So kannst Du in loop() - Welches jetzt einige zig hundert Mal die Sekunde abgelaufen wird, per Abfrage auf millis() prüfen, ob seit 5 Sekunden keine Taste mehr gedrückt wurde und dann das Licht abschalten.
Anders halt auch, wenn ein Knopf gedrückt wird, das Licht einschalten (und ggf. den ersten Tastendruck ignorieren - der Anwender sieht ggf. ja nicht, WAS Er Da ändern würde).

MfG

const unsigned int DISPLAY_TIMEOUT = 5000;
bool displayIsOn = true;
unsigned long displayTimeout;

void displayBacklight()
{
  if ( Taste gedrückt )    //Pseudocode!
  {
    displayTimeout = millis();

    if (!displayIsOn)
    {
       displayIsOn = true;
       *****          //Display an
    }

    return;
  }

  if(displayIsOn && (millis() - displayTimeout > DISPLAY_TIMEOUT))
  {
     displayIsOn = false;
     *****          //Display aus
  } 
}

void loop()
{

  displayBacklight();

}

Den Druck von mehreren Tasten erfasst am besten so, dass bei jedem Druck eine weiteren Variable gesetzt wird auf die dann abfragen kann (z.B. bool buttonPressed). Diese muss dann nach der Auswertung gleich wieder zurückgesetzt werden.

Ein Tastendruck setzt dann die Timeout Zeit auf den aktuellen Wert. So kann man die An-Zeit verlängern wenn das Display an ist. Wenn es aus ist wird es eingeschaltet.

Wenn das Display an ist und die Zeit abgelaufen ist wird es abgeschaltet

Dazu darf man aber wie gesagt sonst keine Delays verwenden da sonst die Abfrage auf die Tasten und die Zeit nie richtig drankommt

Danke für die Antworten.
Aber wie ich schon in anderen Beiträgen geschrieben habe, ist das Projekt eine Übernahme aus einer Bauanleitung (Dosierpumpe für Aquarium) wo ich davon ausging das programmtechnisch alles ausgereift ist.
Nun muss ich, nachdem ja eigentlich alles soweit läuft, in den Sketch nachbessern. Das fängt ganz simpel bei der Darstellung auf dem LCD an. Da ist dann schon mal der Text zu lang oder geht in die nächste Zeile. Das bekomme ich ja noch geregelt. Aber ich habe mich noch nie mit einem Arduino und dessen Programmierung beschäftigt.
Von dem Ersteller des Sketches bekomme ich auch nicht unbedingt die Unterstützung. Dieser hat relativ alte Library´s verwendet so dass Anfangs gar nichts lief. So bleibt mir nur die Möglichkeit hier im Forum mich durch zu fragen.
So weiß ich nicht was in der IDE die verschiedenen Reiter mit den jeweiligen Abläufen zu sagen haben. Da streikt auch Googel.
Nur für dieses eine Projekt in den vergangenen 50 Jahren werde ich kaum die Programmierung des Arduino erlernen. Ich werde das wohl nie wieder benötigen.
Ich kann die Sketche von den anderen Reitern in der IDE posten, aber es ist halt nur ein "kosmetischer" Aspekt wenn das Backlight ständig an ist.

Hi

Aus dem tollsten Trecker wird kein schneidiger Rennwagen - der Sketch ist vermauert und müsste für diese kleine Änderung komplett überarbeitet werden.
Da es sich dabei, wie Du schreibst, nur um Kosmetik handelt und Du auch nicht weiter vorhast, großartig in die Welt des Arduino einzutauchen, wird's wohl das Sinnvollste sein, Du lebst mit dieser kosmetischen Unschönheit.

Bitte verstehe aber auch unseren Standpunkt, daß wir hier nicht jedermanns Trecker in einen Sportflitzer umbasteln - denn auch Das ist nicht einfach nur so aus dem Ärmel geschüttelt.

Der damalige Programmierer hat die für Ihn brauchbare Lösung entwickelt - Perfektion ist ein tolles Wort, sollte man ggf. auch anstreben, aber ich denke, wir sind hier so ziemlich Alle davon noch eine gute Ecke von entfernt.

Ein Sketch ist 'gut', wenn Er macht, was man will - zumindest 'gut genug' - eben für diese Anwendung.
Wenn man 'was Anderes will' - muß der Sketch ggf. angepasst/komplett geändert werden - um der Perfektion wieder ein Stück näher zu kommen.

Auch, wenn Du schon 50 Lenze auf dem Buckel hast, kann der Arduino zu Deinem Hobby werden - Du solltest allerdings in diese Richtung empfänglich sein und Ihn nicht nur als 'das Teil für die Pumpe' ansehen.

Hilfe zur Selbsthilfe wirst Du hier von so ziemlich Jedem bekommen (wenn auch z.B. delay() nicht gerne gesehen wird :wink: ) - einen Gratis-Sketch wohl eher nicht.
Auf der anderen Seite des Monitor sitzen auch nur Hobbyisten, Die Ihre Zeit damit verplempern, dem Steinchen Das beizubringen, was Sie selber gerade (denken zu) brauchen - ist irgendwie ein Fulltime-Job.

MfG

Ich denke ich habe schon viele andere Dinge gemeistert und irgendwie hin gebogen. Sicherlich nicht auf den praktikabelsten oder kürzesten Weg. Aber nach den Grundsatz "learning by doing" geht es weiter.
Das Backlight hält bestimmt einige Jahre. Und ich kann ja auch ein Schalter einbauen.

Schade eigentlich nur das man eine Bauanleitung ins Netz stellt die unvollständig ist.

Tom2Bit:
Schade eigentlich nur das man eine Bauanleitung ins Netz stellt die unvollständig ist.

Schade ist, dass du nicht bereit bist zu verstehen, wie dir hier schon geholfen wurde und du offensichtlich nicht bereit bist daraus zu lernen.

Da hilft dir Crossposting sicher nicht weiter.

Ich denke ich habe schon viele andere Dinge gemeistert und irgendwie hin gebogen. Sicherlich nicht auf den praktikabelsten oder kürzesten Weg. Aber nach den Grundsatz “learning by doing” geht es weiter.

Also es ist nunmehr kein Geheimnis, dass ich das Problem auch schon in
anderen Foren gepostet habe. (Ohne Erfolg)
Ich habe keine Zeit mich nur für das eine und wahrscheinlich auch
einzinste Projekt mit dem Arduino mich dann mit dessen Programierung
auseinanderzusetzen.
Trotzdem habe ich mich jetzt nochmal mit dem Sketch auseinandergesetzt
auch weil ich Urlaub habe.
Nach gut 6 Stunden bin ich am Ziel angelangt.
Nun was habe ich gemacht?
In Zeile 25 habe ich mit:

const int tasterl = 10; // Taster links

den linken Taster deklariert und diesen in Zeile 29/30 mit

int DisplaySchalter = 0;
long DisplayAus = 0;

eine Variable für den Zustand gegeben.

Die Zeile 91/92 bedarf keiner Erklärung.

In Zeile 102 wird mit

DisplayAus = now() + 30;

der Zeit 30 Sekunden addiert.
In Zeile 103 wird Taster “tasterl” als Eingang definiert

pinMode(tasterl, INPUT);

In Zeile 136-138 wird der Taster abgefragt

DisplaySchalter = digitalRead(tasterl);
if (DisplaySchalter == HIGH) {
DisplayAus = now() + 30;

Dann noch die IF-Abfrage in Zeile 140

if (now() > DisplayAus) { lcd.noBacklight(); } else { lcd.backlight();

So funktioniert das. Ob das optimal ist oder nicht? Egal es
funktioniert.

Und den Taster “tasterl” (linker Taster) habe ich verwendet weil dieser
im Hauptmenü keine Funktion hat.

Alles was ich gemacht habe ist im Code mit // NEU gekennzeichnet.

/*-----[ Bibliotheken einlesen )-----*/
#include <DS3232RTC.h>
#include <Time.h>
#include <EEPROM.h>
#include <Wire.h>
#define ADDR_RTCDS3231 0x68
#include <LCD.h>
#include <LiquidCrystal.h>
#include <LiquidCrystal_I2C.h>

//LiquidCrystal_I2C lcd(0x3f,20,4); // set the LCD address to 0x27 for a 20 chars and 4 line display
LiquidCrystal_I2C lcd(0x3f, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);  // Set the LCD I2C address

byte decToBcd(byte val) {
  return ( (val / 10 * 16) + (val % 10) );
}
byte bcdToDec(byte val)  {
  return ( (val / 16 * 10) + (val % 16) );
}


/*-----[ Variablen deklarieren )-----*/
const int tasterm  = 12;     // Taster Mitte
const int tastero  = 11;     // Taster oben
const int tasterl  = 10;     // Taster links  //Taster an Pin 10 für Backlight ON NEU
const int tasteru =  9;     // Taster unten
const int tasterr =  8;     // Taster rechts

int DisplaySchalter = 0;    // Variable fuer den Zustand des Display-Tasters NEU
long DisplayAus = 0;        // NEU

int pumpe1  =  7;     // Pumpe 1 Ausgang
int pumpe2  =  6;     // Pumpe 2 Ausgang
int pumpe3  =  5;     // Pumpe 3 Ausgang

int pumpschutz1 = 0;
int pumpschutz2 = 0;
int pumpschutz3 = 0;

int x = 1; int y = 0;
long pumpleistung1; long pumpleistung2; long pumpleistung3;

int pumpe1_time_h = EEPROM.read(3); int pumpe2_time_h = EEPROM.read(4); int pumpe3_time_h = EEPROM.read(5);
int pumpe1_time_m = EEPROM.read(6); int pumpe2_time_m = EEPROM.read(7); int pumpe3_time_m = EEPROM.read(8);
int pumpe1_ml = EEPROM.read(0); int pumpe2_ml = EEPROM.read(1); int pumpe3_ml = EEPROM.read(2);
int pumpe1_ml_s = EEPROM.read(9); int pumpe2_ml_s = EEPROM.read(10); int pumpe3_ml_s = EEPROM.read(11);


int Std = 0; int Min = 0; int Tag = 1; int Mon = 1; int Jahr = 2000;

char pause_hour = 0; char pause_min = 0; char pause_day = 0; char pause_month = 0;

/*-----[ Zeitmodul DS3231 einlesen und aktivieren )-----*/
void setDS3231time(int second, int minute, int hour, int ndofweek, int dday, int dmonth, int dyear)
{
  Wire.beginTransmission(ADDR_RTCDS3231);
  Wire.write(0);
  Wire.write(decToBcd(second));   // Sekunden setzen
  Wire.write(decToBcd(minute));   // Minuten setzen
  Wire.write(decToBcd(hour));     // Stunden setzen
  Wire.write(decToBcd(ndofweek)); // Wochentag setzen
  Wire.write(decToBcd(dday));     // Tag setzen
  Wire.write(decToBcd(dmonth));   // Monat setzen
  Wire.write(decToBcd(dyear));    // Jahr Setzen
  //Wire.endTransmission();
}

/*-----[ Einstellungen einlesen )-----*/
void setup(void)
{
  Serial.begin(9600);
  setSyncProvider(RTC.get);   // Funktion zum RTC Modul
  if (timeStatus() != timeSet)
    Serial.println("Zum synchronisieren mit dem RTC Modul");
  else
    Serial.println("Zeit und Datum wurden gespeichert");

  // Ausgänge festlegen
  pinMode(pumpe1, OUTPUT); digitalWrite(pumpe1, HIGH);
  pinMode(pumpe2, OUTPUT); digitalWrite(pumpe2, HIGH);
  pinMode(pumpe3, OUTPUT); digitalWrite(pumpe3, HIGH);

  // Eingänge Festlegen
  pinMode(tasterm, INPUT);
  pinMode(tastero, INPUT);
  pinMode(tasterl, INPUT);
  pinMode(tasteru, INPUT);
  pinMode(tasterr, INPUT);

  //lcd.int();              
  lcd.backlight();        // LCD Hintergrundbeleuchtung NEU
  lcd.begin(20, 4);        // LCD Initialisieren

  /*-----[ Bildschirm aufbauen )-----*/
  lcd.setCursor(0, 1);
  lcd.print("-   Arduino   -");
  lcd.setCursor(2, 2);
  lcd.print("Aqua Dosierpumpe");
  lcd.setCursor(0, 3);
  lcd.print(" ~ Setup      o Info");

  DisplayAus = now() + 30;    // NEU
  pinMode(tasterl, INPUT);    // Port definieren NEU
}

void loop() {
if (hour() < 10) { // wenn kleiner 10 schreibe eine 0 davor
  lcd.setCursor(0, 0); lcd.print("0"); pause_hour = 1;
}
else pause_hour = 0;

if (minute() < 10) { // wenn kleiner 10 schreibe eine 0 davor
  lcd.setCursor(3, 0); lcd.print("0"); pause_min = 4;
}
else pause_min = 3;

if (day() < 10) { // wenn kleiner 10 schreibe eine 0 davor
  lcd.setCursor(10, 0); lcd.print("0"); pause_day = 11;
}
else pause_day = 10;

if (month() < 10) { // wenn kleiner 10 schreibe eine 0 davor
  lcd.setCursor(13, 0); lcd.print("0"); pause_month = 14;
}
else pause_month = 13;
lcd.setCursor(5, 0); lcd.print(" ");
lcd.setCursor(pause_hour, 0); //Start at character 4 on line 0
lcd.print(hour()); lcd.print(":");
lcd.setCursor(pause_min, 0); lcd.print(minute());
lcd.setCursor(pause_day, 0); lcd.print(day()); lcd.print(".");
lcd.setCursor(pause_month, 0); lcd.print(month()); lcd.print("."); lcd.print(year());

if (digitalRead(tasterr) == HIGH)hauptmenue(1);
if (digitalRead(tasterm) == HIGH)uebersicht(1) ;

DisplaySchalter = digitalRead(tasterl);     //NEU
  if (DisplaySchalter == HIGH) {             //NEU
  DisplayAus = now() + 30;                 //NEU
  }                                        //NEU
if (now() > DisplayAus) { lcd.noBacklight(); } else { lcd.backlight(); }   //NEU

Super wenn es funktioniert. Aber sei vorsichtig, sonst fängt es noch an dir Spaß zu machen und du merkst was du noch alles mit dem Arduino anfangen kannst.
Übrigens, ich war über 60 Lenze jung, als ich mit dem Arduino angefangen habe.
Und auch ich wollte Bauanleitungen aus dem Netz nachbauen und nichts hat gepasst.

Ich kann also nachvollziehen, was du gerade durchmachst. Zum Lernen ist man nie zu alt.

Grüße :slight_smile:

Hi

Dann war der Umbau ja doch nicht ganz so umfangreich, wie ich gedacht hatte - Glückwunsch dazu!
Kann aber sein, daß Dir die Abschalt-Abfrage in 49,x Tagen eine lange Nase zeigt.
Kann sein, daß Du nur die 30 Sekunden 'um den Überlauf herum' irgendwie 'überleben' musst - wenn das Display in ferner Zukunft nicht angehen will (now() ist größer als die berechnete und übergelaufene Endzeit) hast Du zumindest einen Anhaltspunkt, wo Du angreifen kannst.

MfG

postmaster-ino:
Kann aber sein, daß Dir die Abschalt-Abfrage in 49,x Tagen eine lange Nase zeigt.
Kann sein, daß Du nur die 30 Sekunden 'um den Überlauf herum' irgendwie 'überleben' musst - wenn das Display in ferner Zukunft nicht angehen will (now() ist größer als die berechnete und übergelaufene Endzeit) hast Du zumindest einen Anhaltspunkt, wo Du angreifen kannst.

MfG

Da bin ich wieder mit meinem Latein am Ende. Oder ich verstehe das nicht so ganz. (49,x Tage)?

MfG

Hallo,

der Wertebereich von millis mit “unsigned long” (du verwendest nur “long” - 1. Fehler) reicht für einen Zeitraum von besagten 49 Tagen. Kannste mal nachrechnen. Danach gibt es einen Überlauf, dass heißt die Variable kippt vom möglichen Maximum ihres Wertebereiches auf ihren Minimumwert ihres Wertebereiches. Unterschied unsigned und nicht unsigned klar machen. Übrigens ist dein Code schlecht lesbar wenn du alles auf eine Zeile quetscht.

Man darf die aktuelle Zeit nicht händisch ändern. Man muss sie sich merken und mit einer Wartezeit vergleichen. Die gemerkte Zeit, die niemals größer sein kann wie die aktuelle, kann man ggf. nachziehen, sprich immer aktualisieren bei Ereignissen.

Ich habe dir mal ein Bsp. gemacht für die Automatikschaltung. Damit siehst du auch wie man alle Taster zusammenfassen kann und mittels Index drüber geht.

Wenn du das hier gelesen hast, dann solltest du den Bsp. Code lesen und verstehen können.

Theseus erklärt millis()

GuntherB - BlinkwithoutDelay - Die Nachtwächtererklärung

// https://forum.arduino.cc/index.php?topic=574644.0

const byte tasterArray[] = {12,11,10,9,8};    // Pins der Taster

const byte ANZAHL_TASTER = sizeof(tasterArray) / sizeof(tasterArray[0]);


void setup() {
  /*
  // I/O Zustände einstellen, kann man bei reiner INPUT Funktion weglassen
  for (byte i=0; i<ANZAHL_TASTER; i++) {
    pinMode(tasterArray[i], INPUT);
  }
  */
  pinMode(LED_BUILTIN, OUTPUT);   // LED13        
}

void loop() {
  
  backlight_automatic_switch_OnOff();            
   
  // weitere sinnvolle Dinge tun
  // ... 

}


// ****** Funktionen ******

void backlight_automatic_switch_OnOff ()                   
{
  static unsigned long last_ms = 0;
  const unsigned int INTERVAL = 3000;          // [ms]
  
  for (byte i=0; i<ANZAHL_TASTER; i++) {
    if (digitalRead(tasterArray[i]) == HIGH) {  // wenn irgendein Taster gedrückt wurde,
      last_ms = millis();                       // Zeit merken
      //lcd.backlight();                        // und Backlight einschalten
      digitalWrite(LED_BUILTIN, HIGH);
    }  
  }

  if (millis() - last_ms > INTERVAL) {          // wenn Wartezeit nach letzten Tasterdruck
    //lcd.noBacklight();                        // abgelaufen Backlight ausschalten
    digitalWrite(LED_BUILTIN, LOW);
  }
  
}

(232 - 1) ms = 49,710269618056 Tage

Danach fängt millis() wieder bei 0 an, das sollte man programmtechnisch berücksichtigen.

Anregungen für Änderungen:

bool DisplaySchalter = 0;    // Variable fuer den Zustand des Display-Tasters NEU => agmue: anderer Typ
unsigned long DisplayAus = 0;        // NEU => agmue: anderer Typ

...

  DisplayAus = now() + 30;    // NEU
  //pinMode(tasterl, INPUT_PULLUP);    // Port definieren NEU => agmue: kann weg, steht schon ein paar Zeilen drüber

...

  DisplaySchalter = digitalRead(tasterl);     //NEU
  if (DisplaySchalter == HIGH) {              //NEU
    DisplayAus = now();                       //NEU
  }                                           //NEU
  if (now() - DisplayAus >= 30) {             //NEU => agmue: überlaufsichere Berechnung
    lcd.noBacklight();                        //NEU
  } else {                                    //NEU
    lcd.backlight();                          //NEU
  }                                           //NEU
}

Ich fände es besser, das Display auch nicht mehr zu beschreiben, wenn es dunkel ist. Was meinst Du?

Tom2Bit:
Nur für dieses eine Projekt in den vergangenen 50 Jahren werde ich kaum die Programmierung des Arduino erlernen.

Tom2Bit:
Ich denke ich habe schon viele andere Dinge gemeistert und irgendwie hin gebogen. Sicherlich nicht auf den praktikabelsten oder kürzesten Weg. Aber nach den Grundsatz “learning by doing” geht es weiter.

Mit Arduino kann man Schrittmotoren ansteuern oder LEDs blinken lassen, möglicherweise würden sich Deine Enkel oder Deine Frau über ein Geschenk freuen. Nur mal so als Denkanstoß. Gerade alte Knochen können prima programmieren :slight_smile:

Hallo,

das ist ja nur die Hintergrundbeleuchtung, dass Display würde ich weiterhin beschreiben.
Nur würde ich, wenn die Problematik verstanden wurde, dann den Sketch abändern und nicht permanent das Display beschreiben. Sondern nur aller 500ms oder 1s. Danach wird er ein Tasten prellen bemerken und muss das auch noch abstellen.

Doc_Arduino:
Sondern nur aller 500ms oder 1s.

Oder gar nur, wenn sich inhaltlich was verändert hat :wink:

void ausgabe(unsigned int wert) {
  if (wert < 10) lcd.print("0");  // wenn kleiner 10 schreibe eine 0 davor
  lcd.print(wert);
}
void loop() {
  if (altMinute != minute()) {
    altMinute = minute();
    lcd.setCursor(0, 0); ausgabe(hour()); lcd.print(":"); ausgabe(minute());
    lcd.setCursor(10, 0); ausgabe(day()); lcd.print("."); ausgabe(month()); lcd.print("."); lcd.print(year());
  }

Hallo,

kann man natürlich auch machen. Ich halte dann immer den Codeaufwand dagegen ob sich das lohnt für die Anwendung.
Je schneller der Sketch werden soll, umso mehr Code muss man schreiben und mehr Variablen müssen verwendet werden.
Ich meine wir wissen das 10 Variablenvergleiche um Faktor x schneller sind wie 10 Werte aufs Display zuschieben.
Nur muss man das als Programmierer erst selbst verstehen lernen. Der Hinweis darauf ist dennoch richtig.
In seinem Fall ersetzt das Display beschreiben noch etwas die Tasterentprellung. Wird dann interessant wenn er mit den Tasten im Menü etwas ändern möchte und nicht nur statisch etwas aufrufen. Mal sachte voraus gedacht.

agmue:
(232 - 1) ms = 49,710269618056 Tage

Danach fängt millis() wieder bei 0 an, das sollte man programmtechnisch berücksichtigen.

Anregungen für Änderungen:

bool DisplaySchalter = 0;    // Variable fuer den Zustand des Display-Tasters NEU => agmue: anderer Typ

unsigned long DisplayAus = 0;        // NEU => agmue: anderer Typ

DisplayAus = now() + 30;    // NEU
 //pinMode(tasterl, INPUT_PULLUP);    // Port definieren NEU => agmue: kann weg, steht schon ein paar Zeilen drüber

DisplaySchalter = digitalRead(tasterl);     //NEU
 if (DisplaySchalter == HIGH) {              //NEU
   DisplayAus = now();                       //NEU
 }                                           //NEU
 if (now() - DisplayAus >= 30) {             //NEU => agmue: überlaufsichere Berechnung
   lcd.noBacklight();                        //NEU
 } else {                                    //NEU
   lcd.backlight();                          //NEU
 }                                           //NEU
}



Ich fände es besser, das Display auch nicht mehr zu beschreiben, wenn es dunkel ist. Was meinst Du?
Mit Arduino kann man Schrittmotoren ansteuern oder LEDs blinken lassen, möglicherweise würden sich Deine Enkel oder Deine Frau über ein Geschenk freuen. Nur mal so als Denkanstoß. Gerade alte Knochen können prima programmieren :)

Jetzt ist das wohl eingetreten. Anfang Januar hatte ich nur noch ein buntes Zeichen-Wirwar auf dem Display. Also habe ich den Sketch entsprechend geändert.(agmue)
Nun habe ich das Problem das ich das Display gar nicht mehr oder selten aktiviert bekomme. Bei einem Neustart kann ich sporadisch das Display aktivieren. Die Funktionen sind aber in Ordnung.

Tom2Bit:
Nun habe ich das Problem das ich das Display gar nicht mehr oder selten aktiviert bekomme. Bei einem Neustart kann ich sporadisch das Display aktivieren. Die Funktionen sind aber in Ordnung.

Das ist bedauerlich, Du hast mein Mitgefühl. Leider kann ich Dir bei der mageren Informationslage nicht helfen.