NeoMatrix betreiben/programmieren

Hallo,

ich habe vor ein Projekt zu bauen bei dem ich die hier verwende.

vom Programmieren habe ich gerade einmal die Grundlagen drauf, wenn überhaupt.
Mit Bibiliotheken habe ich noch gar keine Erfahrung ( ich weiß was es ist und wofür man es nutzt), mehr aber auch nicht.

Meine Frage welche Bibiliothek brauche ich und wie bzw wo lerne ich am schnellsten welche wichtigen befehle es gibt.

ich habe einen Meter apa102 (144LED`s) hier liegen (werde sie auf 64 kürzen!?) kann ich die genauso oder zumindest ähnlich programmieren wie die ws2812 auf der Matrix ?

Ich freue mich über Tipps und Ideen. :slight_smile:

Gruß Florian

FastLED geht ganz gut.

Da sind viele Beispiele dabei, z.B. FastLED/examples/NoisePlusPalette/NoisePlusPalette.ino at master · FastLED/FastLED · GitHub um sich mal gundsätzlich das x/y Mapping für eine Matrix anzusehen.

Doku? Siehe hier meine Antwort #37.

ich habe einen Meter apa102 (144LED`s) hier liegen (werde sie auf 64 kürzen!?) kann ich die genauso oder zumindest ähnlich programmieren wie die ws2812 auf der Matrix ?

Ja. Einfach im Setup den passenden Controller eintragen.

Grüße,

Helmuth

N-E-M-A-N:
werde sie auf 64 kürzen!?

Das ist zunächst zum Probieren nicht nötig, wenn Du 64 definierst, werden auch nur die ersten 64 genutzt.

Ok die Bibiliothek wird ich mir mal anschauen, das Problem ist das mein Englisch nicht so sonderlich gut (reicht über Grundkenntnisse nicht hinaus) ist daher ist es immer schwierig von englischen Quellen zu lernen, wenn jemand also eine Deutsche quelle hätte wäre das super. :slight_smile:

Wie wird das ganze an den Arduino angeschlossen ? es sind 4 Leitungen, GND und 5V sind klar dann D an einen DigitalPin aber C !?

Die LED brauchen bis zu 60mA pro Stück. Bei 64 sind das schon fast 4A. Du brauchst auf alle Fälle ein 5V 4A Netzteil für die LED.
Grüße Uwe

also ein bisschen was habe ich jetzt verstanden..

#include <FastLED.h>
    #define NUM_LEDS 30
    #define DATA_PIN 6
    #define CLOCK_PIN 7

    CRGB leds[NUM_LEDS];

void setup() { 
      FastLED.addLeds<APA102, DATA_PIN, CLOCK_PIN>(leds, NUM_LEDS);
    }

void loop() { 
  for(int dot0 = 0; dot0 < NUM_LEDS; dot0++)
  {
        leds[dot0] = CRGB::Red; 
        FastLED.show();
        delay(50);
        leds[dot0] = CRGB::Black;
        delay(50);
  }
}

aber wie kann ich jetzt eine folge von mehreren unterschiedlich farbigen punkten entlang laufen lassen ?

wenn ich den

for(int dot1 = 1; dot1 < NUM_LEDS; dot1++)

befehl für die anderen übernehme z.b. eben mit dot1 dann bewegt sich der 2. ja erst eine led weiter wenn der 1. einmal bis zum ende gewandert ist ..

so würde es natührlich gehen.. aber das geht doch sicherlich auch einfacher ?!

#include <FastLED.h>
    #define NUM_LEDS 141
    #define DATA_PIN 6
    #define CLOCK_PIN 7
    #define x 100
    CRGB leds[NUM_LEDS];

void setup() {
  FastLED.addLeds<APA102, DATA_PIN, CLOCK_PIN>(leds, NUM_LEDS);
}

