Neopixel wechselt den Modus ohne Grund

Ich habe eine Neopixelkette unter meinem Longboard die in bestimmten Mustern leuchten soll, nun habe ich allerdings das Problem das sich die Muster jedes mal ändern nachdem sie sich einmal durchgelaufen sind, ich weiss allerdings nicht wieso. Eigentlich soll es so laufen das ich einen Taster drücke und dadurch dann der Modus geändert wird.

Meine Inspiration kommt von folgender Seite:

Code ist der:

#include <Adafruit_NeoPixel.h>
#include <avr/power.h>

#define PIN 3                     //Die Neo pixel hängen an Pin 3


const int ledsGesamt = 120;
int modus = 0;
volatile int tasterstatus = 0; 
volatile unsigned long alteZeit=0, entprellZeit=20;
const int taster=4;               //schalterpin
const int led = LED_BUILTIN;      //für testzwecke

Adafruit_NeoPixel strip = Adafruit_NeoPixel(ledsGesamt, PIN, NEO_GRB + NEO_KHZ800);


void setup() {
  pinMode(taster, INPUT_PULLUP);
  pinMode(led, OUTPUT);
  strip.begin();
  strip.show(); // Initialize all pixels to 'off'
  attachInterrupt( digitalPinToInterrupt (taster), interruptRoutine, RISING);
}


void loop() {


if (tasterstatus== LOW){
tasterstatus=0;
modus++;
}




  if (modus == 1) {
    rainbowCycle(1);
  
  } else if (modus == 2) {
    theaterChaseRainbow(1);
  
  } else if (modus == 3) {
    colorWipe(strip.Color(255, 0, 0), 30); // Red
    colorWipe(strip.Color(0, 255, 0), 30); // Green
    colorWipe(strip.Color(0, 0, 255), 30); // Blue
  
  } else if (modus == 4) {
    theaterChase(strip.Color(127, 127, 127), 1);
  
  } else if (modus == 5) {
    theaterChaseRainbow (1) ;
  }
  
}
void interruptRoutine() {                             //Interruptroutine und entprellen
  if((millis() - alteZeit) > entprellZeit) { 
    // innerhalb der entprellZeit nichts machen
    tasterstatus=LOW;// LED umschalten
    alteZeit = millis(); // letzte Schaltzeit merken      
  }
}





// Fill the dots one after the other with a color
void colorWipe(uint32_t c, uint8_t wait) {
  for(uint16_t i=0; i<strip.numPixels()/2; i++) {
      strip.setPixelColor(i, c);
      strip.setPixelColor(strip.numPixels()-i, c);      
      strip.show();
      delay(wait);
  }
}

void rainbow(uint8_t wait) {
  uint16_t i, j;

  for(j=0; j<256; j++) {
    for(i=0; i<strip.numPixels()/2; i++) {
      strip.setPixelColor(i, Wheel((i+j) & 255));
      strip.setPixelColor(strip.numPixels()-i, Wheel((i+j) & 255));      
    }
    strip.show();
    delay(wait);
  }
}

// Slightly different, this makes the rainbow equally distributed throughout
void rainbowCycle(uint8_t wait) {
  uint16_t i, j;

  for(j=0; j<256*2; j++) { // 5 cycles of all colors on wheel
    for(i=0; i< strip.numPixels()/2; i++) {
      strip.setPixelColor(strip.numPixels()/2-i, Wheel(((i * 256 / strip.numPixels()) + j) & 255));
      strip.setPixelColor(strip.numPixels()/2+i, Wheel(((i * 256 / strip.numPixels()) + j) & 255));      
    }
    strip.show();
    delay(wait);
  }
}

//Theatre-style crawling lights.
void theaterChase(uint32_t c, uint8_t wait) {
  for (int j=0; j<4; j++) {  //do 10 cycles of chasing
    for (int q=0; q < 3; q++) {
      for (int i=0; i < strip.numPixels()/2; i=i+3) {
        strip.setPixelColor(i+q, c);    //turn every third pixel on
        strip.setPixelColor(strip.numPixels()-(i+q), c);    //turn every third pixel on        
      }
      strip.show();
     
      delay(wait);
     
      for (int i=0; i < strip.numPixels()/2; i=i+3) {
        strip.setPixelColor(i+q, 0);        //turn every third pixel off
        strip.setPixelColor(strip.numPixels()-(i+q), 0);        //turn every third pixel off        
      }
    }
  }
}

