NeoPixel ohne delay

Hallo Kollegen,

ich bastel gerade an einem Projekt wo 6 PixelRinge eingesetzt werden sollen, doch zurallererst will ich mit einem Pixelring die Farben abbilden, die ich brauche.

Farben ändern über setPixelColor und delay ist super einfach, aber wenn ich später 6 Stück verwende dann will ich auf die delay funktion verzichten.

Mein Problem ist, dass der Code nur mit 3 Farben funktioniert und ich brauche 4.

Helft mir bitte Folgendes zu verstehen:

  • Warum funktioniert der Code nicht mit 2 und 4 Farben
  • Warum läuft der Code rückwärts ab. Rot, Grün, Blau. Ich bin nicht Farbenblind, glaubts mir.

Die Definition NEO_GRBW passt sonst werden die Farben verdreht angezeigt.

Verwendet wird ein Arduino Mega + Adafruit 2862

#include <Adafruit_NeoPixel.h>
#define PIN 6
#define NUM_LIGHTS  24

Adafruit_NeoPixel pixel = Adafruit_NeoPixel(NUM_LIGHTS, PIN, NEO_GRBW + NEO_KHZ800);



unsigned long previousMillis = 0;
unsigned long previousMillis2 = 0;
unsigned long previousMillis3 = 0;

unsigned long interval = 1000;



void setup() {
  pixel.begin();
  pixel.show(); // Initialize all pixels to 'off'
  pixel.setBrightness(10);
}

void loop() {

 
if (millis() - previousMillis >= interval) {
        previousMillis2 = millis();
for( int i = 0; i<NUM_LIGHTS; i++){
      
      
        pixel.setPixelColor(i, pixel.Color(0, 0, 255, 0));
        pixel.show();
    }
    }   
    


if (millis() - previousMillis2 >= interval) {
        previousMillis3 = millis();
    for( int i = 0; i<NUM_LIGHTS; i++){
      
      
        pixel.setPixelColor(i, pixel.Color(0, 255, 0, 0));
        pixel.show();
    }
    }   


if (millis() - previousMillis3 >= interval) {
        previousMillis = millis();
    for( int i = 0; i<NUM_LIGHTS; i++){
      
      
        pixel.setPixelColor(i, pixel.Color(255, 0, 0, 0));
        pixel.show();
    }
    }   





}

Hi

Ich verstehe kein Wort - WAS willst Du, WAS bekommst Du, WO denkst Du, ist der Fehler?

Neopixelring klingt nach WS2812B, Welche ich selber nur als RGB habe - Du benutzt RGBW - laut Sketch.
Hieße: Deine Pixel können auch ein natives Weiß ausgeben und mischen Dieses nicht aus R,G und B zusammen.
Ist Dem so?

MfG

Hallo Postmaster,

was ich brauche in wenigen worten:

PixelRing soll 4 Farben in folgender Reihenfolge anzeigen Blau dann Grün dann Rot dann Orange ohne delay Funktion.

Später wirds 6 PixelRinge geben, die unabhängig von einander diese Farben anzeigen.

Iststand:

Mehr als 3 Farben bringe ich nicht auf die Reihe. Die Farben im Code haben nicht die gewünschte Reihenfolge.

Gib bitte mal einen Link zu den Pixelringen, in RGBW habe ich die noch nicht gesehen.

Ich vermute mal das er diese hier meint --> NeoPixel Ring - 12 x 5050 RGBW LEDs w/ Integrated Drivers - Natural White - ~4500K

Kannte ich persönlich auch noch nicht.

Membuto:
Ich vermute mal das er diese hier meint --> NeoPixel Ring - 12 x 5050 RGBW LEDs w/ Integrated Drivers - Natural White - ~4500K

Kannte ich persönlich auch noch nicht.
NeoPixel Ring - 12 x 5050 RGBW LEDs w/ Integrated Drivers [Natural White - ~4500K] : ID 2852 : $9.50 : Adafruit Industries, Unique & fun DIY electronics and kits

Laut seinem Text ("Adafruit 2862") eher diesen hier.

Moko:
Laut seinem Text ("Adafruit 2862") eher diesen hier.

Verstehe ich jetzt nicht. In der Produktbeschreibung nennen sie:

The NeoPixel is 'split', one half is the RGB you know and love, the other half is a white LED with a yellow phosphor. Unlit, it resembles an egg yolk. Lit up these are insanely bright (like ow my eye hurts) and can be controlled with 8-bit PWM per channel (8 x 4 channels = 32-bit color overall). Great for adding lots of colorful + white dots to your project!

In den angehängten Doku nennen sie den WS2812 und den Sk6812 welche beide RGB mit integrierten Controller sind. Wo ist da die 4. LED weiß?

Grüße Uwe

Es gibt davon offensichtlich verschiedene, RGB und RGBW.

Hier ein Link auf die Dokumentation der RGBW Variante.

uwefed:
Verstehe ich jetzt nicht. In der Produktbeschreibung nennen sie:
In den angehängten Doku nennen sie den WS2812 und den Sk6812 welche beide RGB mit integrierten Controller sind. Wo ist da die 4. LED weiß?

Grüße Uwe

Schau Dir mal auf der Seite das 2. Bild an. Das sieht für mich aus, als wenn bei den LEDs auf 5 Uhr, die weissen LEDs leuchten. So lese ich das Jedenfalls aus der Beschreibung raus: eine "halbe" RGB-LED und eine "halbe" Weisse LED und der Controller spricht die entsprechenden an.

Hallo Kollegen,

das Thema RGB sollte hier nicht das Haptthema sein, aber hier ist der Beweis.

Dieser Code ergibt folgendes Bild:

#include <Adafruit_NeoPixel.h>

#define PIN 6 
#define NUMPIXELS 24 

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

void setup() 
{
  pixels.begin(); // Initialisierung der NeoPixel
  pixels.setBrightness(20);
}

void loop() 
{

  
pixels.setPixelColor(1, pixels.Color(255, 0, 0, 0)); 
pixels.show(); // Durchführen der Pixel-Ansteuerung

pixels.setPixelColor(2, pixels.Color(0, 0, 0, 0)); 
pixels.show(); // Durchführen der Pixel-Ansteuerung

pixels.setPixelColor(3, pixels.Color(0, 255, 0, 0)); 
pixels.show(); // Durchführen der Pixel-Ansteuerung

pixels.setPixelColor(4, pixels.Color(0, 0, 255, 0));
pixels.show(); // Durchführen der Pixel-Ansteuerung

pixels.setPixelColor(5, pixels.Color(0, 0, 0, 255));
pixels.show(); // Durchführen der Pixel-Ansteuerung

}

Ich habe einen dunklen Pixel an zweiter Stelle hinzugefügt, damit man sehen kann wie gezählt wird, von links nach rechts.

Google Photos

@ noiasca:

pixel.show () muss sein an jeder Stelle, denn show tut den Befehl davor einleiten.

Und jetzt zur Lösung meines Problems:

Ich habe heute mit einem Arbeitskollegen gesprochen, er programmiert in c sharp oder ähnlich. Er hat mir den entscheidenden Hinweis geliefert. Es ist schlecht mit mehreren Timern zu hantieren. Besser ist aus einem Timer wie millis() einen Taktgeber zu generieren und die Takte benutzen um bestimmte Vorgänge zu initiieren.

Gesagt, getan. Hier ist der Code mit einem Timer, der alle 1000ms die Variable um 1 erhöht, bis 5, die 5 wird wieder auf 0 zurückgesetzt. Jeder Variable 0 bis 4 wird eine Farbe zugeordnet.

Farben und Reihenfolge stimmen: dunkel, rot, grün, blau, weiß, dunkel, rot, grün, blau, weiß, …

Ich bin glücklich mit dem Code. Enfach, selbserklärend, einleuchtend.

#include <Adafruit_NeoPixel.h>
#define PIN 6
#define NUM_LIGHTS  24

Adafruit_NeoPixel strip = Adafruit_NeoPixel(NUM_LIGHTS, PIN, NEO_GRBW + NEO_KHZ800);



unsigned long previousMillis = 0;
unsigned long interval = 1000;
int takt = 0;

void setup() {
  strip.begin();
  strip.show(); // Initialize all pixels to 'off'
  strip.setBrightness(10);
}

void loop() {


  if (millis() - previousMillis >= interval) {
  takt =  takt + 1;
  previousMillis = millis();
  }

  if (takt == 5){
    takt = 0;
  }

  if (takt == 0) {
    strip.setPixelColor(0, strip.Color(0,0,0,0));
    strip.show();
  }
   
  if (takt == 1) {
    strip.setPixelColor(0, strip.Color(255,0,0,0));
    strip.show();
  }

  if (takt == 2) {
    strip.setPixelColor(0, strip.Color(0,255,0,0));
    strip.show();
  }

  if (takt == 3) {
    strip.setPixelColor(0, strip.Color(0,0,255,0));
    strip.show();
  }


  if (takt == 4) {
    strip.setPixelColor(0, strip.Color(0,0,0,255));
    strip.show();
  }



}

