Frage zu Neo Pixel Streifen

Hallo an alle
Ich möchte in meinen Gang eine Neo Pixel Streifen an der Decke installieren.
Es ist Neo Pixel Streifen mit WS2811 Treibern im Betrieb.
Es gibt 3 Taster,
Taster 1 Led laufen von Links nach Rechts.
Taster 2 Led laufen von Rechts nach links.
Taster 3 Led sollen nur Punktweisen leuchten.
Und jetzt das Problem, wenn ich im Code bei NUMPIXELS 100 eintrage bleibt
der Letzte 3 er Block des Neo Pixel Streifen aus.
Trage ich im Code bei NUMPIXELS 101 ein geht er an.
Das gilt für Taster 1 und 2
Bei Taster 3 sollen ja nur Punktweise Leds aufleuchten.
Wenn ich bei :

"pixels.setPixelColor (0, pixels.Color(0, 255, 0));"
"pixels.setPixelColor (99, pixels.Color(0, 255, 0));"

Eintrage leuchtet das 1 und das 99 Segment mit 3 Leds auf.

Trage ich aber jetzt im Code bei "NUMPIXELS 101" ein
Leuchten bei Taster 1 und 2 dann alle Leds auf.
Hat da jemand eine Idee woran das Liegen kann.

#include <Adafruit_NeoPixel.h>
#define PIN        8
#define NUMPIXELS 100
Adafruit_NeoPixel pixels(NUMPIXELS, PIN, NEO_GRB + NEO_KHZ800);
bool st;

void setup()
{
  pinMode(2, INPUT_PULLUP);
  pinMode(3, INPUT_PULLUP);
  pinMode(4, INPUT_PULLUP);
  pixels.begin();
}

void loop()
{
  if (digitalRead(2))setA();
  else if (digitalRead(3))setB();
  else if (digitalRead(4))setC();
}

void setA()
{
  for (int j = 0; j < NUMPIXELS; j++) {
    setd(0, j);
    delay(25);
  }
  delay(1000);
  for (int j = 0; j < NUMPIXELS; j++) {
    setd(j, NUMPIXELS - 1);
    delay(25);
  } pixels.clear();
}

void setB()
{
  for (int j = NUMPIXELS - 1; j > 0; j--) {
    setd(j - 1, NUMPIXELS - 1);
    delay(25);
  }
  delay(1000);
  for (int j = NUMPIXELS - 1; j > 0; j--) {
    setd(0, j - 1);
    delay(25);
  } pixels.clear();
}

void setC()
{
  pixels.setPixelColor(0, pixels.Color(0, 255, 0));
  delay(25);
  pixels.show();

  pixels.setPixelColor(99, pixels.Color(0, 255, 0));
  delay(25);
  pixels.show();
  
  delay(2000);
  pixels.clear();
  pixels.show();
}

void setd(int st, int ed)
{
  pixels.clear();
  for (int i = st; i < ed; i++) { // For each pixel...
    pixels.setPixelColor(i, pixels.Color(0, 255, 0 ));
    //delay(5);
  }
  pixels.show();
}

Gruss Stefan

Ist durch den PullUp die erste Bedingung nicht immer wahr, solange du den Taster nicht drückst? Vom Gefühl her solltest du die Logik eher umdrehen.

Wo kommt den auf einmal diese "magische" Nummer her? Soll das nicht NUMPIXELS - 1 sein?

@ wwerner
Hallo
Was meinst du damit."Soll das nicht NUMPIXELS - 1 "

Das habe ich aus einen Beispielcode übernommen.

"pixels.setPixelColor(99, pixels.Color(0, 255, 0));"
Für Aufklärung wäre ich Dankbar

Gruss Stefan

Hast du es auch verstanden? Oder einfach nur kopiert?

Magische Nummern:
Ein im Quellcode eines Programms auftauchender Zahlenwert (auch englisch „hard coded value“ genannt), dessen Bedeutung sich nicht unmittelbar erkennen lässt – seine Bedeutung ist somit „magisch“. Derartige Magische Zahlen sind zu vermeiden und durch gut benannte Konstantendefinitionen zu ersetzen, deren Namen, Bedeutung und Herkunft klar angegeben ist. Aus: Magische Zahl (Informatik) – Wikipedia