//Theatre-style crawling lights with rainbow effect
void theaterChaseRainbow(uint8_t wait) {
  for (int j=0; j < 256; j++) {     // cycle all 256 colors in the wheel
    for (int q=0; q < 3; q++) {
        for (int i=0; i < strip.numPixels()/2; i=i+3) {
          strip.setPixelColor(i+q, Wheel( (i+j) % 255));    //turn every third pixel on
          strip.setPixelColor(strip.numPixels()-(i+q), Wheel( (i+j) % 255));    //turn every third pixel on          
        }
        strip.show();
       
        delay(wait);
       
        for (int i=0; i < strip.numPixels()/2; i=i+3) {
          strip.setPixelColor(i+q, 0);        //turn every third pixel off
          strip.setPixelColor(strip.numPixels()-(i+q), 0);        //turn every third pixel off          
        }
    }
  }
}








// Input a value 0 to 255 to get a color value.
// The colours are a transition r - g - b - back to r.
uint32_t Wheel(byte WheelPos) {
  WheelPos = 255 - WheelPos;
  if(WheelPos < 85) {
   return strip.Color(255 - WheelPos * 3, 0, WheelPos * 3);
  } else if(WheelPos < 170) {
    WheelPos -= 85;
   return strip.Color(0, WheelPos * 3, 255 - WheelPos * 3);
  } else {
   WheelPos -= 170;
   return strip.Color(WheelPos * 3, 255 - WheelPos * 3, 0);
  }
}

Wie lang ist dein Kabel zum Taster ?
Und was für Kabel ist das ?

niho33:
nun habe ich allerdings das Problem das sich die Muster jedes mal ändern nachdem sie sich einmal durchgelaufen sind, ich weiss allerdings nicht wieso.

LOW ist gleich 0. tasterstatus hat niemals einen anderen Wert. Deshalb.

Das Entprellen könntest du dir auch sparen, deine blockierenden Animamationen erlauben kein Prellen der Taste.
Ebenso könnte der ein oder andere Tastendruck verloren gehen,
da .show() die Interrupts für beträchtliche Zeit abschaltet.

Das Kabel ist in etwa 17cm lang und ist ziemlich dünn, hat bei tests mit einer LED aber funktioniert, die eine Seite des Tasters ist an GND die andere an PIN4

niho33:
Das Kabel ist in etwa 17cm lang und ist ziemlich dünn, hat bei tests mit einer LED aber funktioniert, die eine Seite des Tasters ist an GND die andere an PIN4

Ok, das Kabel ist wohl nicht das Problem.

Whandall hat dir aber schon den Weg gezeigt.

Ich habe tasterstatus=0 durch tasterstatus= HIGH ersetzt und jetzt funktioniert es gar nicht mehr, kann ich die show() Befehle durch andere Befehle ersetzen?

niho33:
Ich habe tasterstatus=0 durch tasterstatus= HIGH ersetzt und jetzt funktioniert es gar nicht mehr, kann ich die show() Befehle durch andere Befehle ersetzen?

Ich kann nicht erkennen, wozu du den Status festschreibst.

Das macht keinen Sinn, also würde ich den entfernen, nur dann kannst du den Taster auch auswerten.

niho33:
Ich habe tasterstatus=0 durch tasterstatus= HIGH ersetzt und jetzt funktioniert es gar nicht mehr,

Dann war das wohl nicht genug oder eine falsche Änderung.

niho33:
kann ich die show() Befehle durch andere Befehle ersetzen?

Nein. Gesetzt der Fall deine LEDs sollen etwas anzeigen.

Gute Frage eigentlich weshalb ich den tasterstatus drin habe, habe wahrscheinlich mal nen Interrupt irgendwo rauskopiert und so bei mir rein kopiert.

Warum so kompliziert?