void loop() {
            leds[0] = CRGB::Red;
            leds[1] = CRGB::Yellow;
            leds[2] = CRGB::Green;
            leds[3] = CRGB::Blue;
            leds[4] = CRGB::Purple;
            FastLED.show(10);
            delay(x);
            leds[0] = CRGB::Black;
            leds[1] = CRGB::Red;
            leds[2] = CRGB::Yellow;
            leds[3] = CRGB::Green;
            leds[4] = CRGB::Blue;
            leds[5] = CRGB::Purple;
            FastLED.show(10);
            delay(x);
            leds[0] = CRGB::Black;
            leds[1] = CRGB::Black;
            leds[2] = CRGB::Red;
            leds[3] = CRGB::Yellow;
            leds[4] = CRGB::Green;
            leds[5] = CRGB::Blue;
            leds[6] = CRGB::Purple;
            FastLED.show(10);
            delay(x);
            leds[0] = CRGB::Black;
            leds[1] = CRGB::Black;
            leds[2] = CRGB::Black;
            leds[3] = CRGB::Red;
            leds[4] = CRGB::Yellow;
            leds[5] = CRGB::Green;
            leds[6] = CRGB::Blue;
            leds[7] = CRGB::Purple;
            FastLED.show(10);
            delay(x);
            leds[0] = CRGB::Black;
            leds[1] = CRGB::Black;
            leds[2] = CRGB::Black;
            leds[3] = CRGB::Black;
            leds[4] = CRGB::Red;
            leds[5] = CRGB::Yellow;
            leds[6] = CRGB::Green;
            leds[7] = CRGB::Blue;
            leds[8] = CRGB::Purple;
            FastLED.show(10);
            delay(x);
            leds[0] = CRGB::Black;
            leds[1] = CRGB::Black;
            leds[2] = CRGB::Black;
            leds[3] = CRGB::Black;
            leds[4] = CRGB::Black;
            leds[5] = CRGB::Red;
            leds[6] = CRGB::Yellow;
            leds[7] = CRGB::Green;
            leds[8] = CRGB::Blue;
            leds[9] = CRGB::Purple;
            FastLED.show(10);
            delay(x);
            leds[0] = CRGB::Black;
            leds[1] = CRGB::Black;
            leds[2] = CRGB::Black;
            leds[3] = CRGB::Black;
            leds[4] = CRGB::Black;
            leds[5] = CRGB::Black;
            leds[6] = CRGB::Red;
            leds[7] = CRGB::Yellow;
            leds[8] = CRGB::Green;
            leds[9] = CRGB::Blue;
            leds[10] = CRGB::Purple;
            FastLED.show(10);
            delay(x);
            leds[0] = CRGB::Black;
            leds[1] = CRGB::Black;
            leds[2] = CRGB::Black;
            leds[3] = CRGB::Black;
            leds[4] = CRGB::Black;
            leds[5] = CRGB::Black;
            leds[6] = CRGB::Black;
            leds[7] = CRGB::Red;
            leds[8] = CRGB::Yellow;
            leds[9] = CRGB::Green;
            leds[10] = CRGB::Blue;
            leds[11] = CRGB::Purple;
            FastLED.show(10);
            delay(x);
            leds[0] = CRGB::Black;
            leds[1] = CRGB::Black;
            leds[2] = CRGB::Black;
            leds[3] = CRGB::Black;
            leds[4] = CRGB::Black;
            leds[5] = CRGB::Black;
            leds[6] = CRGB::Black;
            leds[7] = CRGB::Black;
            leds[8] = CRGB::Red;
            leds[9] = CRGB::Yellow;
            leds[10] = CRGB::Green;
            leds[11] = CRGB::Blue;
            leds[12] = CRGB::Purple;
            FastLED.show(10);
            delay(x);
            leds[0] = CRGB::Black;
            leds[1] = CRGB::Black;
            leds[2] = CRGB::Black;
            leds[3] = CRGB::Black;
            leds[4] = CRGB::Black;
            leds[5] = CRGB::Black;
            leds[6] = CRGB::Black;
            leds[7] = CRGB::Black;
            leds[8] = CRGB::Black;
            leds[9] = CRGB::Red;
            leds[10] = CRGB::Yellow;
            leds[11] = CRGB::Green;
            leds[12] = CRGB::Blue;
            leds[13] = CRGB::Purple;
            FastLED.show(10);
            delay(x);
            leds[9] = CRGB::Black;
            leds[10] = CRGB::Black;
            leds[11] = CRGB::Black;
            leds[12] = CRGB::Black;
            leds[13] = CRGB::Black;
            delay(x);
}

