När jag fick min Arduino Due upptäckte jag att den inte har EEPROM vilket kan användas för att spara icke-flyktig data. Vanligtvis på en mikroprocessor så arbetar man med RAM-minnet vilket fungerar bra så länge man inte vill spara data mellan gångerna som processorn startar. Om man vill spara en variabel som ska vara kvar även när processorn förlorar ström behöver man en annan lösning där den vanligaste är att spara ner till EEPROM. På Arduino Due finns tyvärr inte detta minne men den har däremot ett riktigt stort flash-minne som kan konfigureras till att fungera på ett liknande sätt. Jag skrev därför ett bibliotek som gör just detta. Det är tänkt att kunna användas som en rak ersättare till EEPROM. DueFlashStorage är publicerad på Github.
Exempel:
// write the value 123 to address 0
dueFlashStorage.write(0,123);
// read byte at address 0
byte b = dueFlashStorage.read(0);
Eller hela exempelkoden:
/* This example will write 3 bytes to 3 different addresses and print them to the serial monitor.
Try resetting the Arduino Due or unplug the power to it. The values will stay stored. */
#include DueFlashStorage dueFlashStorage;
void setup() {
Serial.begin(115200);
byte b1 = 3;
uint8_t b2 = 1;
dueFlashStorage.write(0,b1);
dueFlashStorage.write(1,b2);
//dueFlashStorage.write(2,b2);
}
void loop() {
/* read from flash at address 0 and 1 and print them */
Serial.print("0:");
Serial.print(dueFlashStorage.read(0));
Serial.print(" 1:");
Serial.print(dueFlashStorage.read(1));
/* read from address 2, increment it, print and then write incremented value back to flash storage */
uint8_t i = dueFlashStorage.read(2)+1;
Serial.print(" 2:");
Serial.print(dueFlashStorage.read(2));
dueFlashStorage.write(2,i);
Serial.println();
delay(1000);
}
Serial monitor:
Men säg att man vill spara undan en hel konfiguration och inte bara några få bytes. Jag skrev biblioteket för att kunna hantera detta också:
// say you want to store a struct with parameters:
struct Configuration {
uint8_t a;
uint8_t b;
int32_t bigInteger;
char* message;
char c;
};
Configuration configuration;
/* then write it to flash like this: */
byte b2[sizeof(Configuration)]; // create byte array to store the struct
memcpy(b2, &configuration, sizeof(Configuration)); // copy the struct to the byte array
dueFlashStorage.write(4, b2, sizeof(Configuration)); // write byte array to flash at address 4
/* and read from flash like this: */
byte* b = dueFlashStorage.readAddress(4); // byte array which is read from flash at adress 4
Configuration configurationFromFlash; // create a temporary struct
memcpy(&configurationFromFlash, b, sizeof(Configuration)); // copy byte array to temporary struct
Se hela koden på Github för ett fungerande exempel.