(compiled aber ungetestet)

#include <Adafruit_NeoPixel.h>

const int ledsGesamt = 120;
byte modus = 0;
volatile bool tasteGedrueckt = false;
const byte taster = 4;

Adafruit_NeoPixel strip(ledsGesamt, 3, NEO_GRB + NEO_KHZ800);

void interruptRoutine() {
  tasteGedrueckt = true;
}

void setup() {
  pinMode(taster, INPUT_PULLUP);
  strip.begin();
  strip.show();
  attachInterrupt( digitalPinToInterrupt (taster), interruptRoutine, FALLING);
}

void loop() {
  if (tasteGedrueckt) {
    tasteGedrueckt = false;
    if (++modus > 5)
      modus = 0;
  }
  if (modus == 1) {
    rainbowCycle(1);
  } else if (modus == 2) {
    theaterChaseRainbow(1);
  } else if (modus == 3) {
    colorWipe(strip.Color(255, 0, 0), 30); // Red
    colorWipe(strip.Color(0, 255, 0), 30); // Green
    colorWipe(strip.Color(0, 0, 255), 30); // Blue
  } else if (modus == 4) {
    theaterChase(strip.Color(127, 127, 127), 1);
  } else if (modus == 5) {
    theaterChaseRainbow (1) ;
  }
}

// Fill the dots one after the other with a color
void colorWipe(uint32_t c, uint8_t wait) {
  for (uint16_t i = 0; i < strip.numPixels() / 2; i++) {
    strip.setPixelColor(i, c);
    strip.setPixelColor(strip.numPixels() - i, c);
    strip.show();
    delay(wait);
  }
}

void rainbow(uint8_t wait) {
  uint16_t i, j;

  for (j = 0; j < 256; j++) {
    for (i = 0; i < strip.numPixels() / 2; i++) {
      strip.setPixelColor(i, Wheel((i + j) & 255));
      strip.setPixelColor(strip.numPixels() - i, Wheel((i + j) & 255));
    }
    strip.show();
    delay(wait);
  }
}

// Slightly different, this makes the rainbow equally distributed throughout
void rainbowCycle(uint8_t wait) {
  uint16_t i, j;

  for (j = 0; j < 256 * 2; j++) { // 5 cycles of all colors on wheel
    for (i = 0; i < strip.numPixels() / 2; i++) {
      strip.setPixelColor(strip.numPixels() / 2 - i, Wheel(((i * 256 / strip.numPixels()) + j) & 255));
      strip.setPixelColor(strip.numPixels() / 2 + i, Wheel(((i * 256 / strip.numPixels()) + j) & 255));
    }
    strip.show();
    delay(wait);
  }
}

//Theatre-style crawling lights.
void theaterChase(uint32_t c, uint8_t wait) {
  for (int j = 0; j < 4; j++) { //do 10 cycles of chasing
    for (int q = 0; q < 3; q++) {
      for (byte i = 0; i < strip.numPixels() / 2; i = i + 3) {
        strip.setPixelColor(i + q, c);  //turn every third pixel on
        strip.setPixelColor(strip.numPixels() - (i + q), c); //turn every third pixel on
      }
      strip.show();

      delay(wait);

      for (byte i = 0; i < strip.numPixels() / 2; i = i + 3) {
        strip.setPixelColor(i + q, 0);      //turn every third pixel off
        strip.setPixelColor(strip.numPixels() - (i + q), 0);    //turn every third pixel off
      }
    }
  }
}

//Theatre-style crawling lights with rainbow effect
void theaterChaseRainbow(uint8_t wait) {
  for (int j = 0; j < 256; j++) {   // cycle all 256 colors in the wheel
    for (int q = 0; q < 3; q++) {
      for (byte i = 0; i < strip.numPixels() / 2; i = i + 3) {
        strip.setPixelColor(i + q, Wheel( (i + j) % 255)); //turn every third pixel on
        strip.setPixelColor(strip.numPixels() - (i + q), Wheel( (i + j) % 255)); //turn every third pixel on
      }
      strip.show();

      delay(wait);

      for (byte i = 0; i < strip.numPixels() / 2; i = i + 3) {
        strip.setPixelColor(i + q, 0);      //turn every third pixel off
        strip.setPixelColor(strip.numPixels() - (i + q), 0);    //turn every third pixel off
      }
    }
  }
}

