WS2812B LEDs über Nano 33 IoT ansteuern

Moin moin!

ich möchte ein Uhrprojekt von einem Nano-Clon auf einen Nano 33 IoT umstellen und habe Probleme beim Ansteuern der richtigen LEDs.

Den gesamten LED-Aufbau habe ich mit einem einfachen Code auf dem nano 33 getestet.

In meinem Uhrprogramm hole ich aus der Epoch-Zeit die aktuelle Zeit hier in Deutschland (mit Sommer-Winterzeit vergleich etc.)
Mir scheint etwas die Übertragung zu zerstören. Der Aufbau ist in etwa dieser:

Hier mal eben die relevanten Ausschnitte aus dem Code

void setup() {
  delay(3000); // Sicherheits Delay
  Serial.begin(115200);

  // Start Real Time Clock
  rtc.begin();

  // Variable for number of tries to NTP service
  int numberOfTries = 0, maxTries = 6;

  // Get epoch
  do {
    epoch = WiFi.getTime();
    numberOfTries++;
  }

  while ((epoch == 0) && (numberOfTries < maxTries));

  if (numberOfTries == maxTries) {
    Serial.print("NTP unreachable!!");
    while (1);
  }

  else {
    Serial.print("Epoch received: ");
    Serial.println(epoch);
    rtc.setEpoch(epoch);
    Serial.println();
  }

  //LEDs werden eingefügt + Farbkorrektur und Farbtemperatur auf Wolfram (warmweiß)
  FastLED.addLeds<LED_TYPE, DATA_PIN, COLOR_ORDER>(leds, NUM_LEDS).setCorrection(TypicalPixelString);
  FastLED.setTemperature( Tungsten40W );
  Serial.println("Starte Wordclock ...");
}


void loop() {
// Am Anfang jeder Stunde soll die Uhrzeit abgeglichen werden
    if (Minute<1) {
    epoch = WiFi.getTime();
    rtc.setEpoch(epoch);
    }
  int year=rtc.getYear();
  byte hour=rtc.getHours();
  byte day=rtc.getDay();
  byte month=rtc.getMonth();
  byte tzHours=1;

  if (summertime_RAMsave(year, month, day, hour, tzHours))
    GMT=2;
    else GMT=1;
  
  Minute =  rtc.getMinutes();
  int Std = rtc.getHours() + GMT;
  if (Std > 12)
    Stunde = Std - 12;
  else if (Std == 0)
    Stunde = 12;
  else
    Stunde = Std;
  printTime(); //Serial Uhrzeit printer
  displaytime(); //Ansteuerung der einzelnen LEDs

FastLED.delay(500);
}

Hier die Funktionsweise der displaytime():

