WS2812 immer nur eine LED geht an

Guten Abend,

ich habe folgendes Problem:

Adafruit_NeoPixel pixels = Adafruit_NeoPixel(NUMPIXELS, PIN, NEO_GRB + NEO_KHZ800);

void loop ()
{

i = Lauflicht (pixels, i, 41, 1000);

}

int Lauflicht(Adafruit_NeoPixel test,int f, int AnzahlPixel, int Pausenzeit)
{
  
  test.setPixelColor(f, test.Color(150,0,0));

  test.show();

  delay (Pausenzeit);
  
  f=f+1;
  Serial.println(f);
  if (f == 50)
  {
    f=0;
  }
  return f;
}

Ich möchte mir ein Lauflicht bauen in einer Funktion. Allerdings nimmt die setPixelColor Funktion immer nur den ersten Wert an. Bedeutet, wenn ich i mit 20 initialisiere, geht nur LED 20 an. Initialisiere ich i mit 10, geht nach hochladen nur LED 10 an. Die Variable läuft jedoch hoch.....da sich also f ändert, sollte doch auch die LEDs nacheinander angehen.....wo liegt das Problem???

Vielen Dank schonmal

Dir ist schon klar, dass das Beispiel nicht testbar ist, oder?
Fehlermeldungen ohne Ende...

Die Variable läuft jedoch hoch.....

Da zählt nix hoch.

// vermutlich Unsinn
int Lauflicht(Adafruit_NeoPixel test,int f, int AnzahlPixel, int Pausenzeit)

// vermutlich das gewünschte
int Lauflicht(Adafruit_NeoPixel &test,int f, int AnzahlPixel, int Pausenzeit)

Hi

Da noch nicht Mal NUMPIXELS in dem Snipped vorkommt, wird Es sich kaum lohnen, den Rest anzusehen - kompilieren wird Das SO nie.

Wer ist i?
Wer Lauflicht ist, frage ich Mal noch nicht, könnte sich in den hinteren Reihen ergeben - Da gucke ich aber erst hin, wenn's vorne herum auch sauber ist und passt!

MfG

Also das i und numpixels als int irgendwo ganz oben definiert sind, darauf kann man doch irgendwie kommen.

Also, damit es sich auch lohnt das ganze anzuschauen....numpixel kann auch irgendeine Zahl sein, bestmöglich unter 32000....und i wird natürlich definiert als ist i;

Punkt 1:
Wenn du nicht in der Lage bist, oder dich gar willentlich dagegen sträubst, ein Programm auf ein testbares Minimum zu bringen, dann kann dir hier nicht fundiert geholfen werden.
Denn: In weit über 50% der hier präsentierten Fälle liegt der Fehler im ausgeblendeten Bereich.

Merke:
Diese Fähigkeit/Arbeit, des auf den Punkt bringens, ist mit das wichtigste Verfahren beim Debuggen.

Und dieses willst du nicht leisten?

Wegen bockig?
Dann tust du mir leid, für die vielen Probleme, welche noch auf dich zu kommen!

Du kannst nicht?
Dann lerne es!

Zu faul?
Sorgfalt und Disziplin bringen dich weiter.
Und ja: Das ist mit Arbeit verbunden.

Punkt 2:
Ich habe dir die (vermutliche) Lösung schon längst genannt!
Was passt dir daran nicht?
Zu einfach?

Puh, so ein Forum ist leider nicht mehr da was es früher einmal war. Früher hat man von denjenigen die Ahnung haben Hilfe bekommen und die, die keinen Plan hatten, haben sich raus gehalten. Heute bekommt man nur noch die Formfehler derer die keinen Plan haben vorgehalten und muss sich dann damit rumschlagen.

Muss man denn expliziert hinzufügen, dass nur Antworten von Leuten erwünscht sind, die nicht googeln müssen was ein ws2812 ist und dann weil sie den ganzen Tag Langeweile haben zur Aufbesserung des Selbstwertgefühls ihre Standardsätze los schießen, nur um an einer Diskussion beigetragen zu haben.....aber eigentlich keinen Plan davon haben.

Trotzdem danke ich euch für eure Zeit....ich denke ich werde meine Zeit lieber in andere Quellen investieren.

Heute bekommt man nur noch die Formfehler derer die keinen Plan haben vorgehalten und muss sich dann damit rumschlagen.

Du irrst!

Das sind NOTWENDIGKEITEN.

PS(OT):
Ich finde es immer wieder amüsant, wenn jemand auf Kompetenzlevel 1 einem auf 3 oder 4 erklären will, wie doof dieser doch ist.

Hier https://www.arduinoforum.de/ wird er von uns die gleichen Antworten bekommen :wink:

Gruß Tommy

