Because of the way that Arduino puts stuff together, stuff like template definitions should be in a separate file. Could be in a library, or you could just put them under a separate tab in the Arduino sketch. (It is not strictly true that you always need another file for the template stuff. See Footnote.)
Here's how I got started:
In the Arduino IDE, I created a new tab. I named it eetest.h.
I pasted the following from the playground example into the eetest.h tab window:
#include <WProgram.h>
template <class T> int EEPROM_writeAnything(int ee, const T& value)
{
const byte* p = (const byte*)(const void*)&value;
int i;
for (i = 0; i < sizeof(value); i++)
EEPROM.write(ee++, *p++);
return i;
}
template <class T> int EEPROM_readAnything(int ee, T& value)
{
byte* p = (byte*)(void*)&value;
int i;
for (i = 0; i < sizeof(value); i++)
*p++ = EEPROM.read(ee++);
return i;
}
I pasted the following from the playground example into the main sketch tab window. (Note that I had to add WProgram.h, since it defines some Arduino stuff that is needed.)
#include <EEPROM.h>
#include "eetest.h"
struct config_t
{
long alarm;
int mode;
} configuration;
void setup()
{
EEPROM_readAnything(0, configuration);
// ...
}
void loop()
{
// let the user adjust their alarm settings
// let the user adjust their mode settings
// ...
// if they push the "Save" button, save their configuration
if (digitalRead(13) == HIGH)
EEPROM_writeAnything(0, configuration);
}
For me it compiles cleanly with arduino-0022.
When/if you get a clean compile, you can make a test sketch that actually writes and reads something.
For example:
#include <EEPROM.h>
#include "eetest.h"
struct config_t
{
long alarm;
int mode;
} configuration;
void setup()
{
Serial.begin(9600);
configuration.alarm = 12345678;
configuration.mode = 1;
// Write the configuration struct to EEPROM
EEPROM_writeAnything(0, configuration);
}
void loop()
{
// Read and print the contents of EEPROM
EEPROM_readAnything(0, configuration);
Serial.print("alarm = ");Serial.println(configuration.alarm);
Serial.print("mode = ");Serial.println(configuration.mode);
// A "do nothing loop" where your real working code would be
while(1)
;
}
If you get the following output, you may be ready for some "real" work.
[color=#0000ff]alarm = 12345678
mode = 1[/color]
It works for me with arduino-0019 and -0022
Regards,
Dave
Footnote:
You can actually impel Arduino do the "Right Thing" for this particular example by putting some declarative statement(s) before the template stuff in your main sketch tab. (This may not always work.)
For example: Paste the template stuff amd the main sketch stuff from the playground into your main sketch pane. Delete the eetest.h tab
Move the struct definition to a position before the template stuff.
#include <EEPROM.h>
struct config_t
{
long alarm;
int mode;
} configuration;
template <class T> int EEPROM_writeAnything(int ee, const T& value)
{
const byte* p = (const byte*)(const void*)&value;
int i;
for (i = 0; i < sizeof(value); i++)
EEPROM.write(ee++, *p++);
return i;
}
template <class T> int EEPROM_readAnything(int ee, T& value)
{
byte* p = (byte*)(void*)&value;
int i;
for (i = 0; i < sizeof(value); i++)
*p++ = EEPROM.read(ee++);
return i;
}
void setup()
{
Serial.begin(9600);
configuration.alarm = 12345678;
configuration.mode = 1;
EEPROM_writeAnything(0, configuration);
// ...
}
void loop()
{
EEPROM_readAnything(0, configuration);
Serial.print("alarm = ");Serial.println(configuration.alarm);
Serial.print("mode = ");Serial.println(configuration.mode);
while(1)
;
}
Why did I create the separate pane? Because of my habit of putting class definitions and template definitions in files away from my main program. It tends to reduce visual clutter when I am developing (and debugging) the main program. In my opinion, that's the Right Thing do do. That's my style. I'm funny that way.
Maybe the playground example could put stuff in an Arduino-compatible order or, at least, tell people what they have to do to get the example to compile as a complete program. Just a thought