fade millis

hallo

zerbreche mir momentan den Kopf mit mit diesem Sketch.
Ein Bewegunglsmelder schaltet Nachts das Licht bei bewegung an, welches sicht nach zeit x gedimmt ausschaltet.
Mit Delay funkt es, leider nicht mit millis. Finde leider den Ausschalt/Einschalt Punkt nicht.
Würde es gerne auch verstehen wollen.

///----Arduino 
int eingang= A1;        
int S1 = 3;         //Beleuchtung         
int PIR_led = 4;    //Kontroll LED         
int PIR = 3;       

int brightness = 0;    // how bright the LED is
int fadeAmount = 5;    // how many points to fade the LED by
unsigned long currentTime;
unsigned long loopTime;

int sensorWert = 0;     
long previousMillis = 0; long previousMillis_2 = 0;
int Beleuchtung = 0;
int PIR_state_2    = 0;

void setup()

{

Serial.begin(9600);

pinMode(PIR, INPUT); 
pinMode (PIR_led, OUTPUT);
pinMode (S1, OUTPUT);
pinMode(9, OUTPUT);
currentTime = millis();
loopTime = currentTime; 

}

 

void loop()

{
Bewegungsmelder();

fade();
sensorWert =analogRead(eingang);

Serial.print("Sensorwert = " );
Serial.println(sensorWert);

}//-ende loop

void Bewegungsmelder()
{
  unsigned long now = millis();
 
  //Einschaltbedingung Beleuchtung  

if (( digitalRead(PIR) == HIGH) && (sensorWert < 100) )
  {
    //previousMillis = now;
     Beleuchtung = 1;      
    //digitalWrite(S1, HIGH);
// fadeIn();                            
    for(int fadeValue = 0 ; fadeValue <= 255; fadeValue +=2) {
    // sets the value (range from 0 to 255):
    analogWrite(S1, fadeValue);        
    // wait for 30 milliseconds to see the dimming effect    
   delay(50);                            
  }
   
  }
//Auschalt bedingung Beleuchtung                        
  if ((now - previousMillis_2 > 10000)  && (Beleuchtung == 1)) 
  {
    previousMillis_2 = now;
    Beleuchtung = 0; 
   // digitalWrite(S1, LOW);
    // fade out from max to min in increments of 5 points:
 //fadeOut();
   for(int fadeValue = 255 ; fadeValue >= 0; fadeValue -=3) {
    // sets the value (range from 0 to 255):
    analogWrite(S1, fadeValue);        
    // wait for 30 milliseconds to see the dimming effect    
    delay(50);                            
  } 
    
  }
if ( digitalRead(PIR) == HIGH ){ digitalWrite(PIR_led, HIGH);   }
else{ digitalWrite(PIR_led, LOW);  }


}//-----------------------Bewegungsmelder end
//quelle http://www.hobbytronics.co.uk/arduino-tutorial5-fade
void fade()  { 
  currentTime = millis();
  if(currentTime >= (loopTime + 20)){  
    // set the brightness of pin 9:
    analogWrite(9, brightness);    

    // change the brightness for next time through the loop:
    brightness = brightness + fadeAmount;

    // reverse the direction of the fading at the ends of the fade: 
    if (brightness == 0 || brightness == 255) {
      fadeAmount = -fadeAmount ; 
    }     
    loopTime = currentTime;  // Updates loopTime
  }
  // Other processing can be done here
                           
}///end fade
int S1 = 3;         //Beleuchtung         
int PIR_led = 4;    //Kontroll LED         
int PIR = 3;       
...
pinMode(PIR, INPUT); 
pinMode (PIR_led, OUTPUT);
pinMode (S1, OUTPUT);

Pins doppelbelegen ist keine gute Idee. Spendiere dem PIR Ausgang ein eigenes Arduino Eingangs Pin.