Hallo wwerner
Also wie ich es verstanden habe spreche ich mit der Nummer 99 den letzen Led Controller an. Weil der Neo Pixel Streifen hat 100 Controller der erste beginnt mit 0 und der letze ist dann der 99 zigste, Wenn ich es falsch verstanden habe bitte ich um Berichtigung von dir.
Das klapp ja alles soweit wie ich mir das Vorstelle.
Nur was ich nicht verstehe ist wenn ich bei
"#define NUMPIXELS 100" eintrage bleibt der letze Block aus.
Trage ich 101 ein geht der letze Block mit an.
Und Trage ich hier 99 ein geht der letze Block mit an.

pixels.setPixelColor(99, pixels.Color(0, 255, 0));

Und da ist mein Problem.
Kann auch ein Denkfehler von mir sein.
Kann auch gerne mal Bilder Posten.

Danke Stefan

Hallo Plumps
Kannst du mir das mal ein einem Beispiel verdeutlichen wie das meinst.
Danke Stefan

Du liest das Potenzial an einem PIN den du im Setup mit einem PullUp ausstattest. Durch den PullUp ist das Potenzial an dem Pin ohne Einfluss von außen HIGH. Über einen Taster kannst du das Potenzial auf GND ziehen. Sprich bei gedrückten Taster hättest du am Pin ein LOW.

Jetzt fragst du in deinem Code im Loop ob der PIN HIGH ist und führst eine Funktion aus.

Also wird die Funktion immer ausgeführt, solange du den Taster nicht drückst. Laut Beschreibung im Eingangspost, liest es sich, das etwas ausgeführt werden soll, wenn der Taster gedrückt wird, und nicht, wenn er nicht gedrückt wird.

