3LED's fade in/out Übergang

Hallo an das Forum,

ich bin seit kurzem ein stolzer Besitzer eines Arduino Uno aber leider noch nicht so sicher im programmieren.

Ich wollte "eigentlich" eine scheinbar simple Sache realisieren, doch stoße ich auf Granit.

Die Aufgabenstellung war:

3 LED's, die erste fade in in 2 Sekunden, dann 10 Sekunden an und dann fade out in 2 Sekunden. In den fadeout nach 1 Sekunde der ersten LED soll das fade in (2 Sekunden) der zweiten LED gestartet werden. Diese soll dann wieder 10 Sekunden an sein, danach fade out 2 Sekunden und in den fade out der LED nach 1 Sekunde den fade in der dritten LED. Diese auch 10 Sekunden an, fade out 2 Sekunden und fade in der ersten.

Im Moment kann ich auf Grund des delay erst nach kompletter Beendingung des fade out Vorganges mit dem starten des fade in Vorganges starten.

Gibt es hier eine einfache Lösung oder einen Beispielcode?

Bin für alles dankbar.

Beste Grüße

Toni14:
3 LED's, die erste fade in in 2 Sekunden, dann 10 Sekunden an und dann fade out in 2 Sekunden. In den fadeout nach 1 Sekunde der ersten LED soll das fade in (2 Sekunden) der zweiten LED gestartet werden. Diese soll dann wieder 10 Sekunden an sein, danach fade out 2 Sekunden und in den fade out der LED nach 1 Sekunde den fade in der dritten LED. Diese auch 10 Sekunden an, fade out 2 Sekunden und fade in der ersten.

??? Ich verstehe da nur Bahnhof.

Toni14:
Im Moment kann ich auf Grund des delay erst nach kompletter Beendingung des fade out Vorganges mit dem starten des fade in Vorganges starten.

Gibt es hier eine einfache Lösung oder einen Beispielcode?

Mit delay wäre das sicherlich auch machbar. Jedoch sollte man direkt von Anfang an versuchen, diese "Technik" zu verwenden. Zumal es in diesem Fall vermutlich auch einfacher geht ohne Delay.

Da ich aber die Anweisung von oben nicht verstanden habe, weiß ich nicht, ob es so gedacht ist.

Der Trick selber nennt sich erst einmal das Tutorial Blink Without Delay zu verinnerlichen.

Danach kann man einzelne Funkionen aufbauen
Lediglich PseudoCode

switch(step) {
case 0:
step += function1();
break;

case 1:
step += function2();
break;
...
}

int function1() {
int intervall = 100;
static int i; // fade
static unsigned long lastMillis;

if(millis() - lastMillis >= intervall) {
lastMillis = millis();
  if(i < 255) {
  // solange ausführen bis i == 255 ist.
  }
  else return 1;
  }
}

Hallo,

danke für die Antwort.

es geht mir darum das sich das Fade out/fade in überschneiden. Wenn die eine LED zu 70% aus ist soll die nächste schon zu 30% an sein. Im Moment ist es bei mir erst komplett aus bevor die nächste wieder angeht.

Kannst du mir bitte den Code erklären?

Beste Grüße

Du könntest auch die SoftPWM Lib benutzen.
Da gibt es von vornherein die Möglichkeiten fadin und fadeout Zeiten einzustellen usw.

Allerdings ist die eher dafür gedacht, wenn alle Hardware PWM-Ausgänge bereits belegt sind.

Hallo,

nach einer Nacht schlafen reduziert sich das Problem auf die Frage, wie bekomme ich mit "Blink without delay" einen fade in und fade out hin welche sich überschneiden.

Ich möchte das ganze halt auch verinnerlichen, um nicht immer zu "dumme" Fragen hier zu stellen. :slight_smile:

Gruß

Schau einfach in meinen Blog. Da gibt es jede Menge an Beispielen, das was Du willst findest Du in verschiedenen Varianten hier: Basic Effects | Blinkenlight.

Hallo Udo,

habe in deinem Blog geschaut, aber "scheinbar" nicht das richtige gefunden. Habe nun mal versucht einen zeitlichen Verlauf aufzuzeichnen, damit man besser verstehen kann was ich möchte.

Diese zeitliche Abfolge soll laufen bis der Arduino keine Spannung mehr hat.

Gruß

Einen fertigen Code wird dir keiner Schreiben. Wenn das Projekt zu schwer ist, fang mit kleineren an.

Das sollte dir genügen zur Veranschaulichung. Zum leuchten wird es deine Leds nicht. Das solltest du schon selber herausfinden wie das geht.

Ansonsten mit 3 Leds kann man sich auch mal die Sinusfunktionen anschauen (-> Drehstromtechnik)

void loop() {
  static unsigned long lastMillis;
  static int counter;
  const int interval = 100;
  int pwmFade[3][5] = {
    {0,1,2,3,4},
    {5,0,1,2,3},
    {4,5,0,1,2}
  };


  if(millis() - lastMillis >= interval)
  {
    lastMillis = millis();

    analogWrite(LED1, pwmfade[1][counter]);
    analogWrite(LED2, pwmfade[2][counter]);
    analogWrite(LED3, pwmfade[3][counter]);

    counter++;
    if(counter > 5) counter = 0;
  }
}

Toni14:
Gibt es hier eine einfache Lösung oder einen Beispielcode?

Ja klar gibt es Beispielcode!

Um drei LEDs nacheinander abzuarbeiten, schaue Dir Beispiele für for-Schleifen an!

Und um zyklische Steuervorgänge durchzuführen, müßtest Du ertmal haben:

  • die Gesamtdauer eines Steuerzyklus
  • die Startzeit eines Steuerzyklus
  • und Dir dann für jede Millisekunde innerhalb des Zyklus die zu steuernden Werte ausrechnen
    Gesteuert wird dann nach Zeitablauf über den Stand des millis() Timers.

Gesamtdauer eines Steuerzyklus wie von Dir beschrieben:
3 LEDs mal (2 Sekunden Fade-In plus 10 Sekunden Dauerlicht + 2 Sekunden Fade-Out) = 3*14 = 42 Sekunden
Abzüglich der Zyklenüberschneidung beim Faden von 1s beim Fade-In/Out = 42-3 = 39 Sekunden
Also alle 39 Sekunden wiederholt sich ein Steuerzyklus.

Die Logik für die Startzeit eines Zyklus ist dann einfach (alteStartzeit+39000L).
Aus dem Stand des millis() Timers minus Startzeit des Zyklus bekommst Du einen Wert zwischen 0 und 39000, und Du brauchst jetzt nur noch eine Funktion schreiben, der Du diese Zykluszeit als Parameter übergibst und die zu jeder Zeit den Helligkeitswert der drei LEDs ausrechnet.

Was einfacheres war für mich diese Steuerung ohne Überschneidung. Dachte nicht das wenn sich fade in/fade out überschneiden es so ein großes Thema gibt.

Will es ja auch gerne selber herrausfinden.

