DMX und adressierbare LED arbeiten nur bis DMX-Kanal 50

Hallo,
für ein kleines Theaterprojekt steht die Aufgabe einen LED-Strip mit DMX anzusteuern.
Das funktioniert auch - aber nur bei DMX-Kanal 1-50.
Bei Kanal 51- 512 geben die LED keinen Blinker von sich.
Versucht habe ich es mit Nano, UNO R3, MEGA2560, Verwendung unterschiedlicher PIN...- überall das gleiche Ergebnis.
Ich habe unterschiedliche handelsübliche Low-Cost-Controller sowie USB zu DMX über FX5-Interface ausprobiert.
Das DMX- Eingangssignal am Arduino kommt über ein 485MAX-Board. Die Schaltung analog dieser:

(Geändert ist hier lediglich die Spannungsversorgung (auf extern) und die Datenleitung auf PIN 2, die beiden LED entfallen.)

Der Programmcode:

#include <FastLED.h>
#include <DMXSerial.h>

#define NUM_LEDS 44
#define LED_PIN   2


CRGB leds[NUM_LEDS];
int i=0;
int   Startadresse =0;

void setup() {
  
  FastLED.addLeds<WS2812B, LED_PIN, GRB>(leds, NUM_LEDS);
  FastLED.setBrightness(150);
  DMXSerial.init(DMXReceiver);   
}

void loop () {

  while (DMXSerial.read(Startadresse)<=80)
  {
  FastLED.clear(true);
  }

  while ((DMXSerial.read(Startadresse)>=80) && (DMXSerial.read(Startadresse)<=160))
    {
    averlauf();
     FastLED.show(); 
     delay(85);
  }
 FastLED.clear(true);

      while ((DMXSerial.read(Startadresse)>=161))
    {
    bverlauf();
     FastLED.show(); 
     delay(85);
  }
   FastLED.clear(true);
  }
 
void averlauf() 
{  
    uint16_t beatA = beatsin16(30, 0, 255);
    uint16_t beatB = beatsin16(20, 0, 255);
    fill_rainbow(leds, 15, (beatA+beatB)/2,12);
} 

void bverlauf() 
{  
    uint16_t beatA = beatsin16(30, 0, 255);
    uint16_t beatB = beatsin16(20, 0, 255);
    fill_rainbow(leds+15, 29, (beatA+beatB)/2,12);   
} 

Wer kann mir hier weiterhelfen?
Schon jetzt ein großes Dankeschön
Schorsch

In der Bibliothek in DMXSerial.h finde ich

#define DMXPROBE_RECV_MAX 50 // standard maximum of waiting for a DMX packet in DMXPROBE mode.

Unterbindet zeitweise Interrupts.

Benötigt Interrupts.

Das kann schon zu seltsamen Effekten führen.

Das sind MilliSekunden.
(ein Grund für meine Zeittypen und gegen Defines)

Bei genauerer Betrachtung ...

@schorsch123
wäre günstig wenn du die verwendete Library verlinkst -

im Beispielsketch für den DMX Receiver sind keine delays.
Du hast delays in deinem Sketch.
Die würde ich mal entfernen beginnen.

Wenn du einen Mega hast, nimm mal den Mega, ändere die DMX Schnittstelle auf einen anderen Serial und kontrolliere ob dein DMX Sender die Daten für > 50 überhaupt so schickt dass du diese auch am Arduino empfangen kannst.
Erst wenn das bestätigt ist - machst mit den Neopixel weiter.

Wenn bestätigt ist, dass mehr als 50 ankommen und verarbeitet werden können, lies mal in der Library nach was es mit diesem Versions-Hinweis auf sich hat:

03.09.2017 New DMX mode that pauses DMX receiving for some time. Example for controlling NeoPixel and WS2811.

da wirds doch sicher ein Beispiel dazu geben.

ach, es wäre so schön einfach gewesen...
Trotzdem ein großes Dankeschön

Danke für Deine Antwort.

Die delays sind erforderlich - sonst bleiben die LED dunkel. Allerdings sehe ich darin keine so richtige Logik. Aber ändere nie ein System. das läuft :wink:

Das Beispiel in der Bibliothek hilft mir auch nicht wirklich.

Den nachfolgenden Sketch habe ich schon häufig bei Ansteuerung von Servos, normalen LED, Relais... über alle DMX-Kanäle verwendet und wollte ihn mit den WS2812 modifiziert verwenden. Hier mit einer einfachen LED - funktioniert problemlos (Schaltplan wie im oben angegebenen Plan):

#include <DMXSerial.h>
const int Led1Pin =  6;
  int start=512;

void setup () {
  DMXSerial.init(DMXReceiver);
  pinMode(Led1Pin, OUTPUT); // Pin von der ersten LED als Ausgang definieren
}

void loop() {
  analogWrite(Led1Pin, DMXSerial.read(start)); 
}

Es kann also nur irgendwo an dem Zusammenspiel der beiden verwendeten Bibliotheken liegen.
Nun sind für mich Interrupts usw. (noch immer) böhmische Dörfer und ich bin von externer Hilfe abhängig...
Schon jetzt ein Dankeschön.