Meine Sicht auf die Dinge:

  • Problem 1 (schon erwähnt #5):
    Magic Numbers
  • Problem 2 (schon erwähnt # 8):
    Falsche Logik beim digitalRead() der Schalter-Pins
  • Problem 3:
    Du solltest Dich entscheiden, ob die Grenzen der zu setzenden Pins in setA(), setB(), setC() oder aber in setd() angegeben werden sollen.
    Mögliche Abhilfe: i <= ed in setd() - was Dein eigentlich beschriebenes Problem mit der 100 und der 101 löst.
  • Problem 4:
    Ausschalten des letzten Pixels in setA() und setB() funktioniert nicht, weil hinter dem pixels.clear() jeweils ein pixels.show() fehlt.

Zum Anschauen etwas langsamer und mit nur 30 Lämpchen:

Code (nur angepasst, noch nicht schön)
#include <Adafruit_NeoPixel.h>
#define LED_PIN       8
#define SWITCH_A_PIN  2
#define SWITCH_B_PIN  3
#define SWITCH_C_PIN  4
#define NUMPIXELS    30 // 100
#define SHORT_WAIT  100 // 25
#define LONG_WAIT  2000 // 1000

Adafruit_NeoPixel pixels(NUMPIXELS, LED_PIN, NEO_GRB + NEO_KHZ800);
bool st;

void setup()
{
  pinMode(SWITCH_A_PIN, INPUT_PULLUP);
  pinMode(SWITCH_B_PIN, INPUT_PULLUP);
  pinMode(SWITCH_C_PIN, INPUT_PULLUP);
  pixels.begin();
}

void loop()
{
  if (!digitalRead(SWITCH_A_PIN))      setA();
  else if (!digitalRead(SWITCH_B_PIN)) setB();
  else if (!digitalRead(SWITCH_C_PIN)) setC();
}

void setA()
{
  for (int j = 0; j < NUMPIXELS; j++) {
    setd(0, j);
    delay(SHORT_WAIT);
  }
  delay(LONG_WAIT);
  for (int j = 0; j < NUMPIXELS; j++) {
    setd(j, NUMPIXELS - 1);
    delay(SHORT_WAIT);
  } 
  pixels.clear();
  pixels.show();
}

void setB()
{
  for (int j = NUMPIXELS - 1; j > 0; j--) {
    setd(j - 1, NUMPIXELS - 1);
    delay(SHORT_WAIT);
  }
  delay(LONG_WAIT);
  for (int j = NUMPIXELS - 1; j > 0; j--) {
    setd(0, j - 1);
    delay(SHORT_WAIT);
  } 
  pixels.clear();
  pixels.show();
}

void setC()
{
  pixels.setPixelColor(0, pixels.Color(0, 255, 0));
  delay(SHORT_WAIT);
  pixels.show();

  pixels.setPixelColor(NUMPIXELS-1, pixels.Color(0, 255, 0));
  delay(SHORT_WAIT);
  pixels.show();
  
  delay(2*LONG_WAIT);
  pixels.clear();
  pixels.show();
}

void setd(int st, int ed)
{
  pixels.clear();
  for (int i = st; i <= ed; i++) { // For each pixel...
    pixels.setPixelColor(i, pixels.Color(0, 255, 0 ));
    //delay(5);
  }
  pixels.show();
}

Hallo an alle
Erst mal Danke an alle für die Antworten.
Werde jetzt mal ein bisschen Tesen und mich dann wieder melden

Danke Stefan

Was soll denn ein "3er Block" sein?
Ein Streifen mit 100 LED hat einzelne LED von 0-99.

cu

Nicht bei WS2811

Ahhh ...., alles nochmals durchgelesen, 100 Controller.

cu

Also in "B" übergibst Du durch zweimalig von -1 ja nur 98-0 ...

void setB() {

  for (int j = NUMPIXELS - 1; j > 0; j--) {	// läuft von 99-0
    setd(j - 1, NUMPIXELS - 1);				// Übergabe von 98-0, 99	
    delay(25);
  }

  delay(1000);

  for (int j = NUMPIXELS - 1; j > 0; j--) {	// läuft von 99-0
    setd(0, j - 1);							// Übergabe von 0, 98-0
    delay(25);
  }
  
  pixels.clear();

}

Mit 101 entsprechend die korrekte 99.

Hallo hawe07546
Danke für die Antwort.
Bei meine Neo Pixel Streifen ist 1 Controller für 3 Leds zuständig.

Wie kann man den Code ändern das man mit
#define NUMPIXELS 100 alle zum leuchten bringt .Da fehlt mir die Erfahrung.

Und noch eine Frage , wie kann ich den Neo Pixel Streifen teilen .
Das z.b. von 50 nach 0 und dann noch von 51 nach 100 Zählt.
Danke Stefan

Das hatten wir schon - wenn Du als Maximum NUMPIXELS - 1 an die Funktion setd() übergibst, musst Du darin in der for-Schleife auch bis dahin zählen lassen (i <= ed) und nicht einen Pixel vorher aufhören (i < ed):

void setd(int st, int ed)
{
  pixels.clear();
  for (int i = st; i <= ed; i++) { // For each pixel...
    pixels.setPixelColor(i, pixels.Color(0, 255, 0 ));
    //delay(5);
  }
  pixels.show();
}

Das folgende ist etwas unklar - gleichzeitig oder nacheinander?

Hier ist die Lösung, wo gleichzeitig von der Mitte nach außen gearbeitet wird:

void setMitteNachAussen()
{
  for (int j = 0; j < NUMPIXELS; j++) {
    setd(NUMPIXELS/2 - j, NUMPIXELS/2 + j);
    delay(SHORT_WAIT);
  }
  delay(LONG_WAIT);
  for (int j = 0; j < NUMPIXELS; j++) {
    setd(j, NUMPIXELS - j);
    delay(SHORT_WAIT);
  }
  pixels.clear();
  pixels.show();
}

Wer's ansehen mag:

Hallo wno158
Danke für die schnelle Antwort.
Jetzt habe ich es verstanden,mit dem " (i <= ed) "
Da wäre ich nie draufgekommen. Ich habe erst die Woche mit den
Neo Pixel Streifen angefangen für meinen Flur zu Programmieren.
Nochmal danke für die vielen Antworten.
Gruss Stefan

Kleiner Tip am Rande. Du kannst das auch mit der Lib FastLED aufbauen. Die ist schneller.

Zum Programmieren musst du lernen, das Programm im Kopf laufen zu lassen. Mit allen Rechnungen

Hallo wwerner
Das mit dem Programmieren klappt ja schon ganz gut. Aber das mir den Neo Pixeln habe ich erst diese Woche Angefangen. Und das war mir bis jetzt neu , ist aber interesant was man damit machen kann.Werde es auf jedenfall weiter ausbauen.
GrussStefan