z.B. die erklärung für
int pwmFade[3][5] = {
{0,1,2,3,4},
{5,0,1,2,3},
{4,5,0,1,2}

Gruß

Das

  int pwmFade[3][5] = {
    {0,1,2,3,4},
    {5,0,1,2,3},
    {4,5,0,1,2}
  };

gehört mit dem

    analogWrite(LED1, pwmfade[1][counter]);
    analogWrite(LED2, pwmfade[2][counter]);
    analogWrite(LED3, pwmfade[3][counter]);

zusammen

Ok, das habe ich verstanden.

Frage dazu: Kann ich das array automatisch füllen, wenn ich wie hier Werte von 0-255 benötige? Mit der Hand eintragen ist schon eher mühsam.

Gruß

255 Werte pro Led wirst du nicht haben. Schau dir dazu mal
http://www.mikrocontroller.net/articles/LED-Fading

const int pwmtable[32] =
{
    0, 1, 2, 2, 2, 3, 3, 4, 5, 6, 7, 8, 10, 11, 13, 16, 19, 23,
    27, 32, 38, 45, 54, 64, 76, 91, 108, 128, 152, 181, 215, 255
};

Die musst du halt nun in den entsprechenden Versatz bringen.

Hatte 255 mit 5 Schritten. Das waren dann auch 52 Werte. :slight_smile:

Kann man diesen Versatz mit einer Variable dann auch verschieben? z.B. wenn ich heute den Überlapp bei 30% habe diesen auf 50 zu schieben?

Wenn Du kein Beispiel in meinem Blog gefunden hast, dann hast Du nicht richtig gesucht. Schau Dir mal das hier an:

Das ist im Prinzip Deine Anforderung nur eben mit 20 statt mit 3 LEDs.

Ok, sorry.

Wie gesagt ich habe noch nicht soviel Erfahrung und konnte es den Code nicht wirklich entnehmen.

Versuche mich aber nun explicit mit diesen Code auseinander zu setzen.

Kann ich bei Fragen auf dich zurück kommen?

Gruß

Fragen immer ins Forum. Die Antworten sind ja auch für andere Mitleser interessant.

Verschieben kannst du das ganze auch, dann wäre es aber sinnvoller, sich eine kleine Funktion mit einer Modulo-Berechnung anzulegen.
Das hier unten ist ein Beispiel (der Teil sollte funktionieren, muss aber nicht). Damit solltest du das ohne Probleme hinbekommen. Wenn nicht, fehlen dir defentiv mehr Grundlagen als gedacht.

// Korrigiert die fehlerhaften Zugriffe
int index(int value, int max_value)
{
	if(value >= max_value) value = value % max_value;
	else if(value < 0) value = max_value - value;
	
	return value;
}
void loop()
{
	const int pwmtable[30] =
	{
		0, 1, 2, 2, 2, 3, 3, 4, 5, 6, 7, 8, 10, 11, 13, 16, 19, 23,
		27, 32, 38, 45, 54, 64, 76, 91, 108, 128, 152, 181
	};

	static unsigned long lastMillis;
	static int counter;

	if(millis() - lastMillis >= interval)
	{
		lastMillis = millis();
		counter++;
		if(counter >= 30) counter = 0;

		analogWrite(LED1, pwmFade[index(counter+0, 30)];
		analogWrite(LED1, pwmFade[index(counter+10, 30)];
		analogWrite(LED1, pwmFade[index(counter+20, 30)];
	}
}

Hallo,

@Udo:klar würde ich diese Fragen hier im Forum stellen.

@sschultewolter: Versuche dein Beispiel umzusetzen. Im Moment kann ich halt das tun was ich wollte außer eben die beiden LED Fade's zu überschneiden. Kann ja auch mal meinen Programmcode posten.

Ja mir fehlt da schon einiges an Grundlagen. Wie gesagt, habe den Arduino erst 1 Monat und habe bislang immer nur einfache digitale Programme geschrieben. Etwas Erfahrung hatte ich vor ein paar Jahren einer Siemens S7-200 SPS gesammelt. Diese war für solche Ablaufsteuerungen einfacher zu handeln. Aber nicht jammern, sondern Erfahrungen sammeln...:slight_smile:

Viele Grüße

Siemens S7 Programmierung hat eigentlich so gut wie garnichts mit der MCU Programmierung am Hut. Weder ist es einfacher noch ist es schwieriger. Habe selber nie eine S7-200 programmiert, lediglich die Logo zu privaten Testzwecken und in der Firma diverse S7-3xx Systeme.

Mein Kenntnisstand von damals, Logo ist zum Programmierung lediglich was für Anfänger! Die Programmierung über FUP und KOP ist mehr als ein Grauß für einen Programmierer. Zeilenbasierte Sprachen gab es soweit ich weiß weder in der Orginale Logo Soft noch als alternative IDE.

Bei der S7 selber bin ich mir nicht ganz sicher. Zum einen ging auch hier defentiv wieder der FUP, was nichts besser ist, ausser das hier eine Aufteilung einzelner Netzwerke möglich war. Eine richtige Hochsprache gab es zumindest bis Step7 nicht.

Wie das bei dem aktuellen TIA aussieht, weiß ich nicht. Inzwischen nur noch mit B+R Systemen etwas zu tun. Die lassen sich in verschiendenen Hochsprachen sowie auch FUP programmieren.

Was genau bezeichnest du als Ablaufsteuerung? Die typischen Ablaufsteuerung GRAPH sind auch mit Arduino möglich. Dafür gibt es switch. if/else Verknüpfungen sind ebenfalls problemlos möglich.

Der Vorteil, den viele Steuerung haben, ist lediglich, dass diese meist Leistungsstärker und Multithreading(unterschiedliche Task-Cycles) können.