Ihm erzeugt eine flache Kopie beim Funktionsaufruf.
Beim dekonstruieren der Kopie wird der Pixelspeicher freigegeben und der Pin zum Input.
Danach ist jeder weitere Funktionsaufruf nur noch ein buddeln im Müll, eine Schädigung der Datenintegrität/Konsistenz des Programms.

Oh ja ... Cross-Postings ... :slight_smile:

Mein lieber Kilu ...
Mir ist durchaus bekannt, was eine WS2812B ist, hätte sogar schon Mal eine live in der Hand gehalten - war schon ein tolles Gefühl :slight_smile:

Ok, für die eigene Blödheit kann man Keinem einen Vorwurf machen - aber sollten die von mir erfragten Werte zufällig NICHT dem Datentyp entsprechen, Den Diese - NATÜRLICH - haben sollten, sind Fails vorprogrammiert (hehe - sogar wort-wörtlich).

Es ist eigentlich echt schade - Du nutzt große Buchstaben, Interpunktion, aber Deine Art ist leider nicht so 'die Meine'.
Da Du von mir scheinbar keine Hilfe haben möchtest - Anmerkung: ich Dir im Gegenzug aber mittlerweile auch Keine mehr anbieten möchte - wünsche ich Dir noch viel Spaß in Deinem Leben - vll. bist Du 'offline' ja ein großerer Crack - aber wenn Du Dir eine solche Art leisten kannst, wird's bei den Untergebenen viele Voodoo-Puppen, und bei den Vorgesetzten viel unnötiges Klopapier geben.
Wenn nicht: schau Mal in den Spiegel und frage Dich, ob Deine Anschuldigungen nicht von gaaanz tief innen drin hoch kamen.

Das MfG spare ich mir, wäre jetzt nämlich echt nur eine Floskel ...

PS: Bei den Microkontrollern ist Arduino zwar mittlerweile legitim (ich kann mich an andere Zeiten erinnern :wink: ), aber auf Cross-Postings reagieren Die Da noch mit teeren und federn ...

PS: Bei den Microkontrollern ist Arduino zwar mittlerweile legitim (ich kann mich an andere Zeiten erinnern :wink: )

Da mussten viele Schlachten geführt werden.
Mittlerweile sind die Frontlinien verschoben, aber der Krieg noch nicht beendet.
Mehr als ein vorläufiger Waffenstillstand ist noch nicht erreicht.
Und ein paar Heckenschützen sind weiter aktiv.

Da ich mich gerade mit WS2815 am ESP32 beschäftige (derzeit keine Erfolgsgeschichte), paßt ein Lauflicht da rein.

i = Lauflicht (pixels, i, 41, 1000);

Das Objekt ist global, ebenso wie die Anzahl der Pixel, weshalb mir das als Parameter überflüssig erscheint. Deshalb einfacher nur mit der Intervallzeit:

lauflicht (100);

Ein Klassiker aus den Beispielen, aber dennoch in einem Projekt unerwünscht, weil blockierend:

delay (Pausenzeit);

Besser ist eine blockedearme Variante mit millis.

Den Rest kann man dann in der Funktion erledigen:

void lauflicht(const uint32_t Pausenzeit)
{
  static uint16_t led = 0;
  static uint32_t vorhin = millis();
  if (millis() - vorhin >= Pausenzeit)
  {
    vorhin = millis();
    strip.setPixelColor(led, strip.Color(150, 0, 0));
    strip.show();
    strip.setPixelColor(led, strip.Color(0, 0, 0));
    led = (1 + led) % NUM_LEDS;
  }
}

Das Objekt ist global, ebenso wie die Anzahl der Pixel, weshalb mir das als Parameter überflüssig erscheint.

Kann man geteilter Meinung sein.
Ist allerdings eine gültige Variante.
Vielleicht nicht schön, aber tuts.

Tuts mit Sicherheit besser, als dauernd den "Default Copy Constructor" zu bemühen, und dann mit dem Destructor alles zu zerrütten.


//original Klasse erweitern
class Adafruit_NeoPixel
{
  // hier original Code

  // sinnvolle erweiterung
  public: // von mir aus auch protected:
  Adafruit_NeoPixel(const Adafruit_NeoPixel&)=delete;
  Adafruit_NeoPixel& operator=(const Adafruit_NeoPixel&)=delete;

};

Dann bekommt man den Fehler wenigstens vom Kompiler um die Ohren gehauen

combie:
Kann man geteilter Meinung sein.
Ist allerdings eine gültige Variante.
Vielleicht nicht schön, aber tuts.

Ich bin mir nicht sicher, an welcher Stelle sich die Meinung teilt, denn strip ist ein globales Objekt. Anders habe ich das in diesem Forum auch noch nicht gesehen, zumindest erinnere ich mich nicht daran.