brightness = brightness + fadeAmount;

    // reverse the direction of the fading at the ends of the fade: 
    if (brightness == 0 || brightness == 255) {

Da fadeAmount eine Variable ist, die auch verschieden von 1 oder 5 sein kann, ist es besser die Bedingung nicht auf Gleichheit sondern größer gleich bzw kleiner gleich zu prüfen.

Der Sketch verwendet sowohl ein for mit delay() Faden als auch ein millis() Faden. Entscheide Dich für das Zweite.

grüße Uwe

hallo Uwe

int S1 = 3;         //Beleuchtung         
int PIR_led = 4;    //Kontroll LED         
int PIR = 3;       
...
 // initialize the LED pin as an output:
pinMode(PIR, INPUT); 
pinMode (PIR_led, OUTPUT);
pinMode (S1, OUTPUT);

pinMode sollte man zum initializern nutzen!

Der Sketch verwendet sowohl ein for mit delay() Faden als auch ein millis() Faden. Entscheide Dich für das Zweite.

natürlich würde ich nur millis() Faden benutzen.
nur habe ich eine eine endlos wiederholung. Das Faden soll gestartet werden-volle leistung gehalten-Faden ausschalten.
wie bekomme ich diese unterbrechung nun hin.
dank im vorraus.
karl

Ist Pin 3 nun ein Eingang oder ein Ausgang ??
Grüße Uwe

int S1 = 3;         //Beleuchtung         
int PIR_led = 4;    //Kontroll LED         
int PIR = 2;  //PIR Eingang

sorry, jetzt habe ich es gesehen und geändert.
Kann das zur zeit nicht testen.

leider bekomme ich immer noch keine Unterbrechung zwischen FadeIn und FadeOut.
ich bitte um hilfe.
gruß
karl

Ich hab auch mal kurz drübergeschaut und Bewegungsmelder() macht 256*50 ms delay.

In diesen 12,8 Sekunden findet natürlich kein fade statt.

Meinen Beitrag von gestern abend habe ich gelöscht, um heute gezielter helfen zu können. Ich habe den Sketch verändert, um zu sehen, wie es gehen könnte.

const unsigned int fadeAmount = 5;    // how many points to fade the LED by
int fadeValue;
const unsigned int loopTime = 10;
long previousMillis;
unsigned int sensorWert;
byte status;
enum ZUSTAENDE {TAG, NACHT_LED_AUS, NACHT_LED_HELLER, NACHT_LED_AN, NACHT_LED_DUNKLER};

void setup() {
  pinMode(PIR, INPUT_PULLUP);  // PIR Eingang
  pinMode(TN, INPUT_PULLUP);   // Test Tag/Nacht Eingang anstelle analogem Wert
  pinMode (TN_LED, OUTPUT);    // Tag == An; Nacht == Aus
  pinMode (S1, OUTPUT);        // Fade-LED 100% == An; Fade-LED 0% == Aus
  pinMode(FADE_led, OUTPUT);   // Fade-LED
  if (sensorWert < 100) {
    status = NACHT_LED_AUS;
  } else {
    status = TAG;
  }
}

void loop() {
  if (digitalRead(TN) == HIGH) {  // Test Tag/Nacht Eingang anstelle analogem Wert
    sensorWert = 150;
  } else {
    sensorWert = 5;
  }
  if (sensorWert > 110) {
    status = TAG;
  }
  switch (status) {
    case TAG:
      fadeValue = 0;
      analogWrite(FADE_led, fadeValue);
      digitalWrite(TN_LED, HIGH);
      if (sensorWert < 100) {
        status = NACHT_LED_AUS;
      }
      break;
    case NACHT_LED_AUS:
      digitalWrite(S1, LOW);
      digitalWrite(TN_LED, LOW);
      if (digitalRead(PIR) == HIGH) {
        status = NACHT_LED_HELLER;
      }
      break;
    case NACHT_LED_HELLER:
      if (millis() > previousMillis + loopTime) {
        fadeValue += fadeAmount;
        if (fadeValue > 255) {
          fadeValue = 255;
          status = NACHT_LED_AN;
        }
        analogWrite(FADE_led, fadeValue);
        previousMillis = millis();
      }
      break;
    case NACHT_LED_AN:
      digitalWrite(S1, HIGH);
      if (digitalRead(PIR) == LOW) {
        status = NACHT_LED_DUNKLER;
      }
      break;
    case NACHT_LED_DUNKLER:
      if (millis() > previousMillis + loopTime) {
        fadeValue -= fadeAmount;
        if (fadeValue < 5) {
          fadeValue = 0;
          status = NACHT_LED_AUS;
        }
        analogWrite(FADE_led, fadeValue);
        previousMillis = millis();
      }
  }
}//-ende loop

Leider habe ich gerade bemerkt, dass am Anfang des Hellerwerdens der LED (FADE_led) diese kurz aufblitzt. Nun finde ich meinen Fehler nicht. Probiert habe ich mit ATtiny 4313, daher eine andere Pinbelegung. Und im Zweifel habe ich int genommen :wink:
Wenn jemand einen besseren Ansatz hat, schmeiße ich diesen Code auch wieder raus.

agmue:
Meinen Beitrag von gestern abend habe ich gelöscht, um heute gezielter helfen zu können. Ich habe den Sketch verändert, um zu sehen, wie es gehen könnte.

const unsigned int fadeAmount = 5;    // how many points to fade the LED by

int fadeValue;
const unsigned int loopTime = 10;
long previousMillis;
unsigned int sensorWert;
byte status;
enum ZUSTAENDE {TAG, NACHT_LED_AUS, NACHT_LED_HELLER, NACHT_LED_AN, NACHT_LED_DUNKLER};

void setup() {
 pinMode(PIR, INPUT_PULLUP);  // PIR Eingang
 pinMode(TN, INPUT_PULLUP);   // Test Tag/Nacht Eingang anstelle analogem Wert
 pinMode (TN_LED, OUTPUT);    // Tag == An; Nacht == Aus
 pinMode (S1, OUTPUT);        // Fade-LED 100% == An; Fade-LED 0% == Aus
 pinMode(FADE_led, OUTPUT);   // Fade-LED
 if (sensorWert < 100) {
   status = NACHT_LED_AUS;
 } else {
   status = TAG;
 }
}

void loop() {
 if (digitalRead(TN) == HIGH) {  // Test Tag/Nacht Eingang anstelle analogem Wert
   sensorWert = 150;
 } else {
   sensorWert = 5;
 }
 if (sensorWert > 110) {
   status = TAG;
 }
 switch (status) {
   case TAG:
     fadeValue = 0;
     analogWrite(FADE_led, fadeValue);
     digitalWrite(TN_LED, HIGH);
     if (sensorWert < 100) {
       status = NACHT_LED_AUS;
     }
     break;
   case NACHT_LED_AUS:
     digitalWrite(S1, LOW);
     digitalWrite(TN_LED, LOW);
     if (digitalRead(PIR) == HIGH) {
       status = NACHT_LED_HELLER;
     }
     break;
   case NACHT_LED_HELLER:
     if (millis() > previousMillis + loopTime) {
       fadeValue += fadeAmount;
       if (fadeValue > 255) {
         fadeValue = 255;
         status = NACHT_LED_AN;
       }
       analogWrite(FADE_led, fadeValue);
       previousMillis = millis();
     }
     break;
   case NACHT_LED_AN:
     digitalWrite(S1, HIGH);
     if (digitalRead(PIR) == LOW) {
       status = NACHT_LED_DUNKLER;
     }
     break;
   case NACHT_LED_DUNKLER:
     if (millis() > previousMillis + loopTime) {
       fadeValue -= fadeAmount;
       if (fadeValue < 5) {
         fadeValue = 0;
         status = NACHT_LED_AUS;
       }
       analogWrite(FADE_led, fadeValue);
       previousMillis = millis();
     }
 }
}//-ende loop



Leider habe ich gerade bemerkt, dass am Anfang des Hellerwerdens der LED (FADE_led) diese kurz aufblitzt. Nun finde ich meinen Fehler nicht. Probiert habe ich mit ATtiny 4313, daher eine andere Pinbelegung. Und im Zweifel habe ich int genommen ;) 
Wenn jemand einen besseren Ansatz hat, schmeiße ich diesen Code auch wieder raus.

Leider funktioniert das nicht. Weiß nicht weiter.

karl77:
Leider funktioniert das nicht. Weiß nicht weiter.

Was funktioniert nicht? Compiler, Logik, Rauchwolken?

PS.: Wenn Du meinen Text wiederholst, finde ich das ja nett, muss aber nicht sein, steht ja ein paar Zentimeter darüber. :slight_smile:

danke dir habe es nun hin bekommen mit einer Ausschaltverzögerung.

const unsigned int fadeAmount = 5;    // how many points to fade the LED by
int fadeValue;
const unsigned int loopTime = 10;
long previousMillis;
unsigned int sensorWert;
byte status;
int eingang= A1;        
int S1 = 3;         //Beleuchtung         
int PIR_led = 13;    //Kontroll LED         
int PIR = 2;    
int TN  = 10;
int TN_LED = 11;
int FADE_led = 9;
enum ZUSTAENDE {TAG, NACHT_LED_AUS, NACHT_LED_HELLER, NACHT_LED_AN, NACHT_LED_DUNKLER};

void setup() {                  /// TN = TestNacht??
  pinMode(PIR, INPUT_PULLUP);  // PIR Eingang
  pinMode(TN, INPUT_PULLUP);   // Test Tag/Nacht Eingang anstelle analogem Wert
  pinMode (TN_LED, OUTPUT);    // Tag == An; Nacht == Aus
  pinMode (S1, OUTPUT);        // Fade-LED 100% == An; Fade-LED 0% == Aus
  pinMode(FADE_led, OUTPUT);   // Fade-LED
  if (sensorWert < 100) {    /// start anfangszustand 
    status = NACHT_LED_AUS;    ///NACHT_LED_AUS ????
  } else {
    status = TAG;
  }
}

void loop() {
  if (digitalRead(TN) == HIGH) {  // Test Tag/Nacht Eingang anstelle analogem Wert
    sensorWert = 150;
  } else {
    sensorWert = 5;
  }
  if (sensorWert > 110) {
    status = TAG;
  }
  switch (status) {
    case TAG:
      fadeValue = 0;
      analogWrite(FADE_led, fadeValue);
      digitalWrite(TN_LED, HIGH);
      if (sensorWert < 100) {
        status = NACHT_LED_AUS;
      }
      break;
    case NACHT_LED_AUS:
      digitalWrite(S1, LOW);
      digitalWrite(TN_LED, LOW);
      if (digitalRead(PIR) == HIGH) {
        status = NACHT_LED_HELLER;
      }
      break;
    case NACHT_LED_HELLER:
      if (millis() > previousMillis + loopTime) {
        fadeValue += fadeAmount;
        if (fadeValue > 255) {
          fadeValue = 255;
          status = NACHT_LED_AN;
        }
        analogWrite(FADE_led, fadeValue);
        previousMillis = millis();
      }
      break;
    case NACHT_LED_AN:
      digitalWrite(S1, HIGH);
       if (millis() - previousMillis > 2000) {
        
         if (digitalRead(PIR) == LOW) {
        status = NACHT_LED_DUNKLER;
      }
        
        previousMillis = millis();
      }
      

      break;
      
      
    case NACHT_LED_DUNKLER:
      if (millis() > previousMillis + loopTime) {
        fadeValue -= fadeAmount;
        if (fadeValue < 5) {
          fadeValue = 0;
          status = NACHT_LED_AUS;
        }
        analogWrite(FADE_led, fadeValue);
        previousMillis = millis();
      }
  }
  
  if ( digitalRead(PIR) == HIGH ){ digitalWrite(PIR_led, HIGH);   }
else{ digitalWrite(PIR_led, LOW);  }

}//-ende loop

Gratuliere! :slight_smile:

  if (digitalRead(TN) == HIGH) {  // Test Tag/Nacht Eingang anstelle analogem Wert
    sensorWert = 150;
  } else {
    sensorWert = 5;
  }

Kann weg, ersetzen durch

sensorWert = analogRead(A1);

Du wollst doch mit A1 messen, ob es Tag oder Nacht ist, oder? Der Eingang TN ist dann überflüssig.

das habe auch schon gemacht. nun das was ich benötige behalten.