Go Down

Topic: Zündreihenfolge eines 6 Zylinders simulieren (Read 1 time) previous topic - next topic

Yves83

Der Levelshifter ist bestellt. Kann ein paar Tage dauern.
Ich würde mich jetzt schonmal an die Ansteuerung per Bluetooth machen.

Leider passen die Zündreihenfolgen noch nicht. Ist es für dich ein leichtes es abzuändern?
Ich habe mal ein PDF erstellt, wo die Zündreihenfolgen dargestellt sind.


agmue

#31
Nov 12, 2018, 12:20 pm Last Edit: Nov 12, 2018, 12:25 pm by agmue
Mal ein Versuch, die anzupassenden Stellen kennst Du ja:

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

#define NEOPIN 6          // hier müßte 22 stehen
#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, 2550, 2550, 10, 2550, 2550};
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):
    rot(rot), rotfade(rotfade), gruen(gruen), gruenfade(gruenfade), blau(blau), blaufade(blaufade), weiss(weiss), weissfade(weissfade), ablaufMillis(0) {}

  void start(byte ersterpixel, uint32_t intervall)
  {
    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 || rf == 0) && (g <= -gf || g > 255 - gf || gf == 0) && (b <= -bf || b > 255 - bf || bf == 0) && (w <= -wf || w > 255 - wf || wf == 0))
      {
        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, 255, -1, 0, 0},
  {255,  0, 255, -1,   0,  0, 0, 0},
  {  0,  0,   0,  0, 255, -1, 0, 0},
  {255,  0, 255, -1,   0,  0, 0, 0},
  {  0,  0,   0,  0, 255, -1, 0, 0},
  {255,  0, 255, -1,   0,  0, 0, 0},
  {  0,  0,   0,  0, 255, -1, 0, 0},
  {255,  0, 255, -1,   0,  0, 0, 0},
  {  0,  0,   0,  0, 255, -1, 0, 0},
  {255,  0, 255, -1,   0,  0, 0, 0},
  {  0,  0,   0,  0, 255, -1, 0, 0},
  {255,  0, 255, -1,   0,  0, 0, 0}
};

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 255 nach 0 faden
        if (einmal) {
          einmal = false;
          fade[fadetyp].start(startpixel, intervalle[schritt]);
        } else {
          if (fade[fadetyp].run()) {
            schritt++;
            einmal = true;
          }
          break;
        case 1:  // 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;
        case 2:  // 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;
        case 3:  // Gelb nach Rot faden
          if (einmal) {
            einmal = false;
            fade[fadetyp + 1].start(startpixel, intervalle[schritt]);
          } else {
            if (fade[fadetyp + 1].run()) {
              schritt++;
              einmal = true;
            }
          }
          break;
        case 4:  // 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;
        case 5:  // 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},
  {4, 3, 4},
  {5, 4, 6},
  {1, 5, 8},
  {3, 6, 10}
};

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

Ich vermisse die Nutzung der weißen LEDs.
Wahnsinn und Verstand trennt nur eine dünne Wand. (Daniel Düsentrieb)

Yves83

Jo, funktioniert soweit super. Zylinder 4 und 5 sind noch vertauscht, bekomme ich aber über die Verdrahtung hin.
Ist es in dem Case 3 (Rot fade) noch möglich am Ende vom Rot, alle kurz weiß aufblitzen zu lassen (Eines Zylinders)?
Das wäre dann die Zündung.


Meine Idee wäre gewesen, noch einen weiteren Modi für die einfache Beleuchtung des Tisches zu erstellen z.B. alle Zylinder weiss.
Diese Modi müsste ich dann noch umschalten können.
Ich habe gelesen, das der ESP32 einen Touch Ausgang hat. Kann ich diesen Kontakt nicht einfach auf das Gehäuse des Motors legen und der Chef kann dann über die Berührung des Tisches zwischen "Simulation" und "Ambient" umschalten, indem er das Motorgehäuse berührt?

Der Levelshifter dauert noch, wir machen uns jetzt schonmal an die Hardwareumsetzung.

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

Yves83

So, die Hardware ist vorbereitet. Levelshifter ist da und läuft.
Nun fehlt mir "nurnoch" die Anpassung des Programms.
Was noch fehlt:

- Kurzes weisses Aufblitzen am Ende des Rotfade
- Modi - Alle LED weiß, mit x Helligkeit
- Die Möglichkeit mit einem Touch Ausgang zwischen Simulation und Ambient umzuschalten, alternativ über einen Taster.

PS: Ich bin auf Grund der Bauweise und der 5V Versorgungsspannung vom ESP32 auf den Nano gewechselt. Hoffe das ist zu vernachlässigen  :smiley-confuse:

agmue

Levelshifter ist da und läuft.
...
PS: Ich bin auf Grund der Bauweise und der 5V Versorgungsspannung vom ESP32 auf den Nano gewechselt. Hoffe das ist zu vernachlässigen  :smiley-confuse:
Welche Level shiftes Du?
Wahnsinn und Verstand trennt nur eine dünne Wand. (Daniel Düsentrieb)

Yves83

@agmue

So, habe leider immer nur bedingt Zeit mich diesem Projekt zu widmen.
Jetzt ist wieder etwas Luft, also geht es weiter.
Da ich jetzt den Nano benutze, brauche ich ja keinen Levelshifter mehr.
Habe beim ESP32, den Levelshifter von Ardafruit genommen, um von 3,3V auf 5,0V zu shiften.
Würde jetzt auch das letzte Script nehmen, sprich die Anpassungen mit dem Weiß-Blitz sind jetzt zu vernachlässigen.Die Ambientbeleuchtung würde ich aber gerne noch umgesetzt bekommen.
Ist es ohne viel Aufwand zu ändern.
Würde es gerne über einen Touch-Kanal ändern und den auf das Gehäuse des Motors legen, wenn es funktioniert.

agmue

Jetzt ist wieder etwas Luft, also geht es weiter.
Na dann viel Erfolg!
Wahnsinn und Verstand trennt nur eine dünne Wand. (Daniel Düsentrieb)

Go Up