Ich komm damit nicht weiter .. hab jetzt einiges ausprobiert das mir logisch erschien.. einmal wechselt die LED einfach die farbe wenn sie wieder von vorne los fährt das nächstemal blicken sie nur bleiben aber auf einer Position .. wäre schön wenn mir hier jemand helfen konnt nochmal zu Erklärung:

Ich möchte mehrere LED´s in einer bestimmten farbreihenfolge über den streifen wandern lassen.

Dein Dilemma steckt im delay() und der fehlenden Erkenntnis, daß loop ständig durchlaufen werden sollte. Wenn es Dir ein Trost ist, da bist Du nicht alleine: Auf Kriegsfuss mit den millis

Also delay durch millis ersetzen, nicht direkt, sondern von der Funktionalität her.

okay.. das versteh ich jetzt überhaupt nicht

N-E-M-A-N:
okay.. das versteh ich jetzt überhaupt nicht

Da ich am besten mit einem funktionierenden Programm lerne, anbei eins, was zeigt, was ich meine.

Bitte beachte, mein LEDstreifen hängt an einem teensy 3.2 mit 62 Lichtpunkten, daher ist die Initialisierung anders. Bitte übernimm Deine Initialisierung!

Test_Forum.ino (1.2 KB)

Danke erstmal für den Code,

Funktioniren tut es schonmal allerdings nur einmal also keine schleife.. die milibefehle versteh ich trotzdem noch nicht so ganz.. ich werd damit noch ein bisschen rumspielen und versuchen.

Gruß Florian

N-E-M-A-N:
... also keine schleife..

Nur wer eine Schleife beantragt, bekommt auch eine. :slight_smile:

Jetzt habe ich mit Nano und SPI getestet. SPI könntest Du auch verwenden, wenn Du magst.

Test_Forum.ino (1.57 KB)

N-E-M-A-N:
Funktioniren tut es schonmal allerdings nur einmal also keine schleife.. die milibefehle versteh ich trotzdem noch nicht so ganz.. ich werd damit noch ein bisschen rumspielen und versuchen.

Grundlegende Zusammenhänge werden vielleicht besser verständlich wenn du aufhörst nur in "Befehlen" zu denken, sondern Operanden, Anweisungen und Funktionen unterscheidest.

+, =, && etc. sind Operanden. Die gehen in genau festgelegten Regeln mit ihren Argumenten um

for, while, if, etc. sind Anweisungen. Auch hier gilt dass genau festgelegt ist was die tun. Und wie bei Operanden kommen die von der Programmiersprache und sind Standard

millis(), delay(), addLeds(), etc. sind Funktionen. Hier wird es komplizierter. Die sind von Programmierern selbst geschrieben. Entsprechend sind sie auch dokumentiert. Entweder in der Arduino Referenz oder der Bibliothek wo sie drin stehen (wie bei FastLED).
Bei Funktionen hilft es auch sie zu analysieren: welchen Namen haben sie? Welche Parameter haben sie (sowohl Name als auch Datentyp). Welchen Datentyp hat der Rückgabewert? Aus diesen Sachen kann man oft erschließen was gemacht wird. Aber auch nicht immer.

Die millis() Thematik ist allerdings um einiges komplexer. Da kommt es eher auf den Algorithmus an wie man die Funktion verwendet.

so würde es natührlich gehen.. aber das geht doch sicherlich auch einfacher ?!

In Ergänzung zu allem bereits Gesagtem: Beim Coden von Animationen hat man 2 Herausforderungen - A) Was passiert? und B) Wann passiert es?

B) löst man wie beschrieben am besten mit millis().

A) hat 2 Antworten - entweder man kann es in einer Formel ausdrücken, oder man muss die einzelnen Schritte der Sequenz abspeichern - was Du im Prinzip getan hast, nur etwas unelegant. Ist aber am Anfang egal, Hauptsache, es funktioniert.
Wenn Du Dich mal mit Arrays beschäftigst, wirst Du bessere Ideen bekommen.
Der Königsweg sind natürlich immer Formeln - fang mal mit einem einfachen einfarbigen Lauflicht an, das geht mit einer For-Schleife und 3 Zeilen Code in der Schleife.

