ws2812B leuchtet nicht mit eigenem Programm

Hallo,

ich habe ein WS2812B Streifen.
Mein Vorhaben ist, eine 7 Segement Anzeige zu realisieren, und mit einem Taster Druck die Zahlen von 0-9 Hochzählen.

Ich habe bis dato mir diesen Code überleget leider leuchtet der Streifen nicht und ich weiß nicht wieso, für jeden tipp bin ich Dankbar.

#include "FastLED.h"


#define NUM_LEDS 63 // Wieviele LED hat dein Strip dafür die anzahl ändern (aktuell 60 eingestellt)

// Data pin that led data will be written out over
#define DATA_PIN 3 // Auf welchen pin der DI pin geklemmt wird


// This is an array of leds.  One item for each led in your strip.
CRGB leds[NUM_LEDS];

// Hier die Werte fuer den Interrupt einstellen
volatile unsigned long alteZeit=0, entprellZeit=20;
int zahlenmerker = 0;

void setup() {
	// sanity check delay - allows reprogramming if accidently blowing power w/leds
   	delay(2000);
       FastLED.addLeds<WS2812B, DATA_PIN, RGB>(leds, NUM_LEDS);
       pinMode(2, INPUT);       // Pin 2 ist INT0
       digitalWrite(2, HIGH);   // interner Pull up Widerstand auf 5V
       attachInterrupt(0, interruptRoutine, LOW);
}


void loop() {
}


// Ab hier die Funktionen fuer die einzelnen Zahlen
//void ledsloeschen(){
  for(int whiteLed = 0; whiteLed < NUM_LEDS; whiteLed = whiteLed + 1) {
    leds[whiteLed] = CRGB::Black;
  }
}

// Hier wird eine eins dargestellt. indem nur LED 10-20 und 40-60 eingeschaltet werden
void ledNR1() {
   for(int whiteLed = 10; whiteLed < 20; whiteLed = whiteLed + 1) {
      // Turn our current led on to white, then show the leds
      leds[whiteLed] = CRGB::White;

      // Show the leds (only one of which is set to white, from above)
      FastLED.show();
    }
    for(int whiteLed = 40; whiteLed < 60; whiteLed = whiteLed + 1) {
       // Turn our current led on to white, then show the leds
       leds[whiteLed] = CRGB::White;

       // Show the leds (only one of which is set to white, from above)
       FastLED.show();
     }
}

// Hier wird eine 2 dargestellt. indem nur LED 0-10 und 40-60 eingeschaltet werden
void ledNR2() {
   for(int whiteLed = 0; whiteLed < 10; whiteLed = whiteLed + 1) {
      // Turn our current led on to white, then show the leds
      leds[whiteLed] = CRGB::White;

      // Show the leds (only one of which is set to white, from above)
      FastLED.show();
    }
    for(int whiteLed = 20; whiteLed < 30; whiteLed = whiteLed + 1) {
       // Turn our current led on to white, then show the leds
       leds[whiteLed] = CRGB::White;

       // Show the leds (only one of which is set to white, from above)
       FastLED.show();
     }
     for(int whiteLed = 20; whiteLed < 30; whiteLed = whiteLed + 1) {
        // Turn our current led on to white, then show the leds
        leds[whiteLed] = CRGB::White;

        // Show the leds (only one of which is set to white, from above)
        FastLED.show();
      }
}


void interruptRoutine() {
  if((millis() - alteZeit) > entprellZeit) {
    // innerhalb der entprellZeit nichts machen
    ledsloeschen();
    zahlenmerker = zahlenmerker +1;
    if (zahlenmerker >2){
      zahlenmerker = 1;
    }
   switch (zahlenmerker)
      {
        case '1':
          ledNR1();
          zahlenmerker = 1;
          break;
        case '2':
          ledNR2();
          zahlenmerker = 2;
          break;


      }

    alteZeit = millis(); // letzte Schaltzeit merken
  }
}

Ach ja sorry für den Doppelpost im normalen Programmier Forum den werde ich löschen sobald die Zeit sperre aufgehoben ist

Ich kann mir nicht vorstellen, dass der Kode so gemeint ist:

   switch (zahlenmerker)
      {
        case '1':
          ledNR1();
          zahlenmerker = 1;
          break;
        case '2':
          ledNR2();
          zahlenmerker = 2;
          break;
      }

Ich würde nicht einmal ein FastLED.show(); innerhalb einer ISR aufrufen, geschweige denn 30.

Ich würde nicht nach dem Ändern jeder LED FastLED.show(); aufrufen, sondern erst nach dem Setzen aller.

Ich vermisse das Löschen der alten LEDs wenn neue Zahlen angezeigt werden sollen.

NRF2 schreibt ein Segment doppelt.

    for(int whiteLed = 20; whiteLed < 30; whiteLed = whiteLed + 1) {
       // Turn our current led on to white, then show the leds
       leds[whiteLed] = CRGB::White;

       // Show the leds (only one of which is set to white, from above)
       FastLED.show();
     }
     for(int whiteLed = 20; whiteLed < 30; whiteLed = whiteLed + 1) {
        // Turn our current led on to white, then show the leds
        leds[whiteLed] = CRGB::White;

        // Show the leds (only one of which is set to white, from above)
        FastLED.show();
      }

Löschen kannst du deinen Array einfacher mitmemset(leds, 0, sizeof(CRGB) * NUM_LEDS);
memset

jetzt stehe ich komplett auf dem Schlauch.

was meinst du?

Ich bin ein echter anfänger sorry wenn ich so doof frage

Na dann hast du noch etwas zu lernen, z.B. https://www.gammon.com.au/interrupts.

Eine ISR = Interrupt Service Routine sollte so schnell wie möglich sein,
30 mal FastLED.show(); aufzurufen erfüllt die Bedingung sicher nicht.

Den Rest kann ich eigentlich nicht viel deutlicher schreiben.

zahlenmerker wird in deinem switch mit dem Wert überschrieben den es schon hat, warum?

Warum willst du jede LED einzeln angehen sehen?

Hi,

jop da hast du Recht das ich da noch eine ganze menge lernen muss. Ich habe nur ein Problem lesen und verstehen... und dann noch Englisch hilfe...!

Naja nun zu deinen Fragen,

Ich habe es so geschrieben weil ich dachte das ist logisch, nach dem ich mit IF und else versucht habe und dann bin ich irgendwann mal auf diese idee gekommen.

Bestimmt nicht sauber... Ich weiß aber deswegen frage ich ja auch hier.

Zahlenmerker wie der Name es schon sagt es soll sich merken bei welcher Zahl er gerade ist und dann eine Hochzählen.

Aber anscheind bin ich da ganz schön auf dem Holz weg schade.

ludino:
ich habe ein WS2812B Streifen.
Mein Vorhaben ist, eine 7 Segement Anzeige zu realisieren, und mit einem Taster Druck die Zahlen von 0-9 Hochzählen.

Funktioniert ein Testprogramm?

Wie ist die Zuordnung der LEDs zu den Segmenten?

Ja ein Testprogramm läuft.

Ich hoffe du meinst das

Oben ist a und die ersten 7 LED und das geht dann im Uhrzeigersinn weiter. Der mittlere ist g.

Gruss

ludino:
Ja ein Testprogramm läuft.

Ich hoffe du meinst das

Ja, meine ich. Die grundsätzliche Funktion ist gegeben, gut.

ludino:
Oben ist a und die ersten 7 LED …

Du hast 63 LEDs definiert, also 63/7=9 das paßt mit den “7 LED” nicht zusammen. Bei 9 würde ich zustimmen. Dazu paßt dann aber die Schleife nicht, da sind es zehn (10 bis 19):