void displaytime(void) {
  //Rücksetzen aller LEDs
  fill_solid( leds, NUM_LEDS, CHSV(0, 0, 0));

  // Nun suchen wir die richtigen LEDs und übergeben sie an die Funktion zum Anschalten
  SwitchLED(Es, (sizeof(Es) / 2));
  SwitchLED(Ist, (sizeof(Ist) / 2));

hier die Definition der Worte und allgemeinen FastLED sachen:

FASTLED_USING_NAMESPACE
#define DATA_PIN    3
#define LED_TYPE    WS2812B
#define COLOR_ORDER GRB
#define NUM_LEDS    114      // Gesamtanzahl der WS2812 LEDs
CRGB leds[NUM_LEDS];

int Es[]        = {0, 1};
int Ist[]       = {3, 4, 5};

wobei die SwitchLED() in Auszügen so aussieht:

void SwitchLED(int MyArray[], int n) {
  //Funktion zum Anschalten der LEDs in warmweiß (oder gewünschter Farbe)
  for (i = MyArray[0]; i < MyArray[0] + n; i++) {
    FastLED.setBrightness(BRIGHTNESS);
    leds[i].setRGB(255, 255, 255);             
  }
}

Das ganze funktioniert auf einem normalen Nano einwandfrei, aber aus irgendeinem Grund scheint das Signal nicht richtig anzukommen.
Beim LED-Test habe ich jede LED einzeln hintereinander anschalten lassen, das hat aber irgendwie Funktioniert?

Ich weiß leider nicht wonach ich suchen soll, vielleicht kann mir ja jemand von euch helfen!

Vielen lieben Dank vorab

Warum funktioniert denn dieser Code problemlos?:

type #include <FastLED.h>

int i = 0;
FASTLED_USING_NAMESPACE
#define DATA_PIN    3
#define LED_TYPE    WS2812B
#define COLOR_ORDER GRB
#define NUM_LEDS    114      // Gesamtanzahl der WS2812 LEDs
CRGB leds[NUM_LEDS];


void setup() {
  FastLED.addLeds<LED_TYPE, DATA_PIN, COLOR_ORDER>(leds, NUM_LEDS).setCorrection(TypicalPixelString);
}

void loop() {
  for (i = 0; i < 115; i++) {
    leds[i].setRGB(255, 255, 255);
    FastLED.show();
    delay(100);
  }
}

Mit den Serial prints habe ich auch die Case- struktur in der displaytime() kontrolliert, das funktioniert soweit.

Es scheint als würden einfach nicht die richtigen Daten übertragen werden, es leuchten zu viele LEDs und zum Beispiel auch die LED mit der nummer 2, die aber nie an sein sollte....

Hallo,
d.h der Unterschied zwischen Nano und Nano33IoT ist der Levelschifter ? Eventuell ist der nicht schnell genug.
Wenn Du eine einzelne LED aus dem Streifen hast , dann betreibe die mal nur diese erste über eine Diode mit 5V . D_Out dieser ersten verbindest Du mit D_in der übrigen. So nutzt Du eigentlich die erste LED als Pegelwandler.
Heinz

Auch ich bin beim Levelschifter, der vermutlich für I²C aber nicht WS2812b geeignet ist.

Verbinde mal DIN vom ersten WS2812b über einen Widerstand 1 - 10 kΩ mit +5V.

Wird es besser?

Ich verstehe jetzt nicht, warum du mit dieser Frage einen 3. Thread öffnest.
Das Problem wurde dir doch schon in den beiden anderen Threads gepostet.
Der I2C-Levelshifter ist nicht für alle Schaltungen geeignet.
Andere Beispiele wurden dir doch auch schon genannt.

Weil ich noch nicht verstanden habe, warum der in #2 beschriebene code problemlos die richtigen LEDs anspricht, während der andere es nicht hinkriegt. Ich müsste doch wenn es an dem levelshifter liegt das selbe Problem bekommen, dass er zu viele LEDs gleichzeitig anspricht, statt der gewünschten, oder nicht?
Für mich war es dann hier jetzt naheliegender, dass der code fehlerhaft sein könnte.

8-Bit auf 32-Bit ALU, manche Datentypen ändern ihre Bitzahl.

Meist, so meine Erfahrung, verbirgt sich der Fehler in dem nicht gezeigten Programmteil.

Ich leider auch nicht. Deine Problembeschreibung ist auch viel zu ungenau. Ich habe schon alle möglichen Fehlerbilder mit WS2812b gesehen, kann die aber mangels Beschreibung nicht abgleichen.

Ich habe keinen Nano 33 IoT, dessen spezielle Eigenschaften kenne ich daher nicht, weshalb ich mich in diesem Thema eher zurückhalte. Wenn Du mir aber ein kompilierbares Programm anbietest, könnte ich das mit 144 WS2815 Pixeln an einem ESP32 dran, der auch eine 32-Bit-ALU hat, ausprobieren. Möglicherweise ergibt sich dadurch eine Erkenntnis.

int Es[]        = {0, 1};
...
  SwitchLED(Es, (sizeof(Es) / 2));

Auf einem 32-Bit µC ist int 4 Byte lang.

  SwitchLED(Es, (sizeof(Es) / sizeof(Es[0])));  // paßt immer
  SwitchLED(Es, (sizeof(Es) / sizeof(int);      // mal probieren

Besser fände ich bei weniger als 256 Pixeln:

uint8_t Es[]        = {0, 1};
...
  SwitchLED(Es, (sizeof(Es)));

bei mehr als 256 Pixeln:

uint16_t Es[]        = {0, 1};
...
  SwitchLED(Es, (sizeof(Es) / 2));              // paßt jetzt wieder
  SwitchLED(Es, (sizeof(Es) / sizeof(Es[0])));  // paßt immer
1 Like

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.