Grüße,

Helmuth

@agmue danke für den Code habe leider immernoch nicht ganz verstanden wie die milli Funktion Funktioniert ... wie kann ich das denn am einfachsten verstehen lernen ? am besten auf deutsch da mein englisch nicht so besonders gut ist.

@Serenifly ich nenne zwar alles Befehl aber mir ist schon klar das es unterschiede gibt und auch in etwa worin diese liegen.

@Helmuth Ich habe mal versucht dein Einfarbigeslauflicht mit der for schleife und einer LED. wäre das so denn dann richtig oder gibt es auch hier noch eine bessere Methode ?
oder war das anders gemeint ?!

#include "FastLED.h"

#define DATA_PIN    6
#define CLOCK_PIN   7
#define NUM_LEDS    141
#define LED_TYPE    APA102
#define COLOR_ORDER BGR
#define SPI_HZ      96
#define BRIGHTNESS  64

CRGB leds[NUM_LEDS];

void setup() {
  FastLED.addLeds<APA102, DATA_PIN, CLOCK_PIN>(leds, NUM_LEDS);
}

void loop() {
  for(int x = 0; x < NUM_LEDS; x++){
    leds[x] = CRGB::Blue;
    FastLED.show(10);
    leds[x] = CRGB::Black;
    delay(100);
  }
}

Ja, so meinte ich das. Du hast das Konzept verstanden - darauf kannst Du jetzt aufbauen.

FastLED.show(10);

Kenne ich nicht. Wofür steht die 10?

FastLED.show(); reicht.

Die Sache mit den millis() wurde hier mal sehr schön anhand eines Wachmanns mit Laufzettel erklärt - aber ich finde den Link gerade nicht. Vielleicht kann jemand aushelfen?!

Gruß,

Helmuth

ich muss gestehen ich weiss selbst nicht wofür das steht jedoch sind die LEDs nicht so hell mit der 10.

Helmuth:
Die Sache mit den millis() wurde hier mal sehr schön anhand eines Wachmanns mit Laufzettel erklärt - aber ich finde den Link gerade nicht. Vielleicht kann jemand aushelfen?!

Gerne doch! Hatte ich in #7 schon mal probiert.

Über Auf Kriegsfuss mit den millis oder Anleitung Endlicher Automat mit millis() gelangt man zum Wachmann.

Helmuth:
Kenne ich nicht. Wofür steht die 10?

Scheint den selben Effekt zu haben wie setBrightness().

Mit loop und for hast Du zwei Schleifen, eine reicht:

#include "FastLED.h"
#define NUM_LEDS       62
#define LED_TYPE   APA102
#define COLOR_ORDER   BGR
#define BRIGHTNESS     96

CRGB leds[NUM_LEDS];

void setup() {
  FastLED.addLeds<LED_TYPE, COLOR_ORDER>(leds, NUM_LEDS).setCorrection(TypicalLEDStrip);
  FastLED.setBrightness(BRIGHTNESS);
  LEDS.showColor(CRGB(0, 0, 0));
}

void loop() {
  static byte x;
  leds[x] = CRGB::Blue;
  FastLED.show();
  leds[x] = CRGB::Black;
  delay(100);
  x++;
  x = x % NUM_LEDS;
}

Und dann mit millis:

#include "FastLED.h"
#define NUM_LEDS       62
#define LED_TYPE   APA102
#define COLOR_ORDER   BGR
#define BRIGHTNESS     96

CRGB leds[NUM_LEDS];
uint64_t aktMillis, goMillis;
const uint64_t goIntervall = 100;

void setup() {
  FastLED.addLeds<LED_TYPE, COLOR_ORDER>(leds, NUM_LEDS).setCorrection(TypicalLEDStrip);
  FastLED.setBrightness(BRIGHTNESS);
  LEDS.showColor(CRGB(0, 0, 0));
}

void loop() {
  static byte x;
  aktMillis = millis();
  leds[x] = CRGB::Blue;
  FastLED.show();
  if (aktMillis - goMillis >= goIntervall) {
    goMillis = aktMillis;
    leds[x] = CRGB::Black;
    x++;
    x = x % NUM_LEDS;
  }
}

