zurück

EEPROM beim Arduino

12.01.2019

Der ATmega-Controller des Arduino enthält ein EEPROM (Electrically Erasable Programmable Readonly Memory), d.h. einen elektrisch lösch- und schreibbarer Halbleiterspeicher. Daten in diesem Speicher bleiben auch dann erhalten, wenn der Arduino ausgeschaltet wird, allerdings ist die Programmierzeit ist relativ lang und die Anzahl der Programmierzyklen begrenzt.
Die Speicherzellen des EEPROMs speichern jeweils ein Byte, wobei das EEPROM des Arduino Uno eine Speicherkapazität von 1024 Bytes besitzt.

In der Arduino-Programmierumgebung ist eine Library für den EEPROM-Zugriff schon standardmäßig enthalten und kann damit leicht verwendet werden.

Ex. I: EEPROM mit Zufallswerten füllen

#include <EEPROM.h>

// Size of the EEPROM
#define EESIZE 1024

int randomValue;

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

    Serial.println("Writing...");
    for (int i=0; i<EESIZE; i++) {
        randomValue = random(255);
        EEPROM.write(i, randomValue);
    }

    Serial.println("Reading...");
    for (int i=0; i<EESIZE; i++) {
        randomValue = EEPROM.read(i);
        Serial.print(String(i) + ": " + String(randomValue));
    }
}

void loop()
{
}

Ex. II: Lesen und Schreiben von Float oder Strings

#include <EEPROM.h>

void setup()
{
    float val1 = 123.456, val2;
    char Hello[] = "Hello World!", Buffer[100] = {0};
    int address = 0; // EEPROM starting address

    Serial.begin(9600);

    EEPROM.put(address, val1); // writing float value
    address += sizeof(float); // add size of float value

    EEPROM.put(address, Hello); // writing string value
    address = 0; // reset address

    // read data
    EEPROM.get(address, val2);
    Serial.println(val2, 3);
    address += sizeof(float);

    EEPROM.get(address, Buffer);
    Serial.println(Buffer);

    // Hexdump of EEPROM
    for (int i=0; i<(sizeof(float)+sizeof(Hello)); i++)
        Serial.println(EEPROM[i], HEX);
    }

void loop()
{
}

Ex. III: Beispiel mit blinkender LED

In diesem Beispiel wird die Blink-Frequenz einer LEDs gespeichert und beim reset des Arduino wieder ausgelesen und somit dauerhaft gespeichert.

Aufbau der Schaltung

Aufbau der Schaltung auf dem Breadboard

Sketch

#include <EEPROM.h>

#define PIN_LED 8
#define PIN_BUTTON 6

// signature/mark to recognize if the value fits to this sketch (choose whatever you what)
#define EEPROM_VALUE_TYPE 8371

// EEPROM address to save the value to
#define EEPROM_VALUE_ADDR 0

volatile unsigned long lastButtonPressed = 0, lastBlinkAction = 0;
const unsigned long debounceInterval = 100; // in milliseconds
int blinkDelay = 50;
byte ledStatus = LOW;

void setup()
{
    pinMode(PIN_LED, OUTPUT);
    pinMode(PIN_BUTTON, INPUT_PULLUP);
    getFromEeprom();
}

void loop()
{
    if (lastBlinkAction + blinkDelay < millis()) {
        lastBlinkAction = millis();
        ledStatus++;
        ledStatus %= 2;
        digitalWrite(PIN_LED, ledStatus);
    }

    if (lastButtonPressed + debounceInterval < millis()) {
        lastButtonPressed = millis();
        if (digitalRead(PIN_BUTTON) == LOW) {
            blinkDelay *= 2;
            if (blinkDelay > 1500) {
                blinkDelay = 50;
            }
            saveToEeprom(blinkDelay);
        }
    }
}

void saveToEeprom(int value)
{
    int addr = EEPROM_VALUE_ADDR;

    EEPROM.put(addr, EEPROM_VALUE_TYPE);
    addr += sizeof(EEPROM_VALUE_TYPE);

    EEPROM.put(addr, value);
    addr += sizeof(value);
}

void getFromEeprom()
{
    int type = 0, addr = EEPROM_VALUE_ADDR;

    EEPROM.get(addr, type);
    if (type != EEPROM_VALUE_TYPE) {
        // maybe data from another sketch
        return;
    }
    addr += sizeof(EEPROM_VALUE_TYPE);

    EEPROM.get(addr, blinkDelay);
}