Forum: Mikrocontroller und Digitale Elektronik Led Matrix in 1D Array umwandeln


von Sebbi (Gast)


Lesenswert?

Hallo,

ich habe mehrere Led Module (3x3) hintereinandergeschaltet. Insgesamt 8 
Stück. Das ganze wird über ein Array mit Werten befeuert.

Nun geht es darum, dass ich die Koordinaten xy in ein 1D umrechne. Die 
Anordnung ist wie im Kommentar zu erkennen. Ist die Funktion soweit 
okay, oder kann man die ggf. kürzen?

Die Reihen sind fix. Die Länge der Spalten hängt von der Menge 
aneinandergereihter Module ab.
1
int getLedNumber(int x, int y)
2
{
3
  /*
4
  Panel0      Panel1      Panel2
5
  00  01  02  |  09  10  11  |  18  19  20
6
  03  04  05  |  12  13  14  |  21  22  23
7
  06  07  08  |  15  16  17  |  24  25  26
8
9
  */
10
  const int rowsEachPanel  = 3;    // Anzahl Reihen
11
  const int colsEachPanel  = 3;    // Anzahl Spalten
12
  const int ledsEachPanel  = 9;    // Anzahl pro Panel
13
  int numPanel = x / colsEachPanel;  // Anzahl Panels
14
  int led;
15
16
  led = (numPanel * ledsEachPanel) + (x % rowsEachPanel) + (y * rowsEachPanel);
17
  return led;
18
}

von asdfasd (Gast)


Lesenswert?

Der Kode sieht korrekt aus.  Falls deine CPU bei Divison/Modulo langsam 
ist, bietet es sich an, eine Lookup-Tabelle zu benutzen:
1
int getLedNumber(int x, int y)
2
{
3
  /*
4
  Panel0      Panel1      Panel2
5
  00  01  02  |  09  10  11  |  18  19  20
6
  03  04  05  |  12  13  14  |  21  22  23
7
  06  07  08  |  15  16  17  |  24  25  26
8
  */
9
10
  static const unsigned char col[] = {
11
    0, 1, 2,  9, 10, 11,  18, 19, 20
12
  };
13
14
  return col[x] + y * 3;
15
}

Ich gehe davon aus, dass das "y*3" zu "(y<<1)+y" optimiert wird.

von asdfasd (Gast)


Lesenswert?

Hmm... kein Edit.  Für 8 Panels muss die Tabelle natürlich entsprechend 
erweitert werden.

von Matthias L. (Gast)


Lesenswert?

Wenns nicht am Flash hapert, dann leg das hier doch direkt als 2D-Array 
ins Flash:
1
  /*
2
  Panel0      Panel1      Panel2
3
  00  01  02  |  09  10  11  |  18  19  20
4
  03  04  05  |  12  13  14  |  21  22  23
5
  06  07  08  |  15  16  17  |  24  25  26
6
  */

von Karl H. (kbuchegg)


Lesenswert?

Sebbi schrieb:

>
1
> int getLedNumber(int x, int y)
2
> {
3
>   /*
4
>   Panel0      Panel1      Panel2
5
>   00  01  02  |  09  10  11  |  18  19  20
6
>   03  04  05  |  12  13  14  |  21  22  23
7
>   06  07  08  |  15  16  17  |  24  25  26
8
> 
9
>   */
10
>   const int rowsEachPanel  = 3;    // Anzahl Reihen
11
>   const int colsEachPanel  = 3;    // Anzahl Spalten
12
>   const int ledsEachPanel  = 9;    // Anzahl pro Panel
13
>   int numPanel = x / colsEachPanel;  // Anzahl Panels
14
>   int led;
15
> 
16
>   led = (numPanel * ledsEachPanel) + (x % rowsEachPanel) + (y * 
17
> rowsEachPanel);
Nitpicking.
Ich denke hier müsste es colsEachPanel lauten und nicht rowsEachPanel. 
Die Anzahl der Zeilen kommt nirgends vor, weil du diese Anzahl nur in 
der Anzahl der LED in einem kompletten Modul 'ledsEachPanel' implizit 
drinnen hast.

Bei dir spielt das jetzt insofern keine Rolle, weil du gleiche viele 
Zeilen (rows) wie Spalten (cols) hast. Aber überleg dir das mal am 
Beispiel von 4*3 Modulen
1
   Panel0            Panel1         Panel2
2
   00  01  02  03 |  12 13 14 15 |  24 25 26 27 28
3
   04  05  06  07 |  16 17 18 19 |  29 39 31 32 33
4
   08  09  10  11 |  20 21 22 23 |  34 35 36 37 28
1
  const int rowsEachPanel  =  3;    // Anzahl Reihen
2
  const int colsEachPanel  =  4;    // Anzahl Spalten
3
  const int ledsEachPanel  = 12;    // Anzahl pro Panel

wir wollen die Nummer der LED an der Position x = 7 und y = 1
Aus der Grafik entnehmen wir, das das richtige Ergebnis
1
                              |
2
                              |
3
                              v
4
   Panel0            Panel1         Panel2
5
   00  01  02  03 |  12 13 14 15 |  24 25 26 27 28
6
   04  05  06  07 |  16 17 18 19 |  29 39 31 32 33   <-----
7
   08  09  10  11 |  20 21 22 23 |  34 35 36 37 28

19 wäre.

Was ergibt deine Formel
1
  int numPanel = x / colsEachPanel;     // 7 / 4 -> 1 . OK
2
3
  led = (numPanel * ledsEachPanel) +    // 1 * 12  ->    12
4
        (x % rowsEachPanel) +           // 7 % 3   ->     1
5
        (y * rowsEachPanel);            // 1 * 3   ->     3
6
                                        //             ------
7
                                        //               16

und das ist offensichtlich nicht richtig.

Gegentest
1
  led = (numPanel * ledsEachPanel) +    // 1 * 12  ->    12
2
        (x % colsEachPanel) +           // 7 % 4   ->     3
3
        (y * colsEachPanel);            // 1 * 4   ->     4
4
                                        //             ------
5
                                        //               19
welches korrekt und auch logisch nachvollziehbar ist. In Y Richtung 
werden die Anzahl der LED in einer kompletten Zeile gezählt. Dies ist 
aber in colsEachPanel vermerkt - die Anzahl der Spalten in jedem Modul. 
Genauso in X Richtung. Die ANzahl der dann noch fehlenden LED in der 
letzten nicht vollständigen Zeile, ist die X Position modulo der Anzahl 
der Spalten. Du hast ja auch völlig korrekt die Nummer des Panels 
dadurch ermittelt, dass du die X Koordinate durch colsEachPanel 
dividiert hast.

Wenn man Dinge ausprobiert, dann ist es meistens keine gute Idee, 
quadratische Verhältnisse anzunehmen. Man merkt dann nie direkt, ob man 
sich mit x und y bzw. Zeilen und Spalten vertan hat. Bei nicht 
quadratischen Verhältnissen fällt so etwas viel früher auf.

: Bearbeitet durch User
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.