[gelöst] Wecheslblinker ohne delay() aber mit pwm #2

Hallo an alle hier

#2 im Subject, weil der Posting-Erstversuch soeben scheinbar nicht funktioniert hat, wenn doch, bitte ich die Dopplung zu entschuldigen.

Ich versuche meinen Wechselblinker-Code schrittweise auszubauen. Diesmal aus bekanntem Grund ohne delay().

Anforderung (vgl. Bahnübergang):
2 LEDs (LED1, LED2) sollen abwechselnd langsam aufleuchten und abdunkeln. Beispiel:
LED1 leuchte langsam auf und dunkelt langsam ab, dabei ist LED2 aus. Danach übt LED2 dies Aktivität aus und LED1 ist aus. Dies solange, wie ein (später zu implementierender Schalter) gedrückt ist.

Folgender Code lässt zumindest eine LED in ansprechender Geschwindigkeit auf- und ableuchten. Allerdings nur eine und das in einer Endlosschleife. Ich scheitere nun daran die 2. LED gemäß der Anforderungen ins Spiel zu bringen.
Ich komme nicht gescheit aus er Schleife raus oder das Timing ist schlecht oder beide LED sind synchron oder ...
Alle Fehlversuche zu posten macht keine Sinn. Es fehlt mir noch ein geeignetes Konzept.
Vielleicht kann mir ja jemand mit einen Ansatz helfen.

Hier das Wesentliche des Codes:

const int LED_1 = 5;
const int LED_2 = 6;

int helligkeit = 1;
int increment = 1; // Das Vorzeichen wechselt und gibt an, ob die LED heller oder dunkler werden soll

unsigned long updateIntervall = 5; // Intervall zwischen Hellligkeitswechesl für langames Auf- bzw. Ableuchten
unsigned long lastUpdate = 0;

void setup() 
{
} 

void loop() 
{
  blink();
}
  
void blink()
{
  unsigned long currentMillis = millis();
  if(currentMillis - lastUpdate >= updateIntervall)
  {
    lastUpdate = millis();
    helligkeit = helligkeit+increment;
     analogWrite(LED_1,helligkeit);
     if(helligkeit >= 255 || helligkeit == 0)
     {
      increment = -increment;
     }
  }
}

Für wohl gemeinte Anregungen bin ich dankbar,

Grüße Dirk

Nimm doch die 2. LED mit rein:

const int LED_1 = 5;
const int LED_2 = 6;

int helligkeit = 1;
int helligkeit2 = 255;
int increment = 1; // Das Vorzeichen wechselt und gibt an, ob die LED heller oder dunkler werden soll

unsigned long updateIntervall = 5; // Intervall zwischen Hellligkeitswechesl für langames Auf- bzw. Ableuchten
unsigned long lastUpdate = 0;

void setup()
{
}

void loop()
{
  blink();
}
 
void blink()
{
  unsigned long currentMillis = millis();
  if(currentMillis - lastUpdate >= updateIntervall)
  {
     lastUpdate = millis();
     helligkeit = helligkeit+increment;
     analogWrite(LED_1,helligkeit);
     helligkeit2 = helligkeit2 - increment;
     analogWrite(LED_2,helligkeit2);
     if(helligkeit >= 255 || helligkeit == 0)
     {
      increment = -increment;
     }
  }
}

Gruß Tommy

Tommy56:
Nimm doch die 2. LED mit rein:

const int LED_1 = 5;

const int LED_2 = 6;

int helligkeit = 1;
int helligkeit2 = 255;
int increment = 1; // Das Vorzeichen wechselt und gibt an, ob die LED heller oder dunkler werden soll

unsigned long updateIntervall = 5; // Intervall zwischen Hellligkeitswechesl für langames Auf- bzw. Ableuchten
unsigned long lastUpdate = 0;

void setup()
{
}

void loop()
{
  blink();
}

void blink()
{
  unsigned long currentMillis = millis();
  if(currentMillis - lastUpdate >= updateIntervall)
  {
    lastUpdate = millis();
    helligkeit = helligkeit+increment;
    analogWrite(LED_1,helligkeit);
    helligkeit2 = helligkeit2 - increment;
    analogWrite(LED_2,helligkeit2);
    if(helligkeit >= 255 || helligkeit == 0)
    {
      increment = -increment;
    }
  }
}




Gruß Tommy

Dank Tommy,
ohne getestet zu haben sieht es mir so aus, dass bei den Code die eine LED heller wird während die andere abdunkelt. das entspricht leider nicht der Anforderung. Während die eine "rumleuchtet" soll die andere ganz aus sein.

Gruß Dirk

const byte LED_1 = 5;
const byte LED_2 = 6;

int helligkeit = 1;
int increment = 1;
byte zyklus = 0;

unsigned long updateIntervall = 5;
unsigned long lastUpdate = 0;

void setup() {
  pinMode(LED_1, OUTPUT);
  pinMode(LED_2, OUTPUT);
}

void loop() {
  unsigned long currentMillis = millis();
  if (currentMillis - lastUpdate >= updateIntervall) {
    lastUpdate = millis();
    helligkeit = helligkeit + increment;
    analogWrite(zyklus % 2 ? LED_2 : LED_1, helligkeit);
    if (helligkeit >= 255) {
      increment = -increment;
    } else if (helligkeit == 0) {
      increment = -increment;
      zyklus++;
    }
  }
}

VWDerby:
Dank Tommy,
ohne getestet zu haben sieht es mir so aus, dass bei den Code die eine LED heller wird während die andere abdunkelt. das entspricht leider nicht der Anforderung. Während die eine "rumleuchtet" soll die andere ganz aus sein.

Gruß Dirk

Ok, dann hatte ich Dich falsch verstanden.

Gruß Tommy

Whandall:

const byte LED_1 = 5;

const byte LED_2 = 6;

int helligkeit = 1;
int increment = 1;
byte zyklus = 0;

unsigned long updateIntervall = 5;
unsigned long lastUpdate = 0;

void setup() {
 pinMode(LED_1, OUTPUT);
 pinMode(LED_2, OUTPUT);
}

void loop() {
 unsigned long currentMillis = millis();
 if (currentMillis - lastUpdate >= updateIntervall) {
   lastUpdate = millis();
   helligkeit = helligkeit + increment;
   analogWrite(zyklus % 2 ? LED_2 : LED_1, helligkeit);
   if (helligkeit >= 255) {
     increment = -increment;
   } else if (helligkeit == 0) {
     increment = -increment;
     zyklus++;
   }
 }
}

Bombe, das funktioniert. Ich versuche jetzt mal das ganze so umzubauen, dass wieder eine separate Funktion daraus wird, die in loop aufgerufen wird.
Parallel dazu versuche ich den Code zu verstehen ...

Danke Dirk

Whandall:

const byte LED_1 = 5;

const byte LED_2 = 6;

int helligkeit = 1;
int increment = 1;
byte zyklus = 0;

unsigned long updateIntervall = 5;
unsigned long lastUpdate = 0;

void setup() {
  pinMode(LED_1, OUTPUT);
  pinMode(LED_2, OUTPUT);
}

void loop() {
  unsigned long currentMillis = millis();
  if (currentMillis - lastUpdate >= updateIntervall) {
    lastUpdate = millis();
    helligkeit = helligkeit + increment;
    analogWrite(zyklus % 2 ? LED_2 : LED_1, helligkeit);
    if (helligkeit >= 255) {
      increment = -increment;
    } else if (helligkeit == 0) {
      increment = -increment;
      zyklus++;
    }
  }
}

Hallo Whandall,

Funktion funktioniert!
Aber folgendes etwas epischer und ich kann es auch verstehen.
1.
analogWrite(zyklus % 2 ? LED_2 : LED_1, helligkeit)

"%2" macht Modulo 2, Ergebnis also immer 0 oder 1
Was macht der kryptische Rest?

Wie/wo schaffst Du es, dass die andere LED immer aus bleibt.

"byte zyklus"
Nach 255 Durchläufen geht es wieder bei 0 los und läuft weiter?

Bitte nicht falsch verstehen, vielen Dank für Deine Code-Ergänzung. Wenn Du mir auf die Sprünge hilfst kapiere ich es schnell, andernfalls brauche ich wohl einen Tag und bin mir hinterher nicht sicher ob ich da komplett richtig liege.

Gruß Dirk

