NeoPixel Buttoncycler Sketch umbauen??

Guten Abend zusammen. Ich habe vergebens versucht den Sketch "buttoncycler" aus den Adafruit NeoPixel Beispielen für meine Zwecke umzubauen. Ziel ist es mit dem Push Button die erste Animation zu starten und solange zu wiederholen bis der Button erneut gedrückt wird und die nächste Animation in Endlosschleife läuft.

Der folgende Code ist der normale buttoncycler-Code, nur die Helligkeit habe ich selbst hinzugefügt um nicht zu erblinden während der Nano am PC ist :slight_smile:
Meine Coding-Skills sind leider nicht ausreichend um es selbst zu schreiben, daher hoffe ich auf guten Willen von euch :wink: Werde auch gleich noch ein Foto machen damit ihr sehen könnt was ich vorhabe. Der RGB-LED-Ring soll in einen riesigen Lolli eingebaut werden und unserer Tochter als Nachtlicht dienen.

// Simple demonstration on using an input device to trigger changes on your
// NeoPixels. Wire a momentary push button to connect from ground to a
// digital IO pin. When the button is pressed it will change to a new pixel
// animation. Initial state has all pixels off -- press the button once to
// start the first animation. As written, the button does not interrupt an
// animation in-progress, it works only when idle.

#include <Adafruit_NeoPixel.h>
#ifdef __AVR__
 #include <avr/power.h> // Required for 16 MHz Adafruit Trinket
#endif

// Digital IO pin connected to the button. This will be driven with a
// pull-up resistor so the switch pulls the pin to ground momentarily.
// On a high -> low transition the button press logic will execute.
#define BUTTON_PIN   A3

#define PIXEL_PIN     3  // Digital IO pin connected to the NeoPixels.

#define PIXEL_COUNT 48  // Number of NeoPixels

// Declare our NeoPixel strip object:
Adafruit_NeoPixel strip(PIXEL_COUNT, PIXEL_PIN, NEO_GRB + NEO_KHZ800);
// Argument 1 = Number of pixels in NeoPixel strip
// Argument 2 = Arduino pin number (most are valid)
// Argument 3 = Pixel type flags, add together as needed:
//   NEO_KHZ800  800 KHz bitstream (most NeoPixel products w/WS2812 LEDs)
//   NEO_KHZ400  400 KHz (classic 'v1' (not v2) FLORA pixels, WS2811 drivers)
//   NEO_GRB     Pixels are wired for GRB bitstream (most NeoPixel products)
//   NEO_RGB     Pixels are wired for RGB bitstream (v1 FLORA pixels, not v2)
//   NEO_RGBW    Pixels are wired for RGBW bitstream (NeoPixel RGBW products)

boolean oldState = HIGH;
int     mode     = 0;    // Currently-active animation mode, 0-9

void setup() {
  pinMode(BUTTON_PIN, INPUT_PULLUP);
  strip.begin(); // Initialize NeoPixel strip object (REQUIRED)
  strip.show();  // Initialize all pixels to 'off'
  strip.setBrightness(10); // Set BRIGHTNESS to about 1/5 (max = 255)
}

void loop() {
  // Get current button state.
  boolean newState = digitalRead(BUTTON_PIN);

  // Check if state changed from high to low (button press).
  if((newState == LOW) && (oldState == HIGH)) {
    // Short delay to debounce button.
    delay(20);
    // Check if button is still low after debounce.
    newState = digitalRead(BUTTON_PIN);
    if(newState == LOW) {      // Yes, still low
      if(++mode > 8) mode = 0; // Advance to next mode, wrap around after #8
      switch(mode) {           // Start the new animation...
        case 0:
          colorWipe(strip.Color(  0,   0,   0), 50);    // Black/off
          break;
        case 1:
          colorWipe(strip.Color(255,   0,   0), 50);    // Red
          break;
        case 2:
          colorWipe(strip.Color(  0, 255,   0), 50);    // Green
          break;
        case 3:
          colorWipe(strip.Color(  0,   0, 255), 50);    // Blue
          break;
        case 4:
          theaterChase(strip.Color(127, 127, 127), 50); // White
          break;
        case 5:
          theaterChase(strip.Color(127,   0,   0), 50); // Red
          break;
        case 6:
          theaterChase(strip.Color(  0,   0, 127), 50); // Blue
          break;
        case 7:
          rainbow(10);
          break;
        case 8:
          theaterChaseRainbow(50);
          break;
      }
    }
  }

  // Set the last-read button state to the old state.
  oldState = newState;
}

