[C++] LED Matrix berechnen

Heute ist Stammtischzeit:
Jeden Donnerstag 20:30 Uhr hier im Chat.
Wer Lust hat, kann sich gerne beteiligen. ;)
  • Hallo zusammen,

    ich wollte mich jetzt in meinem Projekt jetzt mal der LED-Matrix widmen und bis ich alle Module hab, schon mal etwas mit der Software beginnen.

    Ich bin noch absoluter Anfänger in C++, PHP ist mir da viel vertrauer.

    Jedenfalls, ich nutze in meiner LED-Matrix mehrere LED-Module mit 8x8 LEDs, von denen ich 4 untereinander und 10 nebeneinander anreihe. Da natürlich erst das einzelne Modul durchgeschleift ist, geh ich nicht Reihe für Reihe durch mit der Nummerierung, sondern 8 rüber, eine Zeile runter, wieder 8 rüber und nach der 8 Zeile und Spalte wieder in die erste Zeile.

    Also wollte ich mir eine kleine Funktion schreiben, die in einem Vector festhält, wo welche LED sitzt. Zum einem als Koordinatensystem mit der laufenden Nummer, als auch, welche Koordinaten die laufende Nummer hat.

    Zur kontrolle wollte ich mir das dann mal ausgeben lassen, aber es kam nichts.

    Hier mal der Code:

    Bei mir kommt nicht mal ein "Hallo" aus der geschachtelten for-Schleife raus, also irgendwo bleibt das hängen. Die Werte werden aber richtig an die Funktion übergeben.

    Natürlich werd ich das später noch richtig "aufräumen", das war jetzt nur mal ein Code-Schnipsel, ob das so überhaupt funktionieren könnte.

    Ich hoffe, es ist verständlich, wo mein Problem liegt und was ich eigentlich will.

    Vielen Dank schon mal und

    liebe Grüße

    Fipsi

    P.S.: ich vermiss mein Array-Handling aus PHP jetzt schon :X:X

  • 1. Dir fehlt ein include:

    C++
    #include <iostream>

    2. Du kannst nicht einfach so an beliebige Stellen eines vector<T> schreiben, sondern du musst erst mit resize() den nötigen Platz schaffen (oder anderweitig, z.B. insert()).

    Ganz ganz hässlich, funktioniert aber:

    C++
    display.resize(i_1 + 1);
    display[i_1].resize(led_row + 1);
    display[i_1][led_row].resize(led_col + 1);
    leds.resize(led_nr + 1);
    
    display[i_1][led_row][led_col] = led_nr;
    leds[led_nr] = { led_row, led_col };

    Ich denke aber, dass ein Vektor hier die falsche Datenstruktur ist - wenn die Größe des Displays in createDisplay() ja eh bekannt ist, kannst du doch ein normales Array erstellen, das eine zu Beginn festgelegte fixe Größe hat. Dann kannst du auch wieder an beliebige Stellen im Array schreiben, vorrausgesetzt du bleibst innerhalb dieser festgelegten Größe.

  • Du benutzt ja schon std::array, das kannst du doch ueberall machen. Die sind schon gleich vorallokiert.

    Mir ist aber der Sinn nicht klar. Aus einer Frame-Koordinate willst du doch nur auf das konkret angegangene Display kommen, und welche Koordinate du da hast. Eine so verschachtelte Struktur hilft doch da ueberhaupt nicht.

  • Ich glaub, ich sollte dazu sagen, dass ich Matrixen verschiedener Größe haben kann, deswegen will ich nur die Größe angeben können und der Rest wird berechnet, weshalb meiner Ansicht nach Array nicht das richtige ist? Zumindest wollte der Compiler bei mir keine Variable bei der Array-Größe annehmen.

    Linus, wie wäre die schöne Variante deines Beispiels?

    (Ich hoffe, ich bin jetzt voll auf euch beide eingegangen... :conf:)

  • Mir ist hier das Endziel noch unklar. Wie sind die Displays angeschlossen? Welche Frage beantwortet dieses Stueck Code dann ueberhaupt?

  • Okay, ich fang noch mal an:

    Ich hab hier neben mir 8x8 LED-Matrixen [Anzeige] liegen, die ich zu einer größeren Matrix verbinden will, momentan z. B. 32 x 80 LEDs.
    Die LEDs werden ja über den Bus der Reihenfolge nach angesteuert. Durch die Matrixen, die ich aber verwende, läuft nicht die erste Zeile der gesamten Matrix von 0 bis 79 durch, sondern steht die 8 in der zweiten Zeile und in der ersten Zeile an Position 8 steht die tatsächliche 64.

    Und das ganze möchte ich mir in einem mehrdimensionalen Array, bzw. Vector berechnen, an welcher Koordinatenposition welche laufende Nummer der LEDs sitzt, um Zeichen auf die Koordinaten setzen zu können und beim refresh zu wissen, welche Koordinate welche laufende Nummer ist.

    Hab ich jetzt alle Klarheiten beseitigt oder muss ich noch mal anders ansetzen?:denker:

  • Linus:

    also z. B. so?

    Also dass ich das vor die anderen 5 for-Schleifen häng, die dann die Berechnungen vornehmen? Compiler sagt nein.. :-/

  • Also, wenn ich dich richtig verstehe, geht es darum, zu den Koordinaten einer LED (Zeile 11, Spalte 27) die LED-Nummer in der Kette neben- und übereinander geschalteter 8x8-Module zu ermitteln.

    Wenn du das meinst, dann finde ich dein Programm etwas kompliziert - das kann man mit mathematischen Formeln ausrechnen...

    Ich finde die Vektorstruktur unnötig und aufwändig. Wenn du eine Bibliothek wie FastLED benutzt, legst du einfach ein LED-Array an mit so vielen Elementen, wie du LEDs hast. Wenn du eine bestimmte LED ändern willst, kannst du ihre lineare Nummer aus Zeile und Spalte mathematisch berechnen.

    Modulgröße (matrix_height, matrix_width) und Modulanzahl (rows, cols) verstehe ich. Aber wozu brauchst du mehrere Outputs? Willst du mehrere Modulblöcke über getrennte Datenleitungen ansteuern? Geht natürlich auch. Sind die Modulblöcke dann übereinander oder Nebeneinander angeordnet?

    Oh, man kann hier unliebsame Nutzer blockieren. Wie praktisch!

  • Zitat

    Also, wenn ich dich richtig verstehe, geht es darum, zu den Koordinaten einer LED (Zeile 11, Spalte 27) die LED-Nummer in der Kette neben- und übereinander geschalteter 8x8-Module zu ermitteln.

    Richtig

    Wenn du das meinst, dann finde ich dein Programm etwas kompliziert - das kann man mit mathematischen Formeln ausrechnen...

    Ich finde die Vektorstruktur unnötig und aufwändig. Wenn du eine Bibliothek wie FastLED benutzt, legst du einfach ein LED-Array an mit so vielen Elementen, wie du LEDs hast. Wenn du eine bestimmte LED ändern willst, kannst du ihre lineare Nummer aus Zeile und Spalte mathematisch berechnen.

    Aber bei FastLED z. B. ist das doch nur, wenn die laufende LED-Nummer die Reihe fertig durch geht, oder?

    Ich hab grad mal versucht aufzumalen, wie bei mir der Bus verläuft. Der großse Schwarze Kasten ist die ganze Matrix, die kleineren die einzelnen Module, die schwarzen Punkte die einzelnen LEDs und der orangene Strich der Bus.

    Ja, ich weiß, ich bin künstlerisch sehr begabt :no_sad::no_sad:

    Zitat

    Modulgröße (matrix_height, matrix_width) und Modulanzahl (rows, cols) verstehe ich. Aber wozu brauchst du mehrere Outputs? Willst du mehrere Modulblöcke über getrennte Datenleitungen ansteuern? Geht natürlich auch. Sind die Modulblöcke dann übereinander oder Nebeneinander angeordnet

    Modulgröße (matrix_height, matrix_width) und Modulanzahl (rows, cols) verstehe ich. Aber wozu brauchst du mehrere Outputs? Willst du mehrere Modulblöcke über getrennte Datenleitungen ansteuern? Geht natürlich auch. Sind die Modulblöcke dann übereinander oder Nebeneinander angeordnet?Ja, das wäre der Gedanke dahinter, falls ich doch auf einen ESP umsteigen sollte. In dem Beispiel wären die Modulblöcke untereinander.

  • Das geht auch, wenn die LEDs beliebig angeordnet sind. Aber du hast ja eine logische Struktur drin.

    8x8 LEDs ist eine Matrix

    10x4 Matritzen ist ein Block

    soundsoviel Blöcke übereinander sind das ganze Panel.

    Man kann aus der Position einer LED (Zeile/Spalte) im gesamten Panel die Nummer im linearen LED-Array ausrechnen, auch wenn das Array schlingelschlangel durch die Module mäandert.

    Oh, man kann hier unliebsame Nutzer blockieren. Wie praktisch!

  • Du musst eine Datenstruktur anlegen, welche die Position und Dimension der Displays beschreibt in der Reihenfolge, in der sie aneinander gekettet sind. Und dann kannst du fuer jedes Pixel aus dem Definitionsbereicht (Position auf dem virtuellen Screen) den Wert imWertebereich (globale Position, weil die ja einfach hintereinander stehen) berechnen.

    In Python sieht das so aus:

    Einmal editiert, zuletzt von MistyFlower59469 (8. Juni 2020 um 17:38)

  • Code
    int modul  = led / 64 ;
    int zeile  = (led % 64) / 8 ;
    int spalte = (led % 64) % 8 ;

    Tell, das klappt so nicht. Das ist trivial. Er will aus der Zeile und Spalte auf dem Gesamtpanel die LED-Nummer bestimmen, nicht aus der LED-Nummer das Modul und die Zeile und Spalte auf dem Modul...


    Ich hab mir das so vorgestellt (hier mal als Excel-Formel):

    ZEILE = Zeile der LED auf dem gesamten Panel

    SPALTE = Spalte der LED auf dem gesamten Panel

    LEDY = LEDs pro Modul vertikal (8)

    LEDY = LEDs pro Modul vertikal (8)

    (8x8-Module)

    MODX = Module pro Block horizontal (10)

    MODY = Module pro Block vertikal (4)

    (10x4 Module pro Block)

    BLX = Blöcke horizontal (1)

    (Blöcke nur untereinander nicht nebeneinander - hier könnte auch 2 stehen für z. B. 2x3 Blöcke)

    Block:

    =ABRUNDEN((ZEILE / (MODY*LEDY));0) * BLX + ABRUNDEN(SPALTE / (MODX*LEDX);0)

    LED:

    =(ABRUNDEN(REST(ZEILE; (LEDY * MODY)) / LEDY; 0) * MODX + ABRUNDEN(REST(SPALTE; (LEDX*MODX)) / LEDX; 0)) * (LEDX * LEDY) + (REST(ZEILE; LEDY)) * LEDX + REST(SPALTE; LEDX)

    Ich hoffe, es stimmt... ;)


    Im Code ersetzt du die Werte wegen der Geschwindigkeit besser durch Konstanten, wobei du natürlich z. B. LEDY * MODY am besten gleich ausrechnest.

    Ich hab sowas in C programmiert - da C bei Integern von sich aus intern abrundet, entfallen die ganzen Abrundungen. Das ist natürlich dann recht einfach.

    Ne andere Lösung, die mit genügend Speicher sicher ganz gut geht (und schnell ist - zumindest in C auf einem ESP32) wäre ein Mapping. Du erstellst einmal eine Matrix nach Spalten und Zeilen in der die Pointer auf die Elemente des LED-Arrays stehen. Um dieses Array zu erstellen, brauchst du aber dann doch wieder die obigen Formeln. Die Ausführung dürfte aber mit einem Mapping schneller sein.

    Oh, man kann hier unliebsame Nutzer blockieren. Wie praktisch!

    2 Mal editiert, zuletzt von Gnom (8. Juni 2020 um 19:42)

  • Ich danke euch dreien, ich werde mir das morgen noch mal zu Gemüte führen.

    __deets__, dass mir deins gerade zu hoch ist, kann ich dir aber gleich schon sagen :conf::lol:

    Jetzt mal ganz blöd gefragt...: gibt es eine Sprache wie C++, Java, etc., bei der Arrays so einfach sind wie in PHP? Also auch ohne dem ganzen Typengedöns? Da hätte ich die Lösung schon längst :shy::lol:

  • Na Python hat auch kein Typgedoens. Oder siehst du irgendwo eine Typdeklaration? Und wenn es dir einfacher faellt das in PHP zu machen, mach es doch in PHP. Und uebersetz das dann Stueck fuer Stueck nach C++. Nur habe ich meinen Zweifel, dass es in PHP einfacher ist als in Python. Denn unter einer gewissen Komplexitaet ist das Problem nunmal nicht zu haben.

  • Eine andere Moeglichkeit ist uebrigens, die Ausgabe von zB meinem Skript in eine C-Datenstruktur zu wandeln, und mit einzukompilieren. Wenn einem das in C selbst zu hoch ist.

  • > Er will aus der Zeile und Spalte auf dem Gesamtpanel die LED-Nummer bestimmen

    Code
    /* Alle zaehler beginnen bei 0 */
    int module    = (row / 8) * 7 + col / 8 ;
    int modulerow = row % 8 ;
    int modulecol = col % 8 ;

    Auscodiert

    Einmal editiert, zuletzt von Tell (8. Juni 2020 um 20:42)

  • > Er will aus der Zeile und Spalte auf dem Gesamtpanel die LED-Nummer bestimmen

    Code
    /* Alle zaehler beginnen bei 0 */
    int module    = (row / 8) * 7 + col / 8 ;
    int modulerow = row % 8 ;
    int modulecol = col % 8 ;

    Was immer du damit sagen willst, es klappt nicht und es ist nicht das, was er will/braucht. Es bringt relativ wenig, hier irgendwelche Codebrocken hinzuwerfen, die nicht viel mit der Aufgabenstellung zu tun haben. Du hast jetzt die Nummer des Moduls und dessen Zeile und Spalte. Das ist nur die halbe Miete. Wenn du deinen Ansatz mal richtig zu Ende bringst, landest du genau bei meiner Formel. Wenn du dem TO helfen willst, dann tu es richtig. Wenn du keine Zeit oder Lust hast, dann lass es ganz bleiben.

    Oh, man kann hier unliebsame Nutzer blockieren. Wie praktisch!

Jetzt mitmachen!

Du hast noch kein Benutzerkonto auf unserer Seite? Registriere dich kostenlos und nimm an unserer Community teil!