Zunächst werden goMillis und aktMillis gleichgesetzt. Während goMillis unverändert bleibt, wird millis() und damit aktMillis vom System (Timer) inkrementiert. Irgendwann hat sich aktMillis soweit von goMillis entfernt, daß goIntervall den Unterschied ausmacht, also (aktMillis - goMillis >= goIntervall) wahr wird. Dann werden wieder goMillis und aktMillis gleichgesetzt und es beginnt von vorne.

@agume danke den link in #7 habe ich auch gesehen aber trotzdem nicht verstanden.. bis zu deinem Wachman link bin ich dann gar nicht gekommen.
wie die millis funktionieren weiss ich auch ich denke bei vielen "befehlen" (ich nenne sie jetzt mal wieder so ..) fällt es mir schwer sie richtig zu benutzen weil ich nicht genau weiss welcher was tut, könnte evtl. auch daran liegen das mein englisch nicht so toll ist und mir der Name daher schon gar nichts sagt ?!

villeicht kann mir ja jemand erklären welche zeile genau was bewirkt.. hier mal ein fertiger, funktionierender Sketch:

#define FASTLED_FORCE_SOFTWARE_SPI
#include "FastLED.h"
FASTLED_USING_NAMESPACE
#define DATA_PIN    6
#define CLK_PIN     7
#define LED_TYPE    APA102
#define COLOR_ORDER BGR
#define SPI_HZ      96
#define BRIGHTNESS  64
#define NUM_LEDS    141

CRGB leds[NUM_LEDS];
unsigned long aktMillis, verzMillis, intervall = 100;
unsigned int ind;
bool initalisierung = true;

void setup() {
  Serial.begin(9600);
  Serial.println("Programmanfang");
  FastLED.addLeds<APA102, DATA_PIN, CLK_PIN>(leds, NUM_LEDS);
  FastLED.addLeds<LED_TYPE, DATA_PIN, CLK_PIN, COLOR_ORDER, SPI_HZ>(leds, NUM_LEDS).setCorrection(TypicalLEDStrip);
  FastLED.addLeds<LED_TYPE, COLOR_ORDER>(leds, NUM_LEDS);   
  FastLED.setBrightness(BRIGHTNESS);
  LEDS.showColor(CRGB(0, 0, 0));
}

void loop() {
  aktMillis = millis();
  if (initalisierung) {
    initalisierung = false;
    ind = 0;
    leds[0] = CRGB::Red;
    leds[1] = CRGB::Yellow;
    leds[2] = CRGB::Green;
    leds[3] = CRGB::Blue;
    leds[4] = CRGB::Purple;
    FastLED.show();
  }
  if ((aktMillis - verzMillis > intervall) && (ind < NUM_LEDS)) {
    verzMillis = aktMillis;
    for (byte k = 5; k > 0; k--) {
      if (ind + k < NUM_LEDS) {
        leds[ind + k] = leds[ind + k - 1];
      }
    }
    leds[ind] = CRGB::Black;
    ind++;
    Serial.print("ind: ");
    Serial.println(ind);
    FastLED.show();
    if (ind >= NUM_LEDS) {
      initalisierung = true;
    }
  }
}

jetzt nochmal der selbe Sketch aber nur die zeilen die was mit dem milli zu tun haben ?!

unsigned long aktMillis, verzMillis, intervall = 100;
unsigned int ind;
bool initalisierung = true;

void setup() {

}

void loop() {
  aktMillis = millis();
  if (initalisierung) {
    initalisierung = false;
    ind = 0;
     }
  if ((aktMillis - verzMillis > intervall) && (ind < NUM_LEDS)) {
    verzMillis = aktMillis;
    for (byte k = 5; k > 0; k--) {
      if (ind + k < NUM_LEDS) {
        leds[ind + k] = leds[ind + k - 1];
      }
    }
    leds[ind] = CRGB::Black;
    ind++;
    Serial.print("ind: ");
    Serial.println(ind);
     if (ind >= NUM_LEDS) {
      initalisierung = true;
    }
  }
}

die Serial.print() sollte mir villeicht auch nochmal jemand genau erklären haben die in dem fall eine Funktion bzw sind sie wichtig damit das Programm läuft oder nicht ?