Oder meinst Du die "ausführliche" Darlegung der Frage, die "keinerlei" Interpretationsspielraum läßt?

Deinen Änderungsvorschlag habe ich übernommen, mal abwarten, wie sich das auswirkt.

Ich bin mir nicht sicher, an welcher Stelle sich die Meinung teilt, denn strip ist ein globales Objekt. Anders habe ich das in diesem Forum auch noch nicht gesehen, zumindest erinnere ich mich nicht daran.

Oder meinst Du die "ausführliche" Darlegung der Frage, die "keinerlei" Interpretationsspielraum läßt?

Die Geister scheiden sich dort, wo Funktionen oder Methoden Daten von außerhalb benötigen.
Ich nenne das "Abhängigkeiten injizieren".
Grundsätzlich ist das nötig.
Nur das "Wie?" ist manchmal Diskussionswürdig, bzw. zum drüber nachdenken oder entscheiden.

Der Grund:

Das verwenden von globalen Variablen in Funktionen,
macht diese Funktionen abhängig,
von genau diesen globalen Variablen.

Ok, das klingt arg abgedroschen......
Wird aber sofort zum Wachmacher, wenn man mit 2 (oder mehr) Strips hantiert.
Eine solche Funktion/Methode ist nur für dieses Programm UND für diesen einen Stripe.
Eine universelle Wiederverwendung ist ausgeschlossen.
Eine, wie ich es nenne, Wegwerffunktion.

Übergibt man die Abhängigkeiten per Parameter, wird die Funktion wiederverwendbar.
Ich halte das für einen erheblichen Qualitätsgewinn.
Eine solche Funktion kann man getrost weitergeben, in Libs stopfen, und tausendfach einsetzen.

Es macht nur ein einziges mal etwas mehr Arbeit.
Danach kann man der Faulheit frönen, und entspannt die schon erledigte Arbeit wiederverwenden.


Deinen Änderungsvorschlag habe ich übernommen, mal abwarten, wie sich das auswirkt.

Wie sich das auswirkt?
Wenn du alles richtig gemacht hast, gar nicht.

Wenn du Mist baust, dann versagt das Programm nicht stumm (wie das im Eingangsposting), sondern der Kompiler haut es dir um die Ohren.

Hier mal ein Testprogramm welches beide Fehler vorführt:

#include <Adafruit_NeoPixel.h>

#define PIN         6 
#define NUMPIXELS  16 // Popular NeoPixel ring size
#define DELAYVAL  500 // Time (in milliseconds) to pause between pixels

Adafruit_NeoPixel pixels(NUMPIXELS, PIN, NEO_GRB + NEO_KHZ800);


void setup() 
{
  pixels.begin(); // allocate Memory and set pinMode()
}


// test: Adafruit_NeoPixel(const Adafruit_NeoPixel&)=delete;
//void foo(Adafruit_NeoPixel &stripe, int num) // reference: ok
void foo(Adafruit_NeoPixel stripe, int num) // flat copy: bad
{
  stripe.setPixelColor(num, stripe.Color(200, 200, 200));
}// destruct copy, frees pixels memory and sets PinMode to input


void loop() 
{
  pixels.clear();
  foo(pixels,1);
  foo(pixels,3);
  foo(pixels,5);
  pixels.show();  


  delay(DELAYVAL);

  // test: Adafruit_NeoPixel& operator=(const Adafruit_NeoPixel&)=delete;
  //Adafruit_NeoPixel &bar  = pixels; // ok
  Adafruit_NeoPixel bar; 
  bar = pixels; // problematic
  foo(bar,2);
  foo(bar,4);
  foo(bar,6);
/**/

  delay(DELAYVAL); 
}  // destruct bar, frees pixels memory and sets PinMode to input

combie:
Die Geister scheiden sich dort, wo Funktionen oder Methoden Daten von außerhalb benötigen.

Da stimme ich Dir zu!

Beim Versuch einer Hilfe bin ich immer zwischen dem, was ich vorfinde und dem, wie ich es gerne machen würde, hin- und hergerissen. Ändere ich zu viel, erkennt der TO dein Programm nicht wieder, weshalb mein Beitrag dann möglicherweise als irrelavant ignoriert wird. Auch dieses Thema ist leider ein Beispiel in diese Richtung.

Persönlich verspüre ich eine Tendenz zu mehr lokaler Verwendung von Objekten. Da ich eher mit einem Streifen hantiere, gilt das für NeoPixel-Objekte bislang aber nicht.

combie:
Wenn du Mist baust, dann versagt das Programm nicht stumm (wie das im Eingangsposting), sondern der Kompiler haut es dir um die Ohren.

Er haut kräftig.

Danke für Deine ausführliche Erklärung, so habe zumindest ich was aus diesem Thema mitgenommen :slight_smile: