Go Down

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

agmue

ok danke funzt soweit. Ich mach jetzt mal mechanisch eine Grundplatte mit 7 LED's pro Zylinder...
Möchtest Du Dir tatsächlich eine Simulation bauen? Mir geht es ja um das Programmieren, aber dann würde ich natürlich von "künstlerisch" zu "technisch" schwenken und noch weitere Animationsschritte hinzufügen.

Ach ja: Was Takte sind, ist technisch vorgegeben. Aber ein Takt kann natürlich in mehrere Animationsschritte zerfallen. Darum hatte ich die Schritte als Schritte und nicht als Takte benannt.
Wahnsinn und Verstand trennt nur eine dünne Wand. (Daniel Düsentrieb)

noiasca

"möchten" ist übertrieben, aber "Flammen-Flackern" wollte ich ohnehin schon mal machen, insofern eine nette Übung. Bei 7 Pixel ist zwar das ausbreiten der Flamme ein wenig witzlos, aber mal sehen ;-)
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

Ich habe mit einem Zylinder angefangen, weil einen das Geblinke sonst irgendwann kirre macht.
Wahnsinn und Verstand trennt nur eine dünne Wand. (Daniel Düsentrieb)

combie

#18
Jul 29, 2018, 05:16 pm Last Edit: Jul 30, 2018, 01:30 am by combie
Quote
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."
....
Habe mich auch mal anregen lassen....

So richtig schön ist es noch nicht geworden.... Nacharbeit könnte sich lohnen.
Optimierungen/Verschönerungen sind noch an vielen Ecken möglich

------

Verwendet wird für jeden Zylinder eine RGB LED

Als Drehpunkt habe ich die Kurbelwelle genommen.
720° für einen vollen Zyklus, beginnend mit "Ansaugen"

Die Kurbelwelle mit ihrer Zündfolge ist in dem Array "motor" verankert.
So ist das leicht austauschbar und es können eigene Motorkreationen "getestet" werden.

Die Takte:
1 "Ansaugen"
Dimmt von Schwarz zu Blau. Die Stärke des Blau soll die angesaugte kalte Frischgasmenge darstellen.

2 "Verdichten"
Dimmt von Blau nach Violett/Mangenta, soll die zunehmende Verdichtung und Erwärmung darstellen

3. "Arbeiten"
Dimmt von Gelb zu Rot, Entspannung des Gases und die Abkühlung dabei

4."Ausstoßen"
Dimmt von Rot nach Schwarz, das noch recht heiße Gas wird ausgestoßen

Zwischen 2 und 3 gibt es einen Weißen Blitz, welcher die Durchzündung des Gemisches symbolisieren soll

Code: [Select]

#include <Adafruit_NeoPixel.h>

const byte stripePin = 6;

const byte zylinder = 3;

// 3 Zylinder 1-2-3
int motor[zylinder] {0, 240, 480};

// 4 Zylinder 1-3-4-2
//int motor[zylinder] {0, 360, 540 , 180};

// 6 Zylinder 1-5-3-6-2-4
//int motor[zylinder] {0, 480, 240, 600, 120, 360};

int winkel = 0;

Adafruit_NeoPixel pixels = Adafruit_NeoPixel(zylinder,stripePin, NEO_GRB + NEO_KHZ800);

int normalisiereWinkel(int winkel)
{
  while(winkel >= 720) winkel -= 720;
  while(winkel <    0) winkel += 720;
  return winkel;
}

void berecheFarbe(int winkel,int zylinder)
{
  winkel = normalisiereWinkel(winkel-motor[zylinder]);
  int fortschritt = winkel % 180; // innerhalb eines Taktes
  int takt = winkel / 180;
  int r,g,b;

  if(winkel > 355 && winkel < 365) // Blitz
  {
    pixels.setPixelColor(zylinder, pixels.Color(255,255,255));
  }else
  {
    switch(takt) // Farben fuer den jeweiligen Takt
    {
      case 0 : r = 0          ; b = fortschritt; g = 0; break;
      case 1 : r = fortschritt; b = 179        ; g = 0; break;
      case 2 : r = 179        ; b = 0          ; g = 179-fortschritt; break;
      case 3 : r = 179-fortschritt; b = 0; g = 0; break;
    }
    pixels.setPixelColor(zylinder, pixels.Color(r,g,b));
  }
}



void setup()
{
  pixels.begin();
}