Hi

Schön, daß Es für Dich läuft und Danke des Feedback.

Trotzdem würde ich an Deinem Code ein/zwei Kleinigkeiten ändern.

  • das show() muß nicht in jedem IF-Zweig enthalten sein - EIN .show() nach allen IF-Zweigen würde reichen
  • die ganzen IF würde ich zu einer switch/case umbauen
  • weiter würde ich die Ansteuerung NUR ausführen, wenn sich auch was geändert hat.

In Deinem Code wird eine ganze Sekunde geprüft, ob die Wartezeit bereits um ist, um den 'Takt' zu erhöhen.
Egal, ob der Takt erhöht wurde, oder nicht - Du schreibst eine Farbe auf den Stripe (.setPixelColor() ) und lässt den ganzen Stripe danach 'rausschieben'.
Wofür?

An dem Aussehen des Stripe wird sich Nichts ändern, da genau die gleichen Farben gesetzt wurden, wie zuvor schon gesetzt waren.
Was Du durch Deinen Weg allerdings hast: Eine konstante Ausführungsgeschwindigkeit:

  • jedes Mal wird der Pixel gesetzt
  • jedes Mal werden alle Pixel in den Stripe geschoben

Bei einer 'nur wenn's nötig ist'-Lösung wäre die Ausführungszeit wesentlich länger, wenn Was geändert wurde (= die jetzige Ausführungszeit - ist ja der gleiche Ablauf, dem Stripe die Daten zu schicken) - nur in der Zeit, wo sich Nichts ändert, hättest Du Zeit im Überfluss.

Wenn's So aber für Dich läuft - lasse Es so!!
Du bekommst für kein gespartes Byte oder für keine gesparte µs auch nur ansatzweise Geld zurück.
Solange der µC nicht zwischendurch schlafen geht, ist der Stromverbrauch auch nur marginal anders.

MfG

Whandall:
Es gibt davon offensichtlich verschiedene, RGB und RGBW.

Hier ein Link auf die Dokumentation der RGBW Variante.

Danke für den Link. Kannte diese LED noch nicht.
Adafruit verlinkt bei dem genannten Produkt aber die RGB-Version der LEDs.

Grüße Uwe

DasNoobtier:

  • Warum läuft der Code rückwärts ab. Rot, Grün, Blau. Ich bin nicht Farbenblind, glaubts mir.

Bei strip.Color(R, G, B, W) sind die Farben wie mit den Buchstaben angedeutet definiert. Daher schaltet strip.Color(255, 0, 0, 0) die rote LED ein. Leider verwenden unterschiedliche Hersteller unterschiedliche Hardware, was mittels NEO_GRBW ausgeglichen wird.

DasNoobtier:
@ noiasca:

pixel.show () muss sein an jeder Stelle, denn show tut den Befehl davor einleiten.

Nö, damit werden die Daten eines internen Feldes mit den LED-Helligkeiten an den LED-Streifen übertragen. Man baut also erst das gewünschte Muster zusammen, um dann dieses Muster zusammen zu übertragen.

DasNoobtier:
Ich bin glücklich mit dem Code. Enfach, selbserklärend, einleuchtend.

Dann nutze ihn. Ich bin nicht so glücklich, daher habe ich ihn mit Ideen von postmaster-ino umgebaut. Das Ergebnis kannst Du ja mal Deinem Kollegen zeigen, was er dazu meint.

#include <Adafruit_NeoPixel.h>
#define PIN 6
#define NUM_LIGHTS  24

Adafruit_NeoPixel strip = Adafruit_NeoPixel(NUM_LIGHTS, PIN, NEO_GRBW + NEO_KHZ800);

unsigned long previousMillis = 0;
const unsigned long interval = 1000;
int takt = 0;

void setup() {
  strip.begin();
  strip.show(); // Initialize all pixels to 'off'
  strip.setBrightness(10);
}

void loop() {
  if (millis() - previousMillis >= interval) {
    previousMillis = millis();
    takt =  (takt + 1) % 5;
    switch (takt) {
      case 0:
        strip.setPixelColor(0, strip.Color(0, 0, 0, 0));
        break;
      case 1:
        strip.setPixelColor(0, strip.Color(255, 0, 0, 0));
        break;
      case 2:
        strip.setPixelColor(0, strip.Color(0, 255, 0, 0));
        break;
      case 3:
        strip.setPixelColor(0, strip.Color(0, 0, 255, 0));
        break;
      case 4:
        strip.setPixelColor(0, strip.Color(0, 0, 0, 255));
        break;
    }
    strip.show();
  }
}