Was macht der kryptische Rest?

( test ?  a : b ) liefert a, wenn test == true, sonst b

(Etwas vereinfacht, hauptsache verständlich)

In deinem Fall werden also abwechselnd LED_2 und LED_1 auf den Wert helligkeitgesetzt.

Nach 255 Durchläufen geht es wieder bei 0 los und läuft weiter?

Ja. Das ist normal und kein Fehler und kann so problemlos verwendet werden.

byte zyklus = 250;
zyklus += 10; // zyklus hat jetzt den Wert 4

michael_x:
( test ?  a : b ) liefert a, wenn test == true, sonst b

(Etwas vereinfacht, hauptsache verständlich)

In deinem Fall werden also abwechselnd LED_2 und LED_1 auf den Wert helligkeitgesetzt.
Ja. Das ist normal und kein Fehler und kann so problemlos verwendet werden.

byte zyklus = 250;

zyklus += 10; // zyklus hat jetzt den Wert 4

Danke !

Hallo,
für u.a. solche Zwecke bei der Modellbahn habe ich mal eine Lib geschrieben, die MobaTools.

Hier der Sketch für einen Wechselblinker ( ist ein Auszug aus einem kompletten beschrankten Bahnübergang mit Schrankensteuerung, Sound und Wechselblinker ) Das weiche Auf/Abblenden macht die Lib. Im Sketch muss man nur ein/ausschalten. Das funktioniert an allen Ports, die müssen nicht PWM-fähig sein.

#include <MobaTools.h>   

// 4. Wechselblinker ----------------------------------------------------
const byte led1P        = 5;        // Ausgänge für den Wechselblinker ( Ports müssen NICHT PWM-fähig sein )
const byte led2P        = 4;
const int wbZykl        = 1200;     // Zykluszeit des Wechselblinkers
const int wbSoft        = 300;      // Auf/Abblendzeit der Lampen

const byte SchalterP    = 7;      // Schaltet den Wechselblinker ein
EggTimer debounce;
const byte debounceTime = 20;

// 4. Wechselblinker ------------------------------------------------------
SoftLed Wblinker[2];    // 2 Leds für den Wechselblinker
EggTimer BlinkerT;
byte wbAktiv = false;   // Flag ob Wechselblinker aktiv ist
byte ledState = LOW;    // Status Wechselblinker
// Zustand Wechselblinker
byte wblZustand = 0;
#define   WBL_AUS     0
#define   WBL_START   1   // Beim Start sind kurz beide Lampen an
#define   WBL_BLINKT  2   

void setup() {
  // put your setup code here, to run once:
    // 4. Wechselblinker ------------------------------------------------------
    Wblinker[0].attach(led1P); // Portzuordnung für den WEchselblinker
    Wblinker[1].attach(led2P);
    Wblinker[0].riseTime(wbSoft); // Weiches Auf/Abblenden der Lampen
    Wblinker[1].riseTime(wbSoft);

    pinMode( SchalterP, INPUT_PULLUP );
    
}

void loop() {
   // put your main code here, to run repeatedly:
    if ( !debounce.running() ) {
        wbAktiv = digitalRead( SchalterP );
        debounce.setTime(debounceTime);
    }
    
    // 4. Wechselblinker ------------------------------------------------------
    /////////////// Wechselblinker (Zustandsautomat ) //////////////////
    switch (wblZustand) {
      case WBL_AUS:
        // Beide Lampen sind aus, warten auf einschalten
        if ( wbAktiv ) {
            // Beide Leds einschalten, Timer für gemeinsames Startleuchten
            Wblinker[0].on();
            Wblinker[1].on();
            BlinkerT.setTime( wbZykl/2 );
            wblZustand = WBL_START;
        }
        break;
      case WBL_START:
        // Startphase: Nach Zeitablauf erste Led wieder aus
        if ( !BlinkerT.running() ) {
            // Übergang zur normalen Blinkphase
            ledState = HIGH;
            Wblinker[1].off();
            BlinkerT.setTime(wbZykl/2);
            wblZustand = WBL_BLINKT;
        }
        break;
      case WBL_BLINKT:
        if ( !BlinkerT.running() ) {
            BlinkerT.setTime(wbZykl/2);
            if ( ledState == LOW ) {
                Wblinker[0].on();
                Wblinker[1].off();
                ledState = HIGH;
            } else {
                ledState = LOW;
                Wblinker[1].on();
                Wblinker[0].off();
            }
        }
        if ( !wbAktiv ) {
            // Wechselblinker abschalten
            Wblinker[0].off();
            Wblinker[1].off();
            wblZustand = WBL_AUS;
        }
        break;
    }
            
}

MicroBahner:
Hallo,
für u.a. solche Zwecke bei der Modellbahn habe ich mal eine Lib geschrieben, die MobaTools.

Hier der Sketch für einen Wechselblinker ( ist ein Auszug aus einem kompletten beschrankten Bahnübergang mit Schrankensteuerung, Sound und Wechselblinker ) Das weiche Auf/Abblenden macht die Lib. Im Sketch muss man nur ein/ausschalten. Das funktioniert an allen Ports, die müssen nicht PWM-fähig sein.

#include <MobaTools.h>   

// 4. Wechselblinker ----------------------------------------------------
const byte led1P        = 5;        // Ausgänge für den Wechselblinker ( Ports müssen NICHT PWM-fähig sein )
const byte led2P        = 4;
const int wbZykl        = 1200;    // Zykluszeit des Wechselblinkers
const int wbSoft        = 300;      // Auf/Abblendzeit der Lampen

const byte SchalterP    = 7;      // Schaltet den Wechselblinker ein
EggTimer debounce;
const byte debounceTime = 20;

// 4. Wechselblinker ------------------------------------------------------
SoftLed Wblinker[2];    // 2 Leds für den Wechselblinker
EggTimer BlinkerT;
byte wbAktiv = false;  // Flag ob Wechselblinker aktiv ist
byte ledState = LOW;    // Status Wechselblinker
// Zustand Wechselblinker
byte wblZustand = 0;
#define  WBL_AUS    0
#define  WBL_START  1  // Beim Start sind kurz beide Lampen an
#define  WBL_BLINKT  2

void setup() {
  // put your setup code here, to run once:
    // 4. Wechselblinker ------------------------------------------------------
    Wblinker[0].attach(led1P); // Portzuordnung für den WEchselblinker
    Wblinker[1].attach(led2P);
    Wblinker[0].riseTime(wbSoft); // Weiches Auf/Abblenden der Lampen
    Wblinker[1].riseTime(wbSoft);

pinMode( SchalterP, INPUT_PULLUP );
   
}

void loop() {
  // put your main code here, to run repeatedly:
    if ( !debounce.running() ) {
        wbAktiv = digitalRead( SchalterP );
        debounce.setTime(debounceTime);
    }
   
    // 4. Wechselblinker ------------------------------------------------------
    /////////////// Wechselblinker (Zustandsautomat ) //////////////////
    switch (wblZustand) {
      case WBL_AUS:
        // Beide Lampen sind aus, warten auf einschalten
        if ( wbAktiv ) {
            // Beide Leds einschalten, Timer für gemeinsames Startleuchten
            Wblinker[0].on();
            Wblinker[1].on();
            BlinkerT.setTime( wbZykl/2 );
            wblZustand = WBL_START;
        }
        break;
      case WBL_START:
        // Startphase: Nach Zeitablauf erste Led wieder aus
        if ( !BlinkerT.running() ) {
            // Übergang zur normalen Blinkphase
            ledState = HIGH;
            Wblinker[1].off();
            BlinkerT.setTime(wbZykl/2);
            wblZustand = WBL_BLINKT;
        }
        break;
      case WBL_BLINKT:
        if ( !BlinkerT.running() ) {
            BlinkerT.setTime(wbZykl/2);
            if ( ledState == LOW ) {
                Wblinker[0].on();
                Wblinker[1].off();
                ledState = HIGH;
            } else {
                ledState = LOW;
                Wblinker[1].on();
                Wblinker[0].off();
            }
        }
        if ( !wbAktiv ) {
            // Wechselblinker abschalten
            Wblinker[0].off();
            Wblinker[1].off();
            wblZustand = WBL_AUS;
        }
        break;
    }
           
}

Danke Franz-Peter,
habe Dir eine PM gesendet
Dirk