void loop()
{
  for(int i=0;i<zylinder;i++) berecheFarbe(winkel,i);
  pixels.show();
  winkel = normalisiereWinkel(++winkel); // wrapp around
  delay(10);
}
> Das größte Problem, ist die Wahl der richtigen Gedanken <
Frei nach Dale Carnegie

noiasca

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

combie

#20
Jul 30, 2018, 09:49 am Last Edit: Jul 30, 2018, 11:54 am by combie
Moin!

Der Titel heißt ja "OOP mit einem Kringel zu viel?"

Also habe ich das/mein Programm etwas überarbeitet.
Etwas mehr OOP, und ein paar Kringel dran gebaut.
Damit es dem Titel etwas gerechter wird.

Funktionalität  und Farben unverändert.

Der Motor ist jetzt ein Array von Zylindern geworden. Was mir von der Betrachtungsweise her, mehr als angemessen erscheint.
Auch ist der aktuelle Kurbelwellenwinkel jetzt ein Objekt, welches nur die 4T üblichen 720° aufnehmen kann. Über und Unterläufe werden selbstständig abgehandelt.

Der Speicherverbrauch hat sich dadurch kaum geändert. Es sind 2 Byte mehr Flash Bedarf.
Ich glaube, dass man eine solche Ressourcen Verschwendung gerade noch tolerieren kann.
 :smiley-cool:  :smiley-cool:  :smiley-cool:  :smiley-cool:

Das Hauptprogramm schaut jetzt so aus, der Rest im Anhang.
Code: [Select]
#include <Adafruit_NeoPixel.h>

#include "Zylinder.h"

//Zylinder motor[] {0, 360};// 2 Zylinder parallel Twin
//Zylinder motor[] {0, 180};// 2 Zylinder gegenlaeufer
Zylinder motor[] {0, 240, 480};// 3 Zylinder 1-2-3
//Zylinder motor[] {0, 540 , 180, 360};          // 4 Zylinder 1-3-4-2
//Zylinder motor[] {0, 480, 240, 600, 120, 360}; // 6 Zylinder 1-5-3-6-2-4

const byte anzahlZylinder = sizeof(motor)/sizeof(motor[0]);
const byte stripePin      = 6;
Adafruit_NeoPixel stripe {anzahlZylinder,stripePin, NEO_GRB + NEO_KHZ800};
KurbelWinkel kurbelwinkel;

void showMotor(Adafruit_NeoPixel & stripe,KurbelWinkel & winkel)
{
  for(int i=0;i<anzahlZylinder;i++)
  {
    Color farbe = motor[i].getColor(winkel);
    stripe.setPixelColor(i, stripe.Color(farbe.r,farbe.g,farbe.b));
  }
  stripe.show();
}

void setup()
{
  stripe.begin();
}

void loop()
{
  showMotor(stripe,kurbelwinkel);
  kurbelwinkel++; 
  delay(10);
}
> Das größte Problem, ist die Wahl der richtigen Gedanken <
Frei nach Dale Carnegie

noiasca

#21
Jul 30, 2018, 05:35 pm Last Edit: Jul 30, 2018, 05:37 pm by noiasca
Ich komm nicht so recht weiter mit der Animation innerhalb des Taktes. Das werden zu viele IFs in Schlangencode. Da combie ohnehin auch schon ein fertiges OOP geliefert hat, bin ich dann mal raus.

Noch ein Bildchen von meinem Test-Motor mit 3 Zylinder (bzw. eine Bank eines V6 ) - das - wie man sehen kann - in der Bohrmaschine fast um die Ohren geflogen ist ;-)

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

combie

#22
Jul 30, 2018, 05:49 pm Last Edit: Jul 30, 2018, 05:55 pm by combie
Quote
Da combie ohnehin auch schon ein fertiges OOP geliefert hat, bin ich dann mal raus.
Ja, nee...
So gehts ja nicht, und ich soll auch noch die Schuld tragen...
(NIE wieder, werde ich hier OOP Code posten)
 :o  :o  :o  :o  :o  :o

Quote
Ich komm nicht so recht weiter mit der Animation innerhalb des Taktes. Das werden zu viele IFs in Schlangencode.
If Kaskaden mag ich auch nicht.
Habe dann immer das Gefühl was falsch gemacht zu haben.

Was machen die if denn?
evtl. kann man das Problem ja mit einer "Lookup Table" erschlagen.
> Das größte Problem, ist die Wahl der richtigen Gedanken <
Frei nach Dale Carnegie

noiasca