Es wird einen Grund geben, warum es das Beispiel DmxSerialNeoPixels.ino mit eigener Ansteuerung der WS2812 gibt.

Man kann das auch mit einer Statemaschiene und millis() ohne delay machen.

Die bleiben dunkel, weil du eine while Schleife in der loop hast. Auch das ist ganz großer Müll. Auch hier die Lösung: Statemaschiene und millis()

Du könntest dich kundig machen.

Sind Dir Programmiersprachen wie Algol60, Fortran, Pascal ein Begriff? Und das nur im Bereich von "Büroarbeiten". Das war vor ca. 30 Jahren - seitdem keine Programmierung mehr angefasst. Und meine Kenntnisse der Mikroelektronik beschränkten sich ohnehin auf R=U/I.

Bis ich vor zwei Jahren für mein kleines Amateurtheater ein paar Steuerungen brauchte...
Seit dem beschäftige ich sporadisch mit diesem Kram.

Ein wenig hast Du mich nun an meiner Ehre gekratzt ("...ganz großer Müll...").
Na, dann machst Du es einfach mal - geht sowieso nicht - delay und millis ist doch fast das selbe...

Dumm gelaufen für mich - jetzt läuft's!!! :

Und die Einschaltverzögerung (1-2 sec)- die mich für zumindest dieses Projekt nicht gestört hat, ist auch kein Thema mehr.

Hier der aktuelle Code (ja, auch Kanal 512 läuft!):

#include <DMXSerial.h>
#include <FastLED.h>

#define NUM_LEDS 44
#define LED_PIN 6


CRGB leds[NUM_LEDS];

int Startadresse = 512;
unsigned long vorherigMillis = 0;
const long interval = 50;

void setup() {

  FastLED.addLeds<WS2812B, LED_PIN, GRB>(leds, NUM_LEDS);
  FastLED.setBrightness(150);
  DMXSerial.init(DMXReceiver);
}

void loop() {

  unsigned long aktuellMillis = millis();

  if (aktuellMillis - vorherigMillis >= interval) {
    vorherigMillis = aktuellMillis;

    if (DMXSerial.read(Startadresse) <= 80) {
      FastLED.clear(true);
    }

    if ((DMXSerial.read(Startadresse) >= 80) && (DMXSerial.read(Startadresse) <= 160)) {

      averlauf();
      FastLED.show();
    }

    if ((DMXSerial.read(Startadresse) >= 161)) {
      bverlauf();
      FastLED.show();
    }
  }
   
}

void averlauf() {
  uint16_t beatA = beatsin16(30, 0, 255);
  uint16_t beatB = beatsin16(20, 0, 255);
  fill_rainbow(leds, 15, (beatA + beatB) / 2, 12);
  fill_solid(leds + 15,29,CRGB::Black);
}

void bverlauf() {
  uint16_t beatA = beatsin16(30, 0, 255);
  uint16_t beatB = beatsin16(20, 0, 255);
  fill_rainbow(leds + 15, 29, (beatA + beatB) / 2, 12);
  fill_solid(leds ,15,CRGB::Black);
}

@Kombi: Schön wäre es, wenn Du für mich einen Hinweis hättest, wo man einen verständlichen Einstieg zu dem Thema finden könnte - warum es nun läuft - wirklich verstanden hab ich es nicht.
Liegt das an der Länge des gewählten Interwalls? (bei bspw. 25 gibt es nur ein unkontrolliertes Blinken)

Euch ein großes Dankeschön und darauf einen Bölkstoff
Schorsch

Naja...
Das ist hier schon eine etwas andere Baustelle.

Nein!
Mit millis() kann man recht einfach Nebenläufigkeiten bauen.
Das wird eher schwierig mit delay(), es sei denn man verwendet eins der Multitasking oder Dual Core Systeme.

Interrupts?
Das fängt bei Wikipedia an, geht über die Libc Doku zu deinem Kompiler und führt zudem über das Datenblatt/Spezifikation der Komponenten, z.B. hier DMX, ATMega328P, WS2812

Mit dem Wissen gefüllt, ist es ein leichtes zu erkennen, wo sich die Probleme, für diesen konkreten Einzelfall, auf tun.

Auch das findet auf dem Wege Aufklärung.

Schön das du die Lösung gefunden hast. Und das ist wirklich was ganz anderes wie while mit delay. Frage: Hast du der Unterschied auch verstanden? Oder nur kopiert?

Ja, der Unterschied war mir bekannt, delay aber geläufiger. Und es lief ja auch - nur aber bis DMX-Kanal 50. Und daran habe ich mich festgebissen.
Nun - mit millis - funktioniert es komplett wie gewünscht.
Kopiert? wenn ich das irgendwo gefunden hätte (und ich suche viel), wäre es nicht nicht hier gelandet.
Kapiert? - naja, im großen Ganzen schon - nur warum Kanal 50, warum die Intervallgröße. (Letztere habe ich durch Probieren gefunden. )
So tun sich mit einer geklärten Frage zwei neue auf - die werde ich auch noch rausfinden - sicher Thema Interrupt. Und wenn ich absolut nicht weiterkomme finde ich sicher auch wieder hier Hilfe...
Bis dann