// Fill strip pixels one after another with a color. Strip is NOT cleared
// first; anything there will be covered pixel by pixel. Pass in color
// (as a single 'packed' 32-bit value, which you can get by calling
// strip.Color(red, green, blue) as shown in the loop() function above),
// and a delay time (in milliseconds) between pixels.
void colorWipe(uint32_t color, int wait) {
  for(int i=0; i<strip.numPixels(); i++) { // For each pixel in strip...
    strip.setPixelColor(i, color);         //  Set pixel's color (in RAM)
    strip.show();                          //  Update strip to match
    delay(wait);                           //  Pause for a moment
  }
}

// Theater-marquee-style chasing lights. Pass in a color (32-bit value,
// a la strip.Color(r,g,b) as mentioned above), and a delay time (in ms)
// between frames.
void theaterChase(uint32_t color, int wait) {
  for(int a=0; a<10; a++) {  // Repeat 10 times...
    for(int b=0; b<3; b++) { //  'b' counts from 0 to 2...
      strip.clear();         //   Set all pixels in RAM to 0 (off)
      // 'c' counts up from 'b' to end of strip in steps of 3...
      for(int c=b; c<strip.numPixels(); c += 3) {
        strip.setPixelColor(c, color); // Set pixel 'c' to value 'color'
      }
      strip.show(); // Update strip with new contents
      delay(wait);  // Pause for a moment
    }
  }
}

// Rainbow cycle along whole strip. Pass delay time (in ms) between frames.
void rainbow(int wait) {
  // Hue of first pixel runs 3 complete loops through the color wheel.
  // Color wheel has a range of 65536 but it's OK if we roll over, so
  // just count from 0 to 3*65536. Adding 256 to firstPixelHue each time
  // means we'll make 3*65536/256 = 768 passes through this outer loop:
  for(long firstPixelHue = 0; firstPixelHue < 3*65536; firstPixelHue += 256) {
    for(int i=0; i<strip.numPixels(); i++) { // For each pixel in strip...
      // Offset pixel hue by an amount to make one full revolution of the
      // color wheel (range of 65536) along the length of the strip
      // (strip.numPixels() steps):
      int pixelHue = firstPixelHue + (i * 65536L / strip.numPixels());
      // strip.ColorHSV() can take 1 or 3 arguments: a hue (0 to 65535) or
      // optionally add saturation and value (brightness) (each 0 to 255).
      // Here we're using just the single-argument hue variant. The result
      // is passed through strip.gamma32() to provide 'truer' colors
      // before assigning to each pixel:
      strip.setPixelColor(i, strip.gamma32(strip.ColorHSV(pixelHue)));
    }
    strip.show(); // Update strip with new contents
    delay(wait);  // Pause for a moment
  }
}

// Rainbow-enhanced theater marquee. Pass delay time (in ms) between frames.
void theaterChaseRainbow(int wait) {
  int firstPixelHue = 0;     // First pixel starts at red (hue 0)
  for(int a=0; a<30; a++) {  // Repeat 30 times...
    for(int b=0; b<3; b++) { //  'b' counts from 0 to 2...
      strip.clear();         //   Set all pixels in RAM to 0 (off)
      // 'c' counts up from 'b' to end of strip in increments of 3...
      for(int c=b; c<strip.numPixels(); c += 3) {
        // hue of pixel 'c' is offset by an amount to make one full
        // revolution of the color wheel (range 65536) along the length
        // of the strip (strip.numPixels() steps):
        int      hue   = firstPixelHue + c * 65536L / strip.numPixels();
        uint32_t color = strip.gamma32(strip.ColorHSV(hue)); // hue -> RGB
        strip.setPixelColor(c, color); // Set pixel 'c' to value 'color'
      }
      strip.show();                // Update strip with new contents
      delay(wait);                 // Pause for a moment
      firstPixelHue += 65536 / 90; // One cycle of color wheel over 90 frames
    }
  }
}

Hi

Von 'Endlos' sehe ich Da Nichts.
Bisher dürfte nach Knopfdruck die nächste Animation 1x durchlaufen.
Dabei lässt sich Diese aber NICHT durch Knopfdruck abschalten, da die Animationen selber per delay() die ganze Zeit 'Nicht machen'.

Erst, wenn die Animation beendet ist, läuft loop() normal durch - bis Du das nächste Mal den Taster drückst - dann kommt die nächste Animation.
Wenn Diese nun 23 Minuten braucht ... jo ... braucht Die halt 23 Minuten - unabbrechbare 23 Minuten!