for(int whiteLed = 10; whiteLed < 20; whiteLed = whiteLed + 1) {

Verstehst Du meine Irritation? Was stimmt, 7, 9 oder 10?

Hallo,

ja, ich verstehe deine Irritation, die Schleife war erst mal nur zum test ob es Überhaupt leuchtet, deswegen auch nur LEDnr1 und LEDnr2.

Ich wollte es erst mal soweit haben das es mit den 2 Zahlen "funktioniert" sprich bei lednr1 sollen die LED 10-20 und 40-60 Leuchten.

Das Feintunning wollte ich zum schluss machen.

Gruß

Luigi

Liefert Dein Nezteil genügend Strom. Jede LED braucht 60mA.
Grüße Uwe

ludino:
Das Feintunning wollte ich zum schluss machen.

Hallo Luigi,
da ich die Anordnung der LEDs immer noch nicht kenne und auch keine 63 WS2812b zum Testen habe, hier ein ausbaufähiges Programm, das anstelle der Segmente einzelne LEDs (Lichtpunkte) einschaltet:

#include "FastLED.h"
#define TASTEN_PIN 2
#define NUM_LEDS 63     // Wieviele LED hat dein Strip dafür die anzahl ändern (aktuell 60 eingestellt)
#define DATA_PIN 3      // Auf welchen pin der DI pin geklemmt wird
#define BRIGHTNESS  50
CRGB leds[NUM_LEDS];    // This is an array of leds.  One item for each led in your strip.
bool altTaste, aktTaste;
const uint32_t entprellZeit = 30;
uint32_t alteZeit;
byte zahlenmerker = 0;

void setup() {
  Serial.begin(9600);
  Serial.println("Anfang");
  Serial.println(zahlenmerker);
  FastLED.addLeds<WS2812B, DATA_PIN, RGB>(leds, NUM_LEDS);
  FastLED.setBrightness(BRIGHTNESS);
  pinMode(TASTEN_PIN, INPUT_PULLUP);
  ledsloeschen();
  ledNR0();
  FastLED.show();
}

void loop() {
  if ((millis() - alteZeit) >= entprellZeit) {    // innerhalb der entprellZeit nichts machen
    alteZeit = millis(); // letzte Schaltzeit merken
    altTaste = aktTaste;
    aktTaste = digitalRead(TASTEN_PIN);
    if (!altTaste && aktTaste) {
      ledsloeschen();
      if (++zahlenmerker > 2) {
        zahlenmerker = 0;
      }
      switch (zahlenmerker)
      {
        case 0:
          ledNR0();
          break;
        case 1:
          ledNR1();
          break;
        case 2:
          ledNR2();
          break;
      }
      Serial.println(zahlenmerker);
      FastLED.show();
    }
  }
}

// Ab hier die Funktionen
void ledsloeschen() {
  for (byte blackLed = 0; blackLed < NUM_LEDS; blackLed++) {
    leds[blackLed] = CRGB::Black;
  }
}

void ledNR0() {
  leds[0] = CRGB::White;
}
void ledNR1() {
  leds[1] = CRGB::White;
}
void ledNR2() {
  leds[2] = CRGB::White;
}

Hallo

@ Uwe, ja ist ein Labornetzteil mit 7A sollte reichen,

@ agmue du bist spitze…! Läuft so wie ich es haben wollte… Riesen Dank.

Jetzt habe ich auch verstanden was du mit der Anordnung meinst dazu Mal ein Foto.

Mal eine Frage kann man da ein Poti oder Drehschalter mit integrieren um Farben zu wechseln? Möchte erst Mal nur ja oder nein wissen vielleicht komme ich ja selber auf die Lösung will ja lernen

Aber riesen Dank noch Mal!

P.s. ja ich weiß ich muss bei 0 anfangen zu zählen

ludino:
Mal eine Frage kann man da ein Poti oder Drehschalter mit integrieren um Farben zu wechseln? Möchte erst Mal nur ja oder nein wissen vielleicht komme ich ja selber auf die Lösung will ja lernen

Ja, auch Drehencoder.

ludino:
P.s. ja ich weiß ich muss bei 0 anfangen zu zählen

Jetzt verstehen wir uns!

ludino:
Aber riesen Dank noch Mal!

Bitte gerne :slight_smile:

Hi,

mir ist gerade noch so eine Idee gekommen,

Kann ich die leds nicht Gruppieren?

und dann nur noch die gruppen aufrufen?

Das müßte doch mit einer Funktion funktionieren oder?

ludino:
@ Uwe, ja ist ein Labornetzteil mit 7A sollte reichen,

Ja recht. 63 WS2812 brauchen ca 3,7A.

Hast Du einen 330 Ohm WIderstanz zwischen Arduino und Din geschaltet? Wenn nicht dann mach das sofort.

Grüße Uwe

ludino:
Kann ich die leds nicht Gruppieren?

und dann nur noch die gruppen aufrufen?

Das müßte doch mit einer Funktion funktionieren oder?

Das funktioniert mit einer Funktion, wobei mir mehrere Möglichkeiten der Realisierung einfallen.

Die "1" könntest Du beispielsweise als Bitmuster B00000110 speichern mit den Segmenten g bis a. Wenn Du die Bitmuster in ein Feld ablegst, kannst Du mit der Zahl als Index darauf zugreifen. Wenn Du dann den Wert jedes Bits mit 9 multiplizierst, hast Du die Adresse der ersten LED der Gruppe. Bei dieser Adresse beginnend schaltest Du die folgenden 9 LEDs an.

Hier ein Lösungsvorschlag für Hex Werte von 0 bis 0xF.

Das Ausdrucken nimmt den meisten Platz ein.

#include <FastLED.h>

CRGB leds[63];

byte segmentKodes[16] { // gfedcba format
  0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x07,
  0x7F, 0x6F, 0x77, 0x7C, 0x39, 0x5E, 0x79, 0x71,
};

void codeToLeds(byte val, CRGB foreground, CRGB background) {
  val &= 0xF;
  for (byte curr = 0, seg = 0, mask = 0x01; seg < 7; seg++, mask <<= 1) {
    bool an = segmentKodes[val] & mask;
    for (byte sLed = 0; sLed < 9; sLed++) {
      leds[curr++] = an ? foreground : background;
    }
  }
}

void setup() {
  Serial.begin(250000);
  codeToLeds(2, CRGB::White, CRGB::Black);
  printLeds();
}

void loop() {}

void printLed(byte index) {
  if (leds[index] == CRGB(0)) {
    Serial.write('-');
  } else if (leds[index] == CRGB(0xFFFFFF)) {
    Serial.write('*');
  } else {
    Serial.write('?');
  }
}

void printQuer(byte startIndex) {
  Serial.write(' ');
  for (byte idx = 0; idx < 9; idx++) {
    printLed(startIndex + idx);
  }
  Serial.println();
}

void printLaengs(byte startIndex1, byte startIndex2) {
  for (byte idx = 0; idx < 9; idx++) {
    printLed(startIndex1 + idx);
    Serial.print(F("         "));
    printLed(startIndex2 + idx);
    Serial.println();
  }
}

void printLeds() {
  printQuer(0);
  printLaengs(45, 9);
  printQuer(54);
  printLaengs(36, 18);
  printQuer(27);
}
 *********
-         *
-         *
-         *
-         *
-         *
-         *
-         *
-         *
-         *
 *********
*         -
*         -
*         -
*         -
*         -
*         -
*         -
*         -
*         -
 *********

Hallo

Danke dir Uwe, hatte schon ein 510 Ohm dazwischen geschaltet, den hatte ich gerade zur Hand.

Gruss

Luigi

Hi,

danke euch beiden für die lösungs hilfe/ vorschläge gerade erst gesehen.

Ich werde es Später mal testen und Mal schauen ob ich es verstehe.

Danke Euch

Klasse Menschen und Super Forum

Wenn Du so weitermachst werden wir noch rot. :wink: :wink: :wink:
Grüße Uwe