// Input a value 0 to 255 to get a color value.
// The colours are a transition r - g - b - back to r.
uint32_t Wheel(byte WheelPos) {
  WheelPos = 255 - WheelPos;
  if (WheelPos < 85) {
    return strip.Color(255 - WheelPos * 3, 0, WheelPos * 3);
  } else if (WheelPos < 170) {
    WheelPos -= 85;
    return strip.Color(0, WheelPos * 3, 255 - WheelPos * 3);
  } else {
    WheelPos -= 170;
    return strip.Color(WheelPos * 3, 255 - WheelPos * 3, 0);
  }
}

Hallo,

ohne show() geht nix, damit gehen die Daten an den Strip.

das ganze Programm ist ziemlich vermurkst. Du musst die for schleifen durch if Abfragen ersetzen und delay() durch millis() damit du fast jederzeit an die Taster Abfrage kommst.

fang einfach mal an einen Taster normal ohne Interupt abzufragen und damit sauber einen Zähler hoch zu zählen. Wenn er bei 5 angekommen ist geht von vorne los.

Dann baust du die annimationen ein allerdings ohne for schleifen. Anstelle dessen benzut du eine Varialbe die hochgezählt wird. Vorteil es ist keine Schleife und du kannst den Taster jederzeit abfragen. Das probiert du erst mal nur mit einer aus.

kannst dir auch mal die FastLED lib ansehen da gibts sowas wie delay() was nicht blokiert.

Heinz

Die Frage mag jetzt blöd klingen, aber wie ersetze ich denn die for durch eine if schleife? einfach if statt for zu schreiben wäre wahrscheinlich zu einfach. Die Void rainbow, etc habe ich auch einfach nur kopiert und eingefügt und verstehe sie auch nicht ganz.
Das kompillierte aber nicht getestete Programm funktioniert auch nicht

niho33:
Das kompillierte aber nicht getestete Programm funktioniert auch nicht

Na dann.

niho33:
Die Frage mag jetzt blöd klingen, aber wie ersetze ich denn die for durch eine if schleife? einfach if statt for zu schreiben wäre wahrscheinlich zu einfach. Die Void rainbow, etc habe ich auch einfach nur kopiert und eingefügt und verstehe sie auch nicht ganz.
Das kompillierte aber nicht getestete Programm funktioniert auch nicht

Mit dieser Aussage hast du dein Problem offen gelegt.
Du musst zwingend die Grundlagen lernen. Ohne die wird das nichts.
Leider....

Was für einen Arduino benutzt du?

Ist Pin 4 bei dem wirklich ein Interrupt Pin?

Für Nano und Uno wäre er das nicht.

External Interrupts: 2 and 3. These pins can be configured to trigger an interrupt on a low value, a rising or falling edge, or a change in value. See the attachInterrupt() function for details.

Whandall:
Na dann.

was funzt da nicht , du könntest ja noch ein paar serial.println(modus) einbauen um zu sehen ob der modus sich ändert. Eigendlich müsste das gehen.

Du musst auch nicht alle for() ersetzen , die innern sind meiner Meinung nach schnell genug, bedenke strip.show() und delay() ist das Problem, das sollte aus der for() raus und ersetzt werden.

Heinz

Hi

Wenn man denn wüsste, WAS 'nicht funzt', könnte man Da ja drauf eingehen.

Was zumindest NICHT DIREKT 'funzen' wird, ist das Reagieren auf den Tastendruck - DAS könnte man aber durch fein verteilte break; etwas (arg) beschleunigen.

Ich behaupte, daß Whandall's Sketch durchaus Funktion zeigt, aber nicht mit Der von Dir Gewünschten überein stimmt.
Dazu ist aber etwas mehr nötig als 'funzt nicht'.

MfG

Funktioniert der Sketch wenn du Pin 2 oder Pin 3 für die Taste benutzt?