Voller Arbeitsspeicher (Arduino Esplora, Part 5)


Der Arduino oder auch vielmehr der verwendete Mikrocontroller hat für viele Anwendungen genügend Arbeitsspeicher. Im ersten Teil der Blogpost Reihe verwendete ich einen Arduino Nano, der einen ATmega328 hat und einen Arbeitsspeicher von 2kByte besitzt. Der Arduino Esplora verwendet den ATmega32u4 der wiederum 2,5kByte Arbeitsspeicher aufweist. Trotz des etwas größeren Arbeitsspeichers muss für dieses Projekt dennoch sparsam damit umgegangen werden.

ATmega328P und ATmega32u4

Arbeitsspeicher verbrauch
Ein Sprite Bild besteht selbst aus 160 Bytes. Das klingt jetzt nicht viel, aber verbraucht den Arbeitsspeicher bereits mit über 6%. Würde man die Sprite Animation der Figur nicht mit dem Trick einzelner Bilder spiegeln, dann würden insgesamt 2,92kByte Arbeitsspeicher anfallen. Stattdessen werden momentan 1,12kB verwendet, dass allerdings für das Ziel immer noch zu viel ist. Und dann kommt noch die Karte mit 160 Bytes hinzu, die noch sehr grob ist. Da bleibt am Ende nicht viel übrig. Der jetzige Sketch verwendet ca. 1,575kBytes Arbeitsspeicher.

Vom Flashspeicher
Im Gegensatz zu dem insgesamten Flash Speicher mit 32kB, ist dieser gerade mal mit 12,45kB belegt. Damit liegt nahe, dass Sprites und weitere Daten am besten zur Laufzeit geladen werden. Hier kommt ein Kompromiss zustande über die Lesegeschwindigkeit von Flasch und RAM.
Eine kleine Umstellung und die Byte Array lassen sich aus dem Flashspeicher lesen, wenn diese zur Laufzeigt benötigt werden. Die folgenden Ergebnisse nach dem Kompilieren zeigen den Unterschied zwischen dem Sketch vom letzten Stand mit dem Anlegen der Karte und das gleiche jedoch nach der Umstellung mit PROGMEM.

Ohne PROGMEM

Mit PROGMEM

Weitere Informationen könnt ihr auf der Arduino Seite über PROGMEM erfahren.

Das folgende Code Ausschnitt zeigt die Änderung der Funktionsvariable eines Byte Array ergänzt wird.

// Figur Sprites load from lokal
byte spriteFigureFrontLeft[160] = { …

// Figur Sprites load from flash
const PROGMEM byte spriteFigureFrontLeft[160] = { …

Sobald alle Byte Arrays mit dem Präfix 'const' und 'PROGMEM' erweitert wurden, dürfte der Belegte Speicher deutlich gesunken sein. Ein Byte Array bleibt allerdings immer im Speicher, dass ist der Buffer oder wie im Beispiel 'tempArray' benannt wird aus dem Flash in das Byte Array geladen, das über eine einfache Funktion übertragen wird.

// kopiert den Array Inhalt vom Flashspeicher in den SRAM
void memCopy(byte arrayContent[]) {
  for(byte index = 0; index < 160; index++) {
    tempArray[index] = pgm_read_byte_near(arrayContent + index);
  }
}

Wann ist der Einsatz von PROGMEM Sinnvoll
Alle Funktionsvariablen die nicht zur aktuellen Ausführung verwendet werden, könnten über die Funktion erweitert werden. Also eine Spriteanimation rendert immer nur eines der angelegten Sprites.

Nächster Post: Du kommst hier nicht vorbei (Arduino Esplora, Part 6)

Kommentare

Beliebte Posts aus diesem Blog

Arduino Control (Teil 5) - PWM Signal einlesen

RC Fahrtenregler für Lego Kettenfahrzeug

Angular auf dem Raspberry Pi