Setze den SWITCH-Block direkt in die loop() und bastel die einzelnen Animationen so um, daß Diese NICHT blockieren.
In jeder Animation musst Du Dir merken, WANN Du zuletzt was gemacht hast und ggf. WAS Du gemacht hast (wird auf eine weitere SWITCH hinaus laufen).
Dort prüfst Du, ob schon genug Zeit vorbei ist - wenn nicht, machst Du Nichts (also verlässt diese Funktion direkt wieder).
Da druch kommt der Arduino zig Mal in dieser Funktion an, und nahezu immer muß Er NICHTS machen.
ABER: Du kannst in der loop() weiterhin Deinen Taster abfragen und den Modus umstellen - IMMER!

Bei den Modi 0-6 musst Du den 'Befehl' nur 1x ausführen - wenn der Stripe bereits rot ist, wird Der nicht viel roter.

Somit verbleiben 'nur' die beiden Rainbow's, Die Du in Einzelschritte zerlegen musst.

Pack erst Mal die SWITSH in die loop() (also aus der IF raus) und kümmere Dich darum, daß die Farbzuweisung nur 1x ausgeführt wird (spart Rechenzeit, an der Optik ändert sich Nichts).

Wenn Du Das 'gefressen' hast, können wir schauen, wie man die Regenbögen vereinzelt.

mfG

Da könnte man evtl. Anleihen bei meinem Weihnachtsstern nehmen.
Ist auch unter den "geilen Projekten" hier verlinkt.
Jede Animation hat einen Initialisierungsteil und einen, der dann weiter schaltet (mit individuellen Zeiten).

Gruß Tommy

Danke für deine Erklärung. Du hast recht, bis jetzt ist da noch kein loop eingebaut. Habe leider nicht genügend Wissen um dir zu folgen, werde es heute auch nicht mehr kapieren, aber morgen nachmittag hab ich Zeit mich nochmal ausführlich damit zu befassen.

Deine Erklärung hört sich an als das du genug Ahnung von der Materie hast, vielleicht hast du nicht Lust ein paar Minuten zu coden, weil wenn du die Fotos im Anhang anschaust wirst du vielleicht nachvollziehen können das ich dafür nicht ubedingt monate am Rechner verbringe :slight_smile:

Soll nur ein schönes Nachtlicht mit verschiedenen Modi werden. Ich wäre dir sehr dankbar wenn du etwas Zeit opfern würdest

Hi

Die Zeit opfern wir hier Alle - täglich.
Aber es kommt nur äußerst selten vor, daß wir einen mundgerechten Sketch abliefern.
(bisher 1x für Karneval ... von dem User hört man nun auch nicht mehr viel ... ich bitte um Korrektur)

Lies Dir meinen Post Morgen noch ein Mal durch und versuche genau Das zu machen, was ich Da geschrieben habe - die SWITCH direkt in die loop() - und nicht erst in einer IF.
Dann wird schon Mal jeder Modus immer wiederholt.
Bei den ersten 7 Modi - kein Problem.
Aus 7 und 8 wirst Du aber nur schwer wieder raus kommen.
Da Das dann doch schon etwas komplizierter werden wird, sollst Du erst Mal schauen, ob Du die Farbzuweisungen (der Modi 0-6) auf 1x begrenzen kannst - die Aufrufe danach soll dieser Switch-Bereich NICHTS machen.

Wenn Das so weit steht - wir sind hier!

MfG

Ja kann dich auch wiederum verstehen, aber wenn ich dir verspreche das Erbgenis als Projekt für alle vorzustellen, sieht es dann vielleicht anders aus? Dann hätten zumindest alle was davon und Zeit opfern wir dann beide.

Werd mir aber trotzdem morgen nochmal deine Erklärung anschauen und versuchen umzusetzen ...

Hab mir heute mehere Stunden um die Ohren geschlagen aber ohne Erfolg. Hab versucht einzelne Code Blöcke zu verschieben, aber folgen und umsetzen ging nicht wirklich. Keine Ahnung wie man eine Funktion oder Switch öffnet oder schließt usw ...

Und ehrlich gesagt ist es der Zweck nicht wert tagelang von Grund auf sämtliche Dokumentation zu studieren. Es soll schließlich nur ein hübsches Nachtlicht für ein Kind werden und nicht mein Studienprojekt :slight_smile:

Da ihr beide bedeutend mehr Ahnung von der Materie habt kann ich nur nochmals nett fragen ob sich jemand erbarmt etwas zu coden ... Ansonsten muss ich halt hoffen irgendwo einen halbwegs fertigen Sketch zu finden

Das ist auch keine Sache, die man mit Null-Ahnung mal so schnell umbaut. Du hast letztendlich 3 Varianten

  1. Du lernst die Grundlagen und irgendwann kannst Du es realisieren
  2. Du bezahlst einen Dienstleister, um das für Dich zu tun
  3. Du verzichtest darauf
    (4. Du findest einen, der das kostenlos für Dich programmiert)

Das ist wie mit Deinem Auto. Wenn Du da ein Problem hast, hast Du auch diese Möglichkeiten. Warum sollte das in der Programmierung anders sein?

Gruß Tommy

Hi

Soll Das jetzt daran scheitern, weil Du nicht Willens bist, den SWITCH-Bereich aus der IF-Abfrage raus zu holen?

Der Sketch ist bereits brauchbar eingerückt (STRG+T in der IDE - rückt den Code auf Klammer-Ebene ein).
Dort sieht man, Was zusammen gehört - Alles, was 'einen nach Hinten' geschoben ist, gehört dazu.

if (...){
___switch (...){
___ ___ case 0: irgendwas;break;
___ ___ case 1: irgendwas anderes;break;
___ ___ default: wenn sonst nix passt;break;
___ }
}

Man KANN erkennen, was Alles zum switch gehört - den Kram markieren, ausschneiden, als erste Zeile in die loop() einfügen (innerhalb des loop-Körper ... also innerhalb der geschweiften Klammern)

Eigentlich kannst Du meine Ausführungen oben fast wortwörtlich genau so umsetzen ... oder wo klemmt's?

MfG

PS: Für stundenlange Versuche sind die gezeigten Fehlversuche aber ... übersichtlich.
Auch wäre ein 'klappt nicht' keine wirklich zielführende Beschreibung des Fehlverhalten.

PPS: Wenn Es Dir nicht wert ist, sich damit zu beschäftigen, warum sollte es mir überhaupt was wert sein?
Mit Deiner Einstellung ist davon auszugehen, daß wir Dich hier nach nie wieder sehen werden - da investiere ich doch lieber in einem Thread, wo der TO 'Arduino' machen WILL - Der kommt nämlich mit neuen Ideen wieder, macht sich Gedanken und wird vll. sogar eine meiner Fragen zukünftig beantworten oder Seinen Standpunkt dazu einbringen.

Hier sind viele Leute, Die verdammt viel über Arduino und C++ wissen, aber eben Hilfe zur Selbsthilfe anbieten - Wissen vermehrt sich, indem man Es teilt.
Mit C&P ist Dir nicht geholfen, da der dann vorhandene Sketch nicht Mal an Kleinigkeiten von Dir selber angepasst werden kann.

Stimmt, ihr seht mich nicht mehr ... Hab keinen Bock mehr mich von euch ach so klugen Programmierern blöd anmachen zu lassen. Ja ich könnte dir auch Fragen beantworten, allerdings nicht im Coden, aber wir könnten ja in die Werkstatt gehen und mal sehen was ihr dann für Fragen habt wenn es heißt: hier ist Werkzeug und jetzt drück das Seitenteil raus oder schweiß mal nen neuen Schweller ins Auto ...

Hi

Dann komme ich aber mit 'mimimimi ... ich will, daß Du mir Das machst' aber wohl auch nicht ans Ziel, oder?
Und keine Angst - manch Einer hier hat sogar 'Werkstatt-Skills' - davon ab kann man Dellen auch ziehen - und wenn man gefressen hat, auf welcher Seite der Lötkolben heiß wird, bekommt man zumindest 'Loch an Loch und hält doch' mit dem Back-o-mat (... Schweißgerät) hin.
Bestimmt nicht, wie der Profi - aber wenn man nicht bestrebt ist, Das zu ändern, kann man Das auch gleich lassen.

Solltest Du keine Parallelen sehen - ich schon!

War schön mit Dir - dann werde ich Mal schauen, ob ich auch ohne Deine Anwesenheit mein seelisches Gleichgewicht gehalten bekomme.

MfG

PS: Zumindest musst Du zugeben, daß die hier 'ach so klugen Programmierer' wohl doch irgendwie klüger sind, als der Fragesteller - mindestens in der Rubrik 'Programmieren'.
Und noch schlimmer: Hier sind auch Nicht-Programmierer meld, Die bei den 'ach so klugen' mitmischen :wink: