Programmierung Zwei-Dimensionales Arrays in Array appenden/einstellen

Hallo zusammen,

ich habe mir ein 5x5 Matrix gebaut.

Jetzt möchte ich mir einen Ticker bauen.

Angenommen ich habe zwei Buchstaben (hier im Beispiel X und M) als zweidimensionale Array definiert:

byte X_Array[5][5] = {
  {X, _, _, _, X},
  {_, X, _, X, _},
  {_, _, X, _, _},
  {_, X, _, X, _},
  {X, _, _, _, X},
};
byte M_Array[5][5] = {
  {X, _, _, _, X},
  {X, X, _, X, X},
  {X, _, X, _, X},
  {X, _, _, _, X},
  {X, _, _, _, X},
};

Wie kann ich nun ein Array bauen, in dem ich ein ganzes Wort nun aus einzelnen Buchstaben(-Arrays) zusammensetze?

Danke und viele Grüße
Mario

Hallöle,
es ist immer wieder ein interessantes Thema, LED-Arrays via Bye oder sogar Integer anzusprechen.
Schau dazu mal in >>> diesen Thread.
Dort existiert ein ähnliches Problem mit vielen guten Aussagen drum herum.
LG, Rudi

Z.B. indem Du Dir ein Array in der passenden Größe erstellst und dann mit for-Schleifen elementweise rüberkopierst. Vermutlich geht noch was Effizienderes mit memcpy, aber dafür reicht mein C nicht ohne Zeit zu investieren.
Das Problem hier scheint mir aber auch ein anderes zu sein: Du bist nicht auf einem modernen PC. Speicher ist stark begrenzt. In Deinem Beispiel haust Du z.B. 25 Byte für einen Buchstaben raus. Das Alphabet ohne Groß/Kleinschreibung nimmt dann schon 650 Byte in Anspruch. Der ganze ATMega hat 32kB Flash und 2KB SRAM.
Dein Wort nimmt nochmal 26 Byte*Wortlänge weg (diesmal vermutlich auf jeden Fall im arg begrenzten RAM).

Es ist also vermutlich eine gute Idee
a) KEINE Wörter zu generieren, sondern was auch immer Du machen willst sequenziell zu erzeugen und nicht gleichzeitig im Speicher zu halten und
b) die Buchstaben effizienter zu speichern. Wenn es monochrom und mit fester Helligkeit ist, dann wäre schon mal boolean statt byte um den Faktor 8 effizienter. 25 bit statt 650. Ansonsten wäre es vielleicht besser, die Daten als sparse matrix zu speichern, also als Paare aus (eindimensionalen) Indizes und Werten.

Auf jeden Fall lesen möchtest Du vermutlich Gammon Forum : Electronics : Microprocessors : Putting constant data into program memory (PROGMEM)

Diesen Aussagen kann ich größtenteils zustimmen. Einziges Manko wäre aber noch der empfohlene Einsatz von “boolean” als Array:

Ein Test in der IDE 1.6.9 ergab, dass es vollkommen gleichgültig ist, ob man “byte”, “boolean”, “bool” oder “char” nimmt. Nachfolgender Code verbraucht immer 208 Bytes statisches RAM:

boolean arr[5][5] = 
{
  { true,  true, true, false, false },
  { true,  true, true, false, true  },
  { false, true, true, false, true  },
  { false, true, true, false, true  },
  { true,  true, true, false, true  }
};

void setup()
{ Serial.begin(9600); }

void loop()
{
  for( byte z = 0; z < 5; z++ )
     for( byte s = 0; s < 5; s++ )
        Serial.print( arr[z][s] );
}

Der Unterschied macht sich aber im FLASH bezüglich der Programmlänge bemerkbar:

Verbauchen “bool” und “boolean” noch 2142 Bytes, reduziert sich der Verbrauch bei “byte” und “unsigned char” schon auf 2002 Bytes. Einzig und allein bei “char” werden hier nur noch 1770 Bytes verbraucht.

Es bietet sich also für solche Matrix-Dinge mit normalen LEDs auf jedem Fall an, dass man sein “Bit-Array” in z.B. einmal “unsigned long” packt ( = 32 Bit ) und dieses “Array” dann mittels bitRead(…) ausliest und an die LEDs sendet.

Der Unterschied im flash-Bedarf liegt übrigens vermutlich an Serial.print.

Natürlich sind bool, boolean und char gleich groß ( 1 byte ).

Probier mal diese Zeile

      Serial.print( (int) arr[z][ s ] ) ;

Da sollte auch der ProgrammSpeicher-Bedarf unabhängig von bool / boolean /char sein. (Ungetestet)

Oh, Tatsache. Boolean ist auch ein Byte groß. Mea culpa. Ich denke das ist auch der Grund, warum es kein uint4_t gibt?

In dem Fall schließe ich mich der Empfehlung an, da ganze bitweise in unsigned integers zu speichern und dann mittels bitshift (oder meinetwegen auch Arduino-Zeug wie bitRead) auszulesen.

Ich denke das ist auch der Grund, warum es kein uint4_t gibt?

Die kleinste Einheit auf den allermeisten Prozessoren heutzutage für die es C-Compiler gibt, die eine eigene Adresse hat, ist ein Byte.
sizeof kann auch minimal nur 1 zurückliefern.

Was noch kleiner geht, ist struct mit Bitfeldern. So kannst du einzelnen Bits Namen geben, wenn das Sinn macht. Wenn es mit Hardware zu tun hat oder irgendwie ausgetauscht werden soll, muss noch klar sein, in welcher Reihenfolge die Bits gezählt werden. Das ist nicht generell festgelegt, daher nicht für portablen Code zu empfehlen.

Bei avr-gcc für avr 8 bit Controller kommt das niedrigstwertige byte zuerst, und innerhalb eines Bytes das höchstwertigste Bit zuerst. ( Ohne Gewähr :wink: )

Sehr verwirrend, und der damit erzeugte Code ist auch nicht kleiner/schneller als wenn man z.B. den BV(Name) Makro für die Bits der Controller-Register verwendet.

Auch wenn Du keinen Treiber MAX7219 verwenden solltest, findest Du bei diesen Links die Definition des Alphabets als Bitmuster usw. Ich habe aus einem Font 5x7 einen mit 5x8 gemacht, Du kannst natürlich auch 5x5 erzeugen:

Tutorial – Arduino and the MAX7219 LED Display Driver IC

Drei Fontgeneratoren

Was noch kleiner geht, ist struct mit Bitfeldern. So kannst du einzelnen Bits Namen geben, wenn das Sinn macht. Wenn es mit Hardware zu tun hat oder irgendwie ausgetauscht werden soll, muss noch klar sein, in welcher Reihenfolge die Bits gezählt werden. Das ist nicht generell festgelegt, daher nicht für portablen Code zu empfehlen

Der Code der dafür erzeugt wird ist auch nicht unbedingt der sparsamste, wenn oben schon Flash Verbrauch angesprochen wurde.

Wenn man selbst direkt Kontrolle möchte, dann wie gesagt ein primitives Bit Set aus einem oder mehreren Integern bauen und bitRead() etc. verwenden