Go Down

Topic: OOP mit einem Kringel zu viel? (Read 1 time) previous topic - next topic

agmue

Jul 27, 2018, 09:01 am Last Edit: Jul 27, 2018, 10:43 am by agmue
Angeregt durch ein anderes Thema und @noiasca  "Also das Aufleuchten eines kleinen Punktes als Funke von der Zündkerze und dann das verzögerte Ausbreiten der Flamme im Brennraum." wollte ich das mal ausprobieren, wie es aussieht. Die weißen LED von RGBW machen sich als Zündfunke ganz gut, finde ich. Aber auch wenn das meine Motivation war, so geht es mir in diesem Thema um "richtiges" Programmieren.

Mangels Hardware habe ich jedem Zylinder nur einen Lichtpunkt (nach Adafruit "Pixel" genannt) zugeordnet. Die einzelnen Schritte:
  • Blau von 0 nach 255 faden
  • weißer Blitz
  • Rot von 255 nach 0 faden
  • kurze Pause alle Farben aus

Das Programm tut, was es soll.

Frage 1: Hat das Programm Fehler?

Frage 2: Ich habe das Gefühl, irgendwas zu kompliziert gemacht zu haben. Ist das so?

Code: [Select]
#include <Adafruit_NeoPixel.h>

#define NEOPIN 6
#define ANZAHLDERPIXEL 7  // hier müßte 42 stehen
#define PIXELPROZYL 1     // hier müßte 7 stehen
#define BRIGHTNESS 255

// Parameter 1 = number of pixels in strip
// Parameter 2 = Arduino pin number (most are valid)
// Parameter 3 = pixel type flags, add together as needed:
Adafruit_NeoPixel strip = Adafruit_NeoPixel(ANZAHLDERPIXEL, NEOPIN, NEO_GRBW + NEO_KHZ800);

const unsigned long intervalle[] = {10, 50, 10, 500};
unsigned long aktMillis;

void setup() {
  strip.setBrightness(BRIGHTNESS);
  strip.begin();
  strip.show(); // Initialize all pixels to 'off'
}

struct Fade  // Für jede Farbe wird ein Startwert (0-255, 0=dunkel, 255=hell) angegeben, der mit dem Fadewert jedes Intervall (in ms) verändert wird.
             // start() setzt die Startwerte, run() macht das Faden.
             // Der Rückgabewert ist true, wenn alle Farben so nahe an 0 oder 255 sind, daß sie nicht mehr verändert werden können.
{
  Fade(byte rot, int8_t rotfade, byte gruen, int8_t gruenfade, byte blau, int8_t blaufade, byte weiss, int8_t weissfade, uint32_t intervall):
    rot(rot), rotfade(rotfade), gruen(gruen), gruenfade(gruenfade), blau(blau), blaufade(blaufade), weiss(weiss), weissfade(weissfade), intervall(intervall), ablaufMillis(0) {}

  void start(byte ersterpixel)
  {
    ep = ersterpixel;
    r = rot;
    rf = rotfade;
    g = gruen;
    gf = gruenfade;
    b = blau;
    bf = blaufade;
    w = weiss;
    wf = weissfade;
    i = intervall;
    ablaufMillis = aktMillis;
    for (byte pixel = ep; pixel < ep + PIXELPROZYL; pixel++)
    {
      strip.setPixelColor(pixel, strip.Color(r, g, b, w));
    }
    strip.show();
  }

  bool run()
  {
    bool rueckgabe = false;
    if (aktMillis - ablaufMillis >= i)
    {
      ablaufMillis = aktMillis;
      if (r >= -rf) r += rf;
      if (g >= -gf) g += gf;
      if (b >= -bf) b += bf;
      if (w >= -wf) w += wf;
      for (byte pixel = ep; pixel < ep + PIXELPROZYL; pixel++)
      {
        strip.setPixelColor(pixel, strip.Color(r, g, b, w));
      }
      strip.show();
      if ((r <= -rf || r > 255 - rf) && (g <= -gf || g > 255 - gf) && (b <= -bf || b > 255 - bf) && (w <= -wf || w > 255 - wf))
      {
        rueckgabe = true;
      }
    }
    return rueckgabe;
  }
  byte rot; int8_t rotfade; byte gruen; int8_t gruenfade; byte blau; int8_t blaufade; byte weiss; int8_t weissfade; uint32_t intervall;

  byte ep;
  byte r;
  int8_t rf;
  byte g;
  int8_t gf;
  byte b;
  int8_t bf;
  byte w;
  int8_t wf;
  byte i;
  unsigned long ablaufMillis;
};
Fade fade[]
{ // rot, rotfade, gruen, gruenfade, blau, blaufade, weiss, weissfade, intervall
  {0, 0, 0, 0, 0, 1, 0, 0, intervalle[0]},
  {255, -1, 0, 0, 0, 0, 0, 0, intervalle[2]},
  {0, 0, 0, 0, 0, 1, 0, 0, intervalle[0]},
  {255, -1, 0, 0, 0, 0, 0, 0, intervalle[2]},
  {0, 0, 0, 0, 0, 1, 0, 0, intervalle[0]},
  {255, -1, 0, 0, 0, 0, 0, 0, intervalle[2]},
  {0, 0, 0, 0, 0, 1, 0, 0, intervalle[0]},
  {255, -1, 0, 0, 0, 0, 0, 0, intervalle[2]},
  {0, 0, 0, 0, 0, 1, 0, 0, intervalle[0]},
  {255, -1, 0, 0, 0, 0, 0, 0, intervalle[2]},
  {0, 0, 0, 0, 0, 1, 0, 0, intervalle[0]},
  {255, -1, 0, 0, 0, 0, 0, 0, intervalle[2]},
};

struct Zyl  // Durchläuft die Schritte einer Schrittkette, wobei jeder Schritt dem Takt eines 4-Takt-Otto-Motors entsprechen könnte,
            // was hier aber eher künstlerisch zu betrachten ist.
            // startphase: Bei welchem Schritt (Takt) die Animation beginnt.
            // startpixel: Erstes Pixel für den Zylinder. Bei 42 Pixeln 0, 7, 14 ...
            // fadetyp: Notwendig, damit sich die Fadephasen nicht in die Quere kommen.
{
  Zyl(const byte startphase, const byte startpixel, const byte fadetyp): schritt(startphase), startpixel(startpixel), fadetyp(fadetyp), einmal(true), ablaufMillis(0) {}
  void run()
  {
    switch (schritt) {  // schritt würde dem Takt eines 4-Takt-Otto-Motors entsprechen.
      case 0:  // Blau von 0 nach 255 faden
        if (einmal) {
          einmal = false;
          fade[fadetyp].start(startpixel);
        } else {
          if (fade[fadetyp].run()) {
            schritt++;
            einmal = true;
          }
          break;
        case 1:  // zusätzlich zu Blau ein weißer Blitz
          if (einmal) {
            einmal = false;
            for (byte pixel = startpixel; pixel < startpixel + PIXELPROZYL; pixel++) {
              strip.setPixelColor(pixel, strip.Color(0,   0,   255, 255));
            }
            strip.show();
            ablaufMillis = aktMillis;
          }
          if (aktMillis - ablaufMillis >= intervalle[schritt]) {
            schritt++;
            einmal = true;
          }
          break;
        case 2:  // Rot von 255 nach 0 faden
          if (einmal) {
            einmal = false;
            fade[fadetyp+1].start(startpixel);
          } else {
            if (fade[fadetyp+1].run()) {
              schritt++;
              einmal = true;
            }
          }
          break;
        case 3:  // kurz alle Farben aus
          if (einmal) {
            einmal = false;
            for (byte pixel = startpixel; pixel < startpixel + PIXELPROZYL; pixel++) {
              strip.setPixelColor(pixel, strip.Color(0,   0,   0,   0));
            }
            strip.show();
            ablaufMillis = aktMillis;
          }
          if (aktMillis - ablaufMillis >= intervalle[schritt]) {
            schritt++;
            einmal = true;
          }
          break;
        default:
          schritt = 0;
          break;
        }
    }
  }
  byte schritt;
  const byte startpixel;
  const byte fadetyp;
  bool einmal;
  unsigned long ablaufMillis;
};
Zyl zylinder[]
{ // startphase, startpixel, fadetyp
  {0, 1, 0},
  {2, 2, 2},
  {3, 3, 4},
  {0, 4, 6},
  {2, 5, 8},
  {3, 6, 10}
};

void loop() {
  aktMillis = millis();
  for (Zyl &z : zylinder) z.run();
}

PS: Was ich hier programmiert habe, beruht unverkennbar auf dem süßen Honig fleißiger Bienchen und anderer freundlicher Menschen.

EDIT 20180727 10:45: Kommentare ergänzt.

Wahnsinn und Verstand trennt nur eine dünne Wand. (Daniel Düsentrieb)

HotSystems

Hallo agmue,

da ich von den bunten Pixeln noch sehr wenig bis keine Ahnung habe, schreib doch mal, welche Pixel (Leds) du hier verwendest.

Danke
Gruß Dieter

I2C = weniger ist mehr: weniger Kabel, mehr Probleme. 8)

combie

> Das größte Problem, ist die Wahl der richtigen Gedanken <
Frei nach Dale Carnegie

noiasca

Ich habe erst wieder ab Sonntag Zugriff auf Neopixels und ohne dass ich das selber life sehe, tu ich mich schwer  beim Einschätzen.

Was ich noch vermisse ist die Angabe, wie du die Pixel angeordnet hast - einfache schematische Zeichnung sollte reichen.

Und kannst du verbal bechreiben was deine Codeabschnitte tun (tun sollen???)

Was steckt hinter den structs, was sind die fadetyps, was sind "schritt" in den Cases die du hardcoded als 0, 1,2,... hingeschrieben hast?
DE: Wie man Fragen postet:
1. was hat man (Sketch und Hardware)
2. was SOLL es machen
3. was macht es: IST (Fehlverhalten, Fehlermeldungen, Serial.Output ...)
4. Eine Frage stellen bzw. erklären was man erwartet

agmue

