Wie setze ich die dauer einer action?

Hallo Community,

Habe hier ein Uno, einen BMP085, DHT22,RTC(kommt später), Pir Sensor und ein 20x4 LCD Display für eine Wetterstation.
Das auslesen der Daten und die Anzeige auf dem LCD hab ich auch hinbekommen.
Nun soll noch die Hintergrundbeleuchtung vom LCD für 20 sec. angehen wen der PIR Bewegung meldet.
Und da hänge ich fest. Aktuell benutze ich den befehl delay(20000), LCD geht dann auch für 20 sec an aber die Sensordaten aktualisieren sich auch 20 sec. lang nicht da der loop ja wartet. Wegen der Sensordaten(Temp,Luftdruck...) weiter nicht schlimm, aber wenn eine Uhr dazu soll geht das so nicht. Da programmieren noch neuland für mich ist (bin Elektriker) habe ich den sketch aus samples anderer sketche(s?) zusammengeschustert.
Meine Frage; wie bestimme ich die dauer von lcd.backlight() ohne die anzeige der Sensordaten damit zu beeinflussen?
Anbei der sketch den ich benutze.

#include <Wire.h> 
#include <LiquidCrystal_I2C.h>
#include "DHT.h"
#include <Adafruit_Sensor.h>
#include <Adafruit_BMP085_U.h>
#define DHTPIN 4
LiquidCrystal_I2C lcd(0x3F,20,4);  // set the LCD address to 0x27 for a 16 chars and 2 line display

#define DHTTYPE DHT22
// Connect pin 1 (on the left) of the sensor to +5V
// Connect pin 2 of the sensor to whatever your DHTPIN is
// Connect pin 4 (on the right) of the sensor to GROUND
// Connect a 10K resistor from pin 2 (data) to pin 1 (power) of the sensor

int inputPin = 2;               // choose the input pin (for PIR sensor)
int pirState = LOW;             // we start, assuming no motion detected
int val = 0;                    // variable for reading the pin status

DHT dht(DHTPIN, DHTTYPE);
Adafruit_BMP085_Unified bmp = Adafruit_BMP085_Unified(10085);



void setup()
{
  pinMode(inputPin, INPUT);     // declare sensor as input
  bmp.begin();
  sensor_t sensor;
  bmp.getSensor(&sensor);
  lcd.init();                      // initialize the lcd 
  lcd.init();
  
}


void loop(){
  
  sensors_event_t event;
  bmp.getEvent(&event);  //Starts BMP085
  
  float h = dht.readHumidity();
  float t1 = dht.readTemperature();
  
  /* Calculating altitude with reasonable accuracy requires pressure    *
     * sea level pressure for your position at the moment the data is     *
     * converted, as well as the ambient temperature in degress           *
     * celcius.  If you don't have these values, a 'generic' value of     *
     * 1013.25 hPa can be used (defined as SENSORS_PRESSURE_SEALEVELHPA   *
     * in sensors.h), but this isn't ideal and will give variable         *
     * results from one day to the next.                                  *
             
    /* First we get the current temperature from the BMP085 */
  float seaLevelPressure = 1020; //Value to change to SLP
  float temperature;
    bmp.getTemperature(&temperature);
  pinMode(inputPin, INPUT); // Set Pirpin to INPUT
  
  if(digitalRead(inputPin) == HIGH) //PIR On
  {
    lcd.backlight(); //Backlight On
    lcd.setCursor(2, 0);
    lcd.print("Uhrzeit + Datum"); // Time From RTC
    lcd.setCursor(0, 1);
    lcd.print("H:");
    lcd.print(h);
    lcd.print("%");
    lcd.setCursor(9, 1);
    lcd.print("Alt:");
    lcd.print(bmp.pressureToAltitude(seaLevelPressure,
                                        event.pressure,
                                        temperature));  //Altitude from BMP085
    lcd.print("m");
    lcd.setCursor(0, 2);
    lcd.print("Temp:");
    lcd.print(t1); //Temp from DHT22
    lcd.print("C");
    lcd.setCursor(11, 2);
    lcd.print(" - ");
    lcd.print(temperature); // Temp from BMP085
    lcd.print("C");
    lcd.setCursor(3, 3);
    lcd.print("PR: ");
    lcd.print(event.pressure); // Pressure from BMP085
    lcd.print(" hPa");
    delay(20000); //Time the Display is On
   
  }
  else {
  }
  lcd.noBacklight(); //backlight Off
  lcd.clear();
}

mit millis(); siehe blink without delay beispel.
Grüße Uwe

Hallo uwefed,
erstmal, danke für deine Antwort.
Hatte natürlich Onkel Google schon gefragt und zB. das hier :Arduino Playground - BlinkWithoutDelayDe
gefunden.
Aber ich verstehe es nicht: :blush:

denilo:
Und da hänge ich fest. Aktuell benutze ich den befehl delay(20000), LCD geht dann auch für 20 sec an aber die Sensordaten aktualisieren sich auch 20 sec. lang nicht da der loop ja wartet. Wegen der Sensordaten(Temp,Luftdruck...) weiter nicht schlimm, aber wenn eine Uhr dazu soll geht das so nicht.

Ja, "delay" ist ein Befehl zum Blockieren der Programmausführung für eine bestimmte Zeit.

Für Programme, die nicht blockiert werden sollen, ist delay völlig ungeeignet.

denilo:
Meine Frage; wie bestimme ich die dauer von lcd.backlight() ohne die anzeige der Sensordaten damit zu beeinflussen?

Ohne delay natürlich. Am besten deklarierst Du Dir oberhalb der loop-Funktion sowas in der Art:

#define BACKLIGHTDURATION 20000L  // Anzahl Millisekunden Einschaltzeit
boolean backlightOn=false;
unsigned long backlightOnTime=0;  // Einschaltzeitpunkt in Millisekunden

Und in der loop behandelst Du es dann ungefähr so (ungetestet hingeschrieben):

void loop() {
  // Irgendwas an Code
  if (backlightOn && millis()-backlightOnTime>BACKLIGHTDURATION)
  {
    lcd.noBacklight(); //backlight Off
    backlightOn=false;
  }
  else if (!backlightOn && digitalRead(inputPin))
  {
    lcd.backlight(); // backlight on
    backlightOn=true;
    backlightOnTime=millis();
  }
  // Noch irgendwas anderes an Code
}

Funktioniert's?

It works. :slight_smile:

Hallo jurs, genau so gehts. Musste noch eine zeile lcd.backlight() im loop entfernen die ich da unbeachtet rumliegen gelassen habe.
Muss mich jetzt unbedingt intensiver mit der Programmierung beschäftigen.

Danke jurs. You made my day. :smiley: