LED im Unterprog einschalten und nach Zeitablauf wider ausschalten !ohne! delay

Ich brauche Hilfe von Euch um ein Problem?! zu lösen und zwar soll in einer Zähl-Abfrage-Schleife die immer 2 Sekunden dauert eine LED für ein paar Sekunden eingeschaltet werden sobald sich der Status ändert. Ist der Status unverändert soll die LED / Hintergrundbeleuchtung aus sein.

Also Statusänderung heisst LED/Hintergrundbeleuchtung für zB. 5 Sek an.

die Funktion

digitalWrite(LED,HIGH)
delay(5000);
digitalWrite(LED,LOW)

muss durch etwas anderes ersetzt werden, damit die 2 Sekunden Schleifenabfrage nicht blockiert wird
und es zu keinen Fehlzählunden kommt.
Ich habe mich schon mit dem “Nachtwächter-Beispiel” beschäftigt um die millis() Funktion zu verstehen.

ich habe als Unterprogramm dies hier:

void HGBLan()                                 //LCD-Hintergrundbeleuchtung

{

 unsigned long currentMillis = millis();
 if (currentMillis - previousMillis >= anZeit) {

     previousMillis = currentMillis;
     digitalWrite(HBL,HIGH);                     // LCD Hintergrundbeleuchtung ein
 }
   
}

Sobald sich ein Status ändert geht die LED auch an… aber ich weis nicht wie ich diese
nach z.B 5 Sekunden wieder aus bekomme.
Wenn ich unter

digitalWrite(HBL,HIGH); 
}

eine “else” Funktion …

else {
digitalWrite(HBL,LOW)
}

… setze passiert gar nichts. Die LED / Hintergrundbeleuchtung bleibt an.

Wie muss die Funktion aussehen damit das so funktioniert wie es soll?

Das Ausschalten der Led funktioniert in ähnlicher Form wie das Einschalten.
Du musst nur andere Namen für die Funktion verwenden und eine Statusvariable abfragen, die den Zustand der Led enthält.
Diesen Zustand fragst du in der Ausschaltroutine zuvor ab.
Einen "else-Zweig" brauchst du dazu nicht.

Edit:
Ich habe dich evtl. falsch verstanden.
Dein obiger Sketch wird sofort gestartet und die Led soll sofort an gehen und nach durchlaufener Zeit wieder ausgehen ?
Richtig ?

deine Funktion HGBLan() wird nur bei Stauswechsel aufgerufen. Das Ausschalten muß aus der Loop angestoßen werden.

Das war der entscheidende Hinweis ardubu. Im Prinzip ist es eine Ausschaltverzögerung.

ich habe es soweit geändert. Immerhin leuchtet die LED bei Statusänderung und geht wieder aus... alles
OK soweit. Allerdings bleibt die LED nicht immer gleich lang an, mal 3 Sekunden und mal 8 Sekunden, mal 10 Sekunden. Ich weis nicht woran es liegt. Falls Ihr das ganze Programm braucht kann ich es posten, allerdings ist es noch nicht ganz fertig, möchte erst die einzelnen Funktionen haben.

In Kurzform sieht es so aus:

unsigned long ausZeit = 10000;  // (10 Sekunden)
etc.