#4
Jul 27, 2018, 09:48 am Last Edit: Jul 27, 2018, 02:25 pm by agmue
da ich von den bunten Pixeln noch sehr wenig bis keine Ahnung habe, schreib doch mal, welche Pixel (Leds) du hier verwendest.
Ich dachte, das ergibt sich aus dem anderen Thema, aber gerne doch. Ich verwende NeoPixel Jewel - 7 x 5050 RGBW LED w/ Integrated Drivers - Cool White - ~6000K. Da ich nur ein Juwel habe, verteile ich die sechs Zylinder auf die sieben Pixel. Ansteuerung wie WS2812 mit Daten und Takt auf einer Leitung (siehe #5).

Was ich noch vermisse ist die Angabe, wie du die Pixel angeordnet hast - einfache schematische Zeichnung sollte reichen.
Geht auch ein Foto? Pixel 0 ist unbenutzt. Gegenüberliegende Pixel entsprechen unterschiedlichen Zylindern, zeigen aber das selbe Muster. Rechts die Zündung:



Und kannst du verbal bechreiben was deine Codeabschnitte tun (tun sollen???)

Was steckt hinter den structs, was sind die fadetyps, was sind "schritt" in den Cases die du hardcoded als 0, 1,2,... hingeschrieben hast?
Ich habe Kommentare in #0 ergänzt. Wenn es nicht reicht, bitte melden :)

Die Schritte sollten den Takten, also Ansaugen, Verdichten, Zündung ... entsprechen, tun sie aber (noch) nicht. Beim Faden könnte man alle Farben in alle Richtungen verändern, was ich derzeit nicht nutze, aber für eine Gelb-Rot-Übergang wie in den Videos zu sehen, nützlich sein könnte. Ich will so ein Modell ja nicht bauen, mich interessiert das Programmieren und die Lichteffekte.

Ich habe erst wieder ab Sonntag Zugriff auf Neopixels ...
Das ist natürlich schade, aber ich habe keinerlei Eile, da keine wie auch immer genannte Arbeit bis zu einem bestimmten kurzfristigen Termin abgegeben werden muß, ich programmiere ja nur zum Spaß :smiley-mr-green:
Wahnsinn und Verstand trennt nur eine dünne Wand. (Daniel Düsentrieb)

combie

#5
Jul 27, 2018, 10:02 am Last Edit: Jul 27, 2018, 10:17 am by combie
Quote
Ansteuerung wie WS2812.
Naja....
Vom Timing, her ja, da sind sich die Chips sehr ähnlich.

WS2812 RGB 24Bit/Chip
SK6812 RGBW 32Bit/Chip

Das Datenblatt, was die da zu "TECHNICAL DETAILS" aufgeführt haben, passt nicht zu den Chips.
Dieses ist das richtige Datenblatt
> Das größte Problem, ist die Wahl der richtigen Gedanken <
Frei nach Dale Carnegie

agmue

Das Datenblatt, was die da zu "TECHNICAL DETAILS" aufgeführt haben, passt nicht zu den Chips.
Dieses ist das richtige Datenblatt
Ist ja schon verwirrend. Ich habe Lady Ada eine Korrekturmitteilung zukommen lassen.
Wahnsinn und Verstand trennt nur eine dünne Wand. (Daniel Düsentrieb)

noiasca

hm, meine Pixel sind offenbar ohne Weiß, deine Effekte kann ich somit kaum nachvollziehen. Das wird eine schwere Geburt.

ad
Code: [Select]


Zyl zylinder[]
{ // startphase, startpixel, fadetyp
  {0, 1, 0},
  {2, 2, 2},
  {3, 3, 4},
  {0, 4, 6},
  {2, 5, 8},
  {3, 6, 10}
};


warum wiederholen sich die Startphasen von 1 & 4, 2 & 5, 3 & 6? Steige da nicht wirklich durch...
DE: Wie man Fragen postet:
1. was hat man (Sketch und Hardware)
2. was SOLL es machen
3. was macht es: IST (Fehlverhalten, Fehlermeldungen, Serial.Output ...)
4. Eine Frage stellen bzw. erklären was man erwartet

agmue

#8
Jul 28, 2018, 12:14 pm Last Edit: Jul 28, 2018, 12:17 pm by agmue
hm, meine Pixel sind offenbar ohne Weiß, deine Effekte kann ich somit kaum nachvollziehen. Das wird eine schwere Geburt.
Soll ich das Programm für RGB umschreiben?

warum wiederholen sich die Startphasen von 1 & 4, 2 & 5, 3 & 6? Steige da nicht wirklich durch...
Wenn ich mich richtig erinnere, macht ein Viertakter Ansaugen, Verdichten, Verbrennen und Ausstoßen. Bei einem Vierzylinder macht Zylinder 1 Takt 1, Zylinder 2 Takt 2, Zylinder 3 Takt 3, Zylinder 4 Takt 4. Nee, tatsächlich läuft das in einer anderen Reihenfolge ab, siehe Viertakt-Ottomotor.

Und wie nun beim Sechszylinder? Ich kann ja keinen fünften und sechsten Takt hinzufügen. Also müssen zwei Zylinder wohl dasselbe machen oder etwas zeitlich versetzt.

An dieser Stelle steigt der Programmierer aus der Motortechnik aus. Ich habe drei für den Einstieg nutzbare Takte (Schritte), weshalb ich bei sechs Zylindern je zwei Zylinder mit der selben Animation habe. Je zwei Pixel zeigen die selbe Animation an. Welcher Zylinder mit welcher Animation startet, lege ich in Zyl als startphase fest.

Die Schritte habe ich nicht Takte genannt, weil es Animationsschritte sind und sie nicht den Takten entsprechen. So ist es notwendig, das Verbrennen im Programm in den Schritt "Zündblitz" (case 1) und "Verbrennen" (case 2) aufzuteilen.
Wahnsinn und Verstand trennt nur eine dünne Wand. (Daniel Düsentrieb)

postmaster-ino

Hi

Denke, der Grund FÜR einen 6-Zylinder ist die größere Laufruhe.
Beim 4-Zylinder (1-4-2-3) sind die Kolben um 180° versetzt - zwei haben immer die gleiche 'Höhe', aber unterschiedlichen Takt.
Auch wird (wenn möglich) verhindert, daß benachbarte Zylinder in der Zündreihenfolge direkt nacheinander dran sind.
Beim 4-Zylinder geht Das nicht, bei 2-3 haben wir zwei aufeinander folgende Zündungen an benachbarten Zylindern - scheint aber sonst trotzdem zu klappen - millionenfach auf den Straßen dieser Welt.

Beim 6-Zylinder sind die Kolben um 120° versetzt.
So habe ich bei 2 Umdrehungen (=720°) die 6 Zündungen gleichmäßig verteilt.
Anders als beim 4-Zylinder habe ich hier die Zündungen 'auseinander'.
1-5-3-6-2-4
Die aufeinander folgenden 'Schläge' wirken hier immer auf andere Lager, beim 4-Zylinder ist das Lager zwischen Zylinder 2 und 3 direkt 2x hintereinander dran.

Auch beim 6-Zyinder haben wir wieder zwei Kolben, Die 'auf gleicher Höhe' laufen, aber im anderen Takt (also um 2 Takte versetzt).

Somit kann die Simulation nicht bei zwei Zylindern gleich sein - Die muß ebenfalls versetzt 'kommen'.

MfG
anscheinend ist Es nicht erwünscht, einen Foren-internen Link als 'Homepage' einzubinden, damit JEDER nur einen Klick von combie's Liste zum Thema State-Maschine entfernt ist.
... dann eben nicht ...

agmue

Somit kann die Simulation nicht bei zwei Zylindern gleich sein - Die muß ebenfalls versetzt 'kommen'.
Wenn ich eine Simulation bauen wollte, stimme ich Dir zu. Ich habe mich aber nur von der Simalation inspirieren lassen. Für mich ist das eine mir selbst gestellt Programmierübung zum Spaß. Da kann es erstmal Blinken und Faden, wie es will. Aber selbst wenn ich die Animation der Simulation angleichen wollte, so bräuchte ich zunächst ein funktionierendes Programm, um die Wirkung beurteilen zu können.
Wahnsinn und Verstand trennt nur eine dünne Wand. (Daniel Düsentrieb)

noiasca

Soll ich das Programm für RGB umschreiben?
wenn du die Zeit aufbringen kannst, würde ich das glatt in meinen mal reinspielen zum Vergleichen. hab hier einen 8er Streifen mit WS2812 (NEO_GRB)

Ich werde auch einen Sketch probieren, aber die Ablaufsteuerung und die Zylinderklasse wohl etwas anders ansetzen.


Ein Problem der Aufgabenstellung sieht man jetzt schon deutlich:

Wenn man nur die Explosion darstellt, hat man max. nur ein 4tel der Zeit die LED Leuchte, wenn man "Auspuffen", Ansaugen" und "Verdichten" auch farblich darstellst, schauts zwar farblich vieleicht intereessant aus, aber hat dann mit der Wirklichkeit weniger zu tun... Ich werds als Option machen.
Was sind deine "Standard"-Farben für Auspuffen, Ansaugen und Verdichten?
DE: Wie man Fragen postet:
1. was hat man (Sketch und Hardware)
2. was SOLL es machen
3. was macht es: IST (Fehlverhalten, Fehlermeldungen, Serial.Output ...)
4. Eine Frage stellen bzw. erklären was man erwartet

postmaster-ino

Hi

Ansaugen kannst Du ggf. den Ansaugstutzen bläulich leuchten lassen.
Ausstoßen Auslaßstutzen hellrötlich.
Verdichten Brennraum bläulich zu rötlich faden, wird vom Zündfunken und der Verbrennung abgelöst.

MfG
anscheinend ist Es nicht erwünscht, einen Foren-internen Link als 'Homepage' einzubinden, damit JEDER nur einen Klick von combie's Liste zum Thema State-Maschine entfernt ist.
... dann eben nicht ...

agmue

#13
Jul 28, 2018, 02:16 pm Last Edit: Jul 28, 2018, 04:09 pm by agmue
wenn du die Zeit aufbringen kannst, würde ich das glatt in meinen mal reinspielen zum Vergleichen. hab hier einen 8er Streifen mit WS2812 (NEO_GRB)
Aber gerne! Die Pixel aus meinem Avatar möchten NEO_RGB. Bespaßt werden die Pixel 0 bis 5. Der weiße Blitz wird mit allen Farben "an" erzeugt.

Code: [Select]
// Variante für RGB anstelle RGBW
#include <Adafruit_NeoPixel.h>

#define NEOPIN 6
#define ANZAHLDERPIXEL 9  // hier müßte 42 stehen
#define PIXELPROZYL 1     // hier müßte 7 stehen
#define BRIGHTNESS 255

// Parameter 1 = number of pixels in strip
// Parameter 2 = Arduino pin number (most are valid)
// Parameter 3 = pixel type flags, add together as needed:
Adafruit_NeoPixel strip = Adafruit_NeoPixel(ANZAHLDERPIXEL, NEOPIN, NEO_RGB + NEO_KHZ800);

const unsigned long intervalle[] = {10, 50, 10, 500};
unsigned long aktMillis;

void setup() {
  strip.setBrightness(BRIGHTNESS);
  strip.begin();
  strip.show(); // Initialize all pixels to 'off'
}

struct Fade  // Für jede Farbe wird ein Startwert (0-255, 0=dunkel, 255=hell) angegeben, der mit dem Fadewert jedes Intervall (in ms) verändert wird.
             // start() setzt die Startwerte, run() macht das Faden.
             // Der Rückgabewert ist true, wenn alle Farben so nahe an 0 oder 255 sind, daß sie nicht mehr verändert werden können.
{
  Fade(byte rot, int8_t rotfade, byte gruen, int8_t gruenfade, byte blau, int8_t blaufade, uint32_t intervall):
    rot(rot), rotfade(rotfade), gruen(gruen), gruenfade(gruenfade), blau(blau), blaufade(blaufade), intervall(intervall), ablaufMillis(0) {}

  void start(byte ersterpixel)
  {
    ep = ersterpixel;
    r = rot;
    rf = rotfade;
    g = gruen;
    gf = gruenfade;
    b = blau;
    bf = blaufade;
    i = intervall;
    ablaufMillis = aktMillis;
    for (byte pixel = ep; pixel < ep + PIXELPROZYL; pixel++)
    {
      strip.setPixelColor(pixel, strip.Color(r, g, b));
    }
    strip.show();
  }

  bool run()
  {
    bool rueckgabe = false;
    if (aktMillis - ablaufMillis >= i)
    {
      ablaufMillis = aktMillis;
      if (r >= -rf) r += rf;
      if (g >= -gf) g += gf;
      if (b >= -bf) b += bf;
      for (byte pixel = ep; pixel < ep + PIXELPROZYL; pixel++)
      {
        strip.setPixelColor(pixel, strip.Color(r, g, b));
      }
      strip.show();
      if ((r <= -rf || r > 255 - rf) && (g <= -gf || g > 255 - gf) && (b <= -bf || b > 255 - bf))
      {
        rueckgabe = true;
      }
    }
    return rueckgabe;
  }
  byte rot; int8_t rotfade; byte gruen; int8_t gruenfade; byte blau; int8_t blaufade; uint32_t intervall;

  byte ep;
  byte r;
  int8_t rf;
  byte g;
  int8_t gf;
  byte b;
  int8_t bf;
  byte i;
  unsigned long ablaufMillis;
};
Fade fade[]
{ // rot, rotfade, gruen, gruenfade, blau, blaufade, intervall
  {0, 0, 0, 0, 0, 1, intervalle[0]},
  {255, -1, 0, 0, 0, 0, intervalle[2]},
  {0, 0, 0, 0, 0, 1, intervalle[0]},
  {255, -1, 0, 0, 0, 0, intervalle[2]},
  {0, 0, 0, 0, 0, 1, intervalle[0]},
  {255, -1, 0, 0, 0, 0, intervalle[2]},
  {0, 0, 0, 0, 0, 1, intervalle[0]},
  {255, -1, 0, 0, 0, 0, intervalle[2]},
  {0, 0, 0, 0, 0, 1, intervalle[0]},
  {255, -1, 0, 0, 0, 0, intervalle[2]},
  {0, 0, 0, 0, 0, 1, intervalle[0]},
  {255, -1, 0, 0, 0, 0, intervalle[2]},
};

struct Zyl  // Durchläuft die Schritte einer Schrittkette, wobei jeder Schritt dem Takt eines 4-Takt-Otto-Motors entsprechen könnte,
            // was hier aber eher künstlerisch zu betrachten ist.
            // startphase: Bei welchem Schritt (Takt) die Animation beginnt.
            // startpixel: Erstes Pixel für den Zylinder. Bei 42 Pixeln 0, 7, 14 ...
            // fadetyp: Notwendig, damit sich die Fadephasen nicht in die Quere kommen.
{
  Zyl(const byte startphase, const byte startpixel, const byte fadetyp): schritt(startphase), startpixel(startpixel), fadetyp(fadetyp), einmal(true), ablaufMillis(0) {}
  void run()
  {
    switch (schritt) {  // schritt würde dem Takt eines 4-Takt-Otto-Motors entsprechen.
      case 0:  // Blau von 0 nach 255 faden
        if (einmal) {
          einmal = false;
          fade[fadetyp].start(startpixel);
        } else {
          if (fade[fadetyp].run()) {
            schritt++;
            einmal = true;
          }
          break;
        case 1:  // ein weißer Blitz
          if (einmal) {
            einmal = false;
            for (byte pixel = startpixel; pixel < startpixel + PIXELPROZYL; pixel++) {
              strip.setPixelColor(pixel, strip.Color(255, 255, 255));
            }
            strip.show();
            ablaufMillis = aktMillis;
          }
          if (aktMillis - ablaufMillis >= intervalle[schritt]) {
            schritt++;
            einmal = true;
          }
          break;
        case 2:  // Rot von 255 nach 0 faden
          if (einmal) {
            einmal = false;
            fade[fadetyp+1].start(startpixel);
          } else {
            if (fade[fadetyp+1].run()) {
              schritt++;
              einmal = true;
            }
          }
          break;
        case 3:  // kurz alle Farben aus
          if (einmal) {
            einmal = false;
            for (byte pixel = startpixel; pixel < startpixel + PIXELPROZYL; pixel++) {
              strip.setPixelColor(pixel, strip.Color(0,   0,   0));
            }
            strip.show();
            ablaufMillis = aktMillis;
          }
          if (aktMillis - ablaufMillis >= intervalle[schritt]) {
            schritt++;
            einmal = true;
          }
          break;
        default:
          schritt = 0;
          break;
        }
    }
  }
  byte schritt;
  const byte startpixel;
  const byte fadetyp;
  bool einmal;
  unsigned long ablaufMillis;
};
Zyl zylinder[]
{ // startphase, startpixel, fadetyp
  {0, 0, 0},
  {2, 1, 2},
  {3, 2, 4},
  {0, 3, 6},
  {2, 4, 8},
  {3, 5, 10}
};

void loop() {
  aktMillis = millis();
  for (Zyl &z : zylinder) z.run();
}

Ich hoffe, ich habe auf die Schnelle an alle Stellen gedacht. Funktionieren tut es.
Wahnsinn und Verstand trennt nur eine dünne Wand. (Daniel Düsentrieb)

noiasca

ok danke funzt soweit. Ich mach jetzt mal mechanisch eine Grundplatte mit 7 LED's pro Zylinder...
DE: Wie man Fragen postet:
1. was hat man (Sketch und Hardware)
2. was SOLL es machen
3. was macht es: IST (Fehlverhalten, Fehlermeldungen, Serial.Output ...)
4. Eine Frage stellen bzw. erklären was man erwartet

Go Up