Dein Arduino Uno ist ein kleines Kraftpaket, aber wie bei jedem Computer hat er begrenzte Ressourcen. Eine der wichtigsten Ressourcen ist der Speicher. Der Arduino Uno hat verschiedene Speichertypen: RAM, Flash und EEPROM. Jeder dient einem anderen Zweck und es ist wichtig zu verstehen, wie sie funktionieren, um dein Arduino-Projekt optimal zu gestalten. In diesem Tutorial tauchen wir tief in diese Speichertypen ein, lernen, wie man den Speicherverbrauch misst, und wie man Variablen und Konstanten strategisch platziert, um das Beste aus deinem Mikrocontroller herauszuholen. Los geht's!
Da wir hier hauptsächlich die Theorie und Anwendung der Speichertypen besprechen, benötigst du für die meisten Beispiele keine speziellen Hardware-Komponenten. Ein Arduino Uno und die Arduino IDE reichen völlig aus!
Da wir keine spezifische Hardware anschließen, gibt es keinen Schaltplan. Wir konzentrieren uns auf die Programmierung und Speicherverwaltung, die unabhängig von externen Komponenten ist.
Hier sind einige Codebeispiele, die die Verwendung von PROGMEM und EEPROM veranschaulichen.
#include <avr/pgmspace.h>
// Statt im RAM, speichern wir diesen Text im Flash-Speicher
const char string_0[] PROGMEM = "Hallo Welt vom Flash-Speicher!";
const char string_1[] PROGMEM = "Dies ist ein zweiter Text im Flash.";
const char string_2[] PROGMEM = "Noch ein Text, um das Prinzip zu zeigen.";
// Array von Zeigern auf die Strings im Flash
const char* const string_table[] PROGMEM = {string_0, string_1, string_2};
void setup() {
Serial.begin(9600);
delay(10); // Warten auf die serielle Verbindung
}
void loop() {
// Lesen des ersten Strings aus dem Flash-Speicher
char buffer[35]; // Puffer muss groß genug sein für den längsten String
strcpy_P(buffer, (char*)pgm_read_word(&(string_table[0]))); // Holen der Adresse des Strings und kopieren ihn
Serial.println(buffer);
delay(1000); // Warte eine Sekunde
}
#include <avr/pgmspace.h>
: Diese Zeile importiert die Bibliothek, die für die Verwendung von PROGMEM
notwendig ist.const char string_0[] PROGMEM = ...
: Hier definieren wir einen String, der nicht im RAM, sondern im Flash-Speicher gespeichert wird. PROGMEM
ist der Schlüssel! Da Flash-Speicher lesbar ist, kann hier Platz gespart werden.strcpy_P(buffer, (char*)pgm_read_word(&(string_table[0])))
: Diese Funktion liest den String aus dem Flash-Speicher und kopiert ihn in den buffer
. Das _P
am Ende der Funktion deutet darauf hin, dass sie für das Lesen aus dem Flash-Speicher gedacht ist (Program Memory).#include <EEPROM.h>
// EEPROM-Adresse, an der wir einen Integer speichern
#define EEPROM_ADDR 0
int myValue;
void setup() {
Serial.begin(9600);
delay(10); // Warten auf die serielle Verbindung
// Lesen des Wertes aus dem EEPROM
myValue = EEPROM.read(EEPROM_ADDR);
Serial.print("Wert aus EEPROM gelesen: ");
Serial.println(myValue);
// Wenn der Wert 255 ist (was bedeutet, dass nichts gespeichert wurde),
// speichern wir einen Startwert
if (myValue == 255) {
myValue = 42; // Ein schöner Startwert
EEPROM.write(EEPROM_ADDR, myValue);
Serial.println("Startwert in EEPROM geschrieben.");
}
// Den Wert um eins erhöhen und wieder speichern
myValue++;
EEPROM.write(EEPROM_ADDR, myValue);
Serial.print("Neuen Wert in EEPROM geschrieben: ");
Serial.println(myValue);
}
void loop() {
delay(5000); // Alle 5 Sekunden wiederholen (nur zum Demonstrieren)
}
#include <EEPROM.h>
: Diese Zeile importiert die Bibliothek, die für die Verwendung des EEPROM notwendig ist.#define EEPROM_ADDR 0
: Hier definieren wir die Adresse im EEPROM, an der wir unseren Wert speichern wollen. Du kannst verschiedene Adressen für verschiedene Variablen verwenden.EEPROM.read(EEPROM_ADDR)
: Liest ein Byte von der angegebenen Adresse im EEPROM.EEPROM.write(EEPROM_ADDR, myValue)
: Schreibt den Wert myValue
(als Byte) an die angegebene Adresse im EEPROM. Beachte: Das EEPROM hat eine begrenzte Anzahl von Schreibzyklen (ca. 100.000). Vermeide also häufiges Schreiben, wenn es nicht unbedingt nötig ist.F()
Makro für Serial.print: Verwende Serial.print(F("Text"));
um Strings, die nur einmal ausgegeben werden, direkt im Flash-Speicher zu speichern und RAM zu sparen.const
für Konstanten: Markiere Variablen, die sich nicht ändern, mit const
. Das hilft dem Compiler, den Speicherverbrauch zu optimieren.int
braucht mehr Speicher als ein byte
.malloc()
und free()
sollten auf dem Arduino vermieden werden, da sie zu Speicherfragmentierung und Instabilität führen können.Du hast gelernt, dass dein Arduino Uno verschiedene Speichertypen hat: RAM (flüchtig, für Variablen), Flash (für dein Programm) und EEPROM (dauerhaft, für Daten). Du hast gelernt, wie du PROGMEM
verwendest, um Strings im Flash-Speicher zu speichern und wie du Daten dauerhaft im EEPROM speichern kannst. Mit diesen Kenntnissen kannst du deine Arduino-Projekte effizienter gestalten und Speicherprobleme vermeiden!