#23
Jul 30, 2018, 06:47 pm Last Edit: Jul 30, 2018, 06:49 pm by noiasca
combie, mir fehlen da positive Smiles in deinem Post. Falls ich falsch rübergekommen bin, - ich habe deine Antwort sehr geschätzt nur sehe ich mich nicht mehr im Stande einen added-value beizutragen. Das OOP Problem ist ja gelöst (von dir).

ich denke nicht, dass mein Animations-Versuch was taugt.

Die Grundidee war, ein Pixel als  Zündkerze zu nehmen (bei mir die dritte  @9Uhr), und die drei Nachbar-LEDs heller (Pixel 2 @11Uhr, 0 = Mitte, Pixel 4@7 Uhr) ("weil schneller durch den Funken erreicht") - darzustellen. Wirkt aber nicht besonders.

Außerdem haben sich meine Bedenken bestätigt: das wird immer mehr geflickere und taugt als Abience-Light nichts - und als Simulation auch nicht.

Code: [Select]


#include <Adafruit_NeoPixel.h>

const byte stripePin = 6;

const byte zylinder = 3;
const byte ledPerZylinder = 7;

// 1 Zylinder 1
//int motor[zylinder] {0};

// 3 Zylinder 1-2-3
int motor[zylinder] {0, 240, 480};

// 4 Zylinder 1-3-4-2
//int motor[zylinder] {0, 360, 540 , 180};

// 6 Zylinder 1-5-3-6-2-4
// int motor[zylinder] {0, 480, 240, 600, 120, 360};

int winkel = 0;

Adafruit_NeoPixel pixels = Adafruit_NeoPixel(50, stripePin, NEO_RGB + NEO_KHZ800);       // meine Kette hat momentan 50 LED's und ich will sie nicht abschneiden

int normalisiereWinkel(int winkel)
{
  while (winkel >= 720) winkel -= 720;
  while (winkel <    0) winkel += 720;
  return winkel;
}

void berechneFarbe(int winkel, int zylinder)
{
  winkel = normalisiereWinkel(winkel - motor[zylinder]);
  int fortschritt = winkel % 180; // innerhalb eines Taktes
  int takt = winkel / 180;
  int r, g, b;

  if (winkel > 355 && winkel < 365) // Blitz
  {
    pixels.setPixelColor(zylinder * ledPerZylinder + 3, pixels.Color(255, 255, 255));   // +3 = Lage der Zündkerze
  }
  else
  {
    switch (takt) // Farben fuer den jeweiligen Takt
    {
      case 0 : r = 0          ; b = fortschritt;       g = 0; break;                  // Ansaugen:   Dimmt von Schwarz zu Blau. Die Stärke des Blau soll die angesaugte kalte Frischgasmenge darstellen.
      case 1 : r = 0;           b = 179 - fortschritt  ; g = 0; break;                // Verdichten: NEU zu Schwarz
      case 2 : r = 179        ; b = 0                ; g = 179 - fortschritt; break;  // Arbeiten:   Dimmt von Gelb zu Rot, Entspannung des Gases und die Abkühlung dabei
      case 3 : r = 179 - fortschritt; b = 0; g = 0; break;                            // Ausstoßen:  Dimmt von Rot nach Schwarz, das noch recht heiße Gas wird ausgestoßen
    }

    for (byte actual = 0; actual < ledPerZylinder; actual++)
    {
      byte actualPixel = zylinder * ledPerZylinder + actual;
      pixels.setPixelColor(actualPixel, pixels.Color(r, g, b));
    }

    if (winkel > 365 && winkel < 400)
    {
      pixels.setPixelColor(zylinder * ledPerZylinder + 2, pixels.Color(r, g + 40, b));  // Pixel 0, 2 und 4 je Zylinder sind am nächsten zur Zündkerze
      pixels.setPixelColor(zylinder * ledPerZylinder,     pixels.Color(r, g + 40, b));
      pixels.setPixelColor(zylinder * ledPerZylinder + 4, pixels.Color(r, g + 40, b));
    }
  }
}



void setup()
{
  Serial.begin(115200);
  pixels.begin();
  for (byte i = 0; i < 50; i++) pixels.setPixelColor(i, pixels.Color(0, 0, 0));  //
  pixels.show();
}


void loop()
{
  for (byte i = 0; i < zylinder; i++) berechneFarbe(winkel, i);
  pixels.show();
  winkel = normalisiereWinkel(++winkel); // wrapp around
  delay(10);
}



OT: Pixel 0 der Kette wegen OSI Layer 8 geschrottet, 12V Netzteil vermutlich auch ... ergo lass ich das jetzt ;-/ ...

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