void loop()
{

HGBLaus();   // Unterprogramm zum LED ausschalten


if Zähler = n1
Status = sowieso1  Text auf LCD schreiben
HGBLan();                                          //Hintergrundbeleuchtung an


if Zähler = n2        Text auf LCD schreiben
Status = sowieso2
HGBLan();                                          //Hintergrundbeleuchtung an

usw.


void HGBLan()      // Unter"programm" LED an
{ 
digitalWrite(HBL,HIGH);  // LED ein.
}


void HGBLaus()   // Unterprogramm LED aus
{

    unsigned long currentMillis = millis();
    if (currentMillis - previousMillis >= ausZeit) {

    previousMillis = currentMillis;
    digitalWrite(HBL,LOW);
   
  
   }

   
}

Setze Deinen Sketch bitte in Codetags (</> oben links im Forumseditor), formatiere ihn ordentlich und entferne die Unmenge sinnloser Leerzeilen. Dann wird alles viel leichter lesbar.

Gruß Tommy

um genaueres sagen zu können braucht man den Rest des Sketches.

Mache ich das nächste mal Tommy…
OK. Hier mal des ganze Sketch gehört zwar zu einem anderem Thema, wie gesagt noch nicht ganz fertig.

//**************************************************************
// ********** Blink Signal Übersetzer zur Alarmanlage **********
//**************************************************************
//
// Blinkfolge der "ZONE STATUS" - LED
// 
// Alarm:                                        120 ms Impuls  120 ms Pause        |--|__|--|__|--|
// Austrittsverzögerung aktiv Zonen OK (60Sek)   280 ms Impuls  280 ms Pause        |----|____|----|____|
// Anlage aktiv:                             2 x 120 ms Impuls dann 1750 ms Pause   |--|__|--|_________|--|__|--|
// Alarm gespeichert                         3 x 120 ms Impuls dann 15000 ms Pause  |--|__|--|__|--|_______|--|__|--|__|--|
// Austrittsverzögerung aktiv  Schleifen NICHT OK        LED leuchtet dauernd       |----------------
// Anlage inaktiv                                        LED leuchtet nicht         |________________
//
//*************************************************************** 
//

//
#include <LiquidCrystal.h>
// LCD-Pin Zuordnung   ! R/W auf Ground !
const int rs = 12, en = 11, d4 = 5, d5 = 4, d6 = 3, d7 = 2;
LiquidCrystal lcd(rs, en, d4, d5, d6, d7);

const byte eingang = 7;                          // Eingangs Pin des Signales (5V/0V)
const uint32_t messIntervall = 2000;             // Messintervall 2 Sekunden
uint32_t aktMillis, messMillis;
byte zaehler, aktStatus, altStatus;
bool aktE, altE;                                 // aktuelles Ereignis , altes Ereignis


int HBL = 13;                                    // Hintergrundbeleuchtung
unsigned long anZeit = 5000;                     // Zeit der Beleuchtung
unsigned long ausZeit = 10000;
unsigned long previousMillis = 0;
unsigned long previousMillisan = 0;
int ledState = LOW;




void setup()
{

pinMode(HBL,OUTPUT);



// **** LCD 16x1 wird wie LCD 8x2 behandelt ****
//
//     ###################################
//     #|1|_|_|_|_|_|_|_|2|_|_|_|_|_|_|_|# 
//     ###################################
//
// *********************************************
   lcd.begin(8,2);                               // Display initialisieren  8 Zeichen und 2 Zeilen
   
// Gibt einen Text auf LCD aus.
  lcd.setCursor(0,0);                            // SetCursor (Spalte,Zeile) 
  lcd.print("Signalzu");
  lcd.setCursor(0,1);
  lcd.print("ordnung");

  delay (1000);
  
  lcd.clear();
  lcd.setCursor(0,0);                            // SetCursor (Spalte,Zeile) 
  lcd.print("Start");
  lcd.setCursor(0,1);
  lcd.print(" ");

  

  
  Serial.begin(9600);
  Serial.println(F("Anfang"));
}

void loop()
{

 HGBLaus();

  aktMillis = millis();
  altE = aktE;
  aktE = digitalRead(eingang);
//-------------------------------------------------  
  if (aktE != altE)                                 
  {
       zaehler++;                      
  }
//-------------------------------------------------

  if (aktMillis - messMillis >= messIntervall)    
  {
    aktStatus = 0;
    if (zaehler == 0)
    {
//-------------------------------------------------      
      if  (aktE)  
      {
        aktStatus = 6;
      } else {
        aktStatus = 5;
      }
    }
//----------------------------------------
     if ( zaehler > 20 )
        {
          aktStatus = 6;
        }

    else   
      
    if ((zaehler >= 16) && ( zaehler < 20 ) )
    {
      aktStatus = 1;
    }
    else if ( (zaehler >= 7) && ( zaehler < 20 ) )
    {
      aktStatus = 2;
    }
    else if ((zaehler == 4) || (zaehler ==3))
    {
      aktStatus = 3;
    }
    else if ( (zaehler >= 5) && ( zaehler < 20 ))
    {
      aktStatus = 4;
    }
    if (aktStatus != altStatus)
    {
      Serial.print(F("Impulse "));
      Serial.print(zaehler);
      Serial.print(F("\tStatus "));
      Serial.println(aktStatus);

       
      
       
     
     
//------------------------------------------------      
      if (aktStatus == 1 )
      {
        Serial.println ( " A L A R M " );
      }
             
       if (aktStatus == 2 )
       {
        Serial.println ( " AVZ OK " );
       }
             
      if (aktStatus == 3 )
      {
        Serial.println ( " Aktiv " );
        
    
  lcd.clear();
  lcd.setCursor(0,0);                            // SetCursor (Spalte,Zeile) 
  lcd.print("Aktiv");
  lcd.setCursor(0,1);
  lcd.print(" ");
      
      HGBLan();
      
    
      } 


      if (aktStatus == 4 )
      {
        Serial.println ( " Alarm gespeichert " );
      }

      if (aktStatus == 5 )
      {

        Serial.println ( " I N A K T I V " );
  lcd.clear();
  lcd.setCursor(0,0);                            // SetCursor (Spalte,Zeile) 
  lcd.print("Inaktiv");
  lcd.setCursor(0,1);
  lcd.print(" ");

       HGBLan();

     
      }

      if (aktStatus == 6)
      {
        Serial.println ( " AVZ nicht OK - Tür offen " );
   lcd.clear();
  lcd.setCursor(0,0);                            // SetCursor (Spalte,Zeile) 
  lcd.print("Tuer off");
  lcd.setCursor(0,1);
  lcd.print("en ");

      HGBLan();
      
      }

      if (aktStatus == 0 )
      {
        Serial.println ( " Fehler ");
      }
    
      altStatus = aktStatus;

    }
    messMillis = aktMillis;
    zaehler = 0;

     }

 
}




void HGBLan()

{

 unsigned long currentMillisan = millis();
 if (currentMillisan - previousMillisan >= anZeit) {

     previousMillisan = currentMillisan;
     digitalWrite(HBL,HIGH);
     
 }
   
}





void HGBLaus()
{

     unsigned long currentMillis = millis();
     if (currentMillis - previousMillis >= ausZeit) {

     previousMillis = currentMillis;
     digitalWrite(HBL,LOW);
    
   
    }

    
}

Bajazzo:
Mache ich das nächste mal Tommy...

Ehrlich....das ist ja wohl ein Witz.

Du willst Hilfe haben, arbeitest allerdings nicht mit.
Und auf Fragen musst du auch nicht antworten.

Danke...
Ich bin raus.

aus meiner sicht warst du eh schon knapp drann.

nur die Logik etwas anpassen:

immer wenn du die HGB ein schaltest, merkst du die millis

also das
previousMillis = millis();

in dein void HGBLan()

und im Loop prüfst du dann ob die HGBL an ist UND die Zeit überschritten ist ... dann schaltest die HGBL aus

also etwa

if (currentMillis - previousMillis >= ausZeit && digitalRead(HBL)) {
digitalWrite(HBL,LOW);
}

kommst damit zurecht?

bring mal deine ganzen LCD Ausgaben in extra Funktionen, die du nur 1 X je Sekunde aufrufst, und benutze kein lcd.clear, sondern überschreibe lieber die ganze Zeile.

Was habe ich denn jetzt falsch gemacht? Das vorher war nur ein Ablauf da ich nicht alles posten wollte.
Ich habe doch das ganze jetzt in Codetags gesetzt.

Deine Frage in deiner Antwort HotSystems habe ich nicht gesehen. Entschuldigung

Ich habe dich evtl. falsch verstanden.
Dein obiger Sketch wird sofort gestartet und die Led soll sofort an gehen und nach durchlaufener Zeit wieder ausgehen ?
Richtig ?

Antwort dazu: Die Hintergrund LED soll kurz eingeschaltet werden sobald sich der Status ändert, ansonsten bleibt die aus.

Bajazzo:
Was habe ich denn jetzt falsch gemacht?

Post #4

.........formatiere ihn ordentlich und entferne die Unmenge sinnloser Leerzeilen.

Strg+T funktioniert auch bei dir.

Gruß Fips

An noiasca: Ja ich komme damit zurecht. Im Grunde läuft es jetzt so wie es soll.

Anfang des Programms:

void loop()
{

 currentMillis = millis();
    
 if (currentMillis - previousMillis >= ausZeit && digitalRead(HBL)) {
  digitalWrite(HBL,LOW);
 }

..Auswertung / Ausgabe..

// Unterprogramm LED an

void HGBLan()

{

 unsigned long currentMillisan = millis();
 if (currentMillisan - previousMillisan >= anZeit) {

     previousMillisan = currentMillisan;
     digitalWrite(HBL,HIGH);
     previousMillis = millis();
     
 }
   
}

ardubu: Mit "Funktionen" meinst du voids oder? Wenn es so ist hätte ich das später auch gemacht. Ist das überschreiben mit Leerzeichen denn schneller als lcdclear?

Danke an alle für die Hinweise!

LG

Bajazzo:
Ist das überschreiben mit Leerzeichen denn schneller als lcdclear?

Wenn Du nur den Bereich überschreibst, wo Du wieder ausgeben willst, dann ja.
Noch ein Tipp: Merke Dir den alten Wert und schreibe nur neu, wenn er sich geändert hat.

Gruß Tommy

Ah, okay. Ich dachte lcdclear wäre da schneller. Na gut dann werde ich das so machen.

Noch eine Info warum ich die LCD Beleuchtung an bzw. ausgeschaltet haben will. Es ist ein blaues Display mit weisser Schrift. Im Normalbetrieb, also wenn sich nichts ändert, ist es nur schwach beleuchtet, sprich ich habe als RV LED 1 kOhm. Das reicht völlig um die Info abzu lesen. Wenn sich der Status ändert wird es mit voller Helligkeit für ein paar Sekunden betrieben, hier ist der RV LED 470 Ohm. Der wirkende Gesamtwiderstand liegt dann bei ca. 320 Ohm und das reicht völlig aus, der Strom liegt dann bei ca 16 mA. Ich denke das ich die volle Spannung über ein Transistor schalten werde. Wenn ich direkt an ein Arduino Pin gehen würde, könnte es sein das es bei digitalRead(pin) es zu Fehlinformationen kommt weil ja der 1K Widerstand anliegt und an dem eine Spannung abfällt. Das ist jetzt unabhängig von dem Programm.

Hi

Auch zu LCDs gibt es Datenblätter - dort steht mimosenhaft drin, was wann wie lange dauert und was Alles passiert.

Aber Datenblätter haben seit IOT und 'ich baue mir einen Mars-Roboter als aller erstes Projekt' deutlich an Reiz verloren ... geht ja auch Ohne.

Zur 'Vollgas-Beleuchtung' - dient dieses 'Aufblitzen' der Aufmerksamkeit?
Also, der Bediener wird optisch drauf hingewiesen, daß sich was geändert hat?

Könnte mir vorstellen, daß dieses Aufblitzen beim normalem Ablesen des Display mehr stört, als nützt.
Lasse mich Da aber gerne eines Besseren belehren!!

MfG

postmaster-ino:
Auch zu LCDs gibt es Datenblätter - dort steht mimosenhaft drin, was wann wie lange dauert und was Alles passiert.

Aber Datenblätter haben seit IOT und 'ich baue mir einen Mars-Roboter als aller erstes Projekt' deutlich an Reiz verloren ... geht ja auch Ohne.
.....

Wie du hier siehst, ja offensichtlich nicht....aber man hat ja uns, bzw. das Forum.

Also mich würde es nerven, wenn bei der kleinsten Änderung das Display gewittert.

Gruß Tommy

Hi,

Zur 'Vollgas-Beleuchtung' - dient dieses 'Aufblitzen' der Aufmerksamkeit?
Also, der Bediener wird optisch drauf hingewiesen, daß sich was geändert hat?

Ja, genauso ist es. Es ist ja kein Aufblitzen, sodern das die HG-Beleuchtung heller wird sobald sich der Status ändert und ne Zeit lang so hell bleibt und nach verstrichener Zeit wieder auf schwache Beleuchtung geht.
Das ist nur der Fall wenn man es nach dem rein kommen, deaktiviert und wenn man es vor dem raus gehen wieder aktiviert. In der Zwischenzeit passiert nichts, also muss es auch nicht mit voller Helligkeit leuchten. Es ist ja nur ein einzeiliges Display mit 16 Zeichen. Viel Text muss nicht angezeigt werden.
Man kann ja die Leuchtdauer auf ne Minute oder noch länger stellen.
Ich hatte schon den Fall das in industriellen Geräten diese LED´s zur HG Beleuchtung durchgebrannt sind,
aber das Display selbst noch OK war. Deswegen habe ich halt diese Idee. Sehe da aber jetzt kein Problem drin. Wenn ich falsch liege, sagt es mir bitte.

LG