combie

Quote
ich denke nicht, dass mein Animations-Versuch was taugt.
.... ergo lass ich das jetzt ;-/ ..
Ja, ok, dann höre ich auch mal auf zu drängeln...


Quote
combie, mir fehlen da positive Smiles in deinem Post.
Ach, da mache dir mal nichts draus.
Die vergesse ich öfter mal.
Auch weiß ich nicht unbedingt, was "positiv" ist. (youtube)

Ärgern wollte ich dich nicht.
(ok, vielleicht ein ganz kleines bisschen...)
Es wäre mir schon ganz recht, wenn ich heute nicht eine Eskalationsspirale vorwärts treiben müsste.

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

agmue

... ergo lass ich das jetzt ;-/ ...
Schade eigentlich, wo Du das Bohren doch so glücklich überstanden hast  ;D

@combie: Dein Programm in #18 hat mich erstaunt, nicht nur weil schön kurz, sondern auch noch prozedural und mit delay()! Den Ansatz über den Drehwinkel finde ich interessant.

Das Programm in #20 hat dann ein paar mir (noch) unverständliche Passagen, die ich in Ruhe analysieren möchte. Das kann ein paar Tage dauern. Mal sehen, ob ich was für meinen Entwurf übernehmen kann.

Bis hierhin schon mal Dank für die Beteiligung an diesem Thema :)

Es wäre mir schon ganz recht, wenn ich heute nicht eine Eskalationsspirale vorwärts treiben müsste.
Wegen mir nicht, ich wechsele jetzt ins Traumland :smiley-sleep:
Wahnsinn und Verstand trennt nur eine dünne Wand. (Daniel Düsentrieb)

noiasca

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

combie

#27
Jul 31, 2018, 02:50 pm Last Edit: Jul 31, 2018, 11:23 pm by combie
Quote
@combie: Dein Programm in #18 hat mich erstaunt, nicht nur weil schön kurz, sondern auch noch prozedural und mit delay()! Den Ansatz über den Drehwinkel finde ich interessant.
Danke, für die Blumen, und schön, wenn es dir gefällt.

Ja, der Kurbelwinkel....
Der fehlte mir ganz extrem, in der ganzen Thematik "Motor Simulator".
Zu Anfang wusste ich nicht wirklich, dass mich das störte.
(darum habe ich mich auch die erste Zeit zurückgehalten)

Die Frage: "Wie würde ich das angehen?"
Begann mit Augen schließen und einer geistigen Abbildung einer sich drehenden Kurbelwelle.
Das war das Erste.
Die Erkenntnis, dass Kurbelwellenwinkel und innerer Zustand eines Motors, streng gekoppelt sind, sich voneinander gegenseitig ableiten lassen, wohnt schon eine kleine Ewigkeit in mir. So kam es zu den 2 "Wichtigkeiten".
1. Drehwinkel
2. Motortype

Aus den beiden Größen, lässt sich der aktuelle Zustand berechnen.
Jederzeit, für jeden Winkel.
Ob sich das jetzt per delay() abspielt, oder man den Nachtwächter bemüht, .. naja ...

Prozedural?
Naja, ich würde es eher einen Entwurf nennen. Es ist also eher meine Neigung, an einfache Probleme, mit naiven Strategien ran zugehen.

Beim schreiben stellten sich aber dann schon ein paar Probleme, welche dann zu #20 geführt haben.
Irgendwie zuviel ineinander geklatscht. Den Problemkomplex nenne ich "Zuständigkeiten" und auch "Koppelung"
> Das größte Problem, ist die Wahl der richtigen Gedanken <
Frei nach Dale Carnegie

Yves83

So Agmue,
ich mache dann hier mal weiter. Habe dein Script von der ersten Seite genommen und:
#define ANZAHLDERPIXEL 21  // hier müßte 42 stehen
#define PIXELPROZYL 7     // hier müßte 7 stehen
angepasst. Leider auch ohne ersichtlicher Funktion, habe sogar grün drinne.

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

#define NEOPIN 22
#define ANZAHLDERPIXEL 21  // hier müßte 42 stehen
#define PIXELPROZYL 7     // 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();
}




Hier das Ergebnis:


Zündung 2


Noch eine Idee?

agmue

Noch eine Idee?
Ja, die Startpixel anpsssen, dazu mein Kommentar:

// startpixel: Erstes Pixel für den Zylinder. Bei 42 Pixeln 0, 7, 14 ...

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

Go Up