EEPROM I2C Write Anything

This code is used to write any data type (int, float, double, string, char, etc.) to an I2C eeprom. The particular IC this was written for is the 24LC256. This is adapted from some code found at the Arduino website.

This file will hold our read and write functions. Save it as eepromi2c.h

#include <WProgram.h>
#define DEVICE 0x50 //this is the device ID from the datasheet of the 24LC256

//in the normal write anything the eeaddress is incrimented after the writing of each byte. The Wire library does this behind the scenes.

template <class T> int eeWrite(int ee, const T& value)
{
const byte* p = (const byte*)(const void*)&value;
int i;
Wire.beginTransmission(DEVICE);
Wire.send((int)(ee >> 8)); // MSB
Wire.send((int)(ee & 0xFF)); // LSB
for (i = 0; i < sizeof(value); i++)
Wire.send(*p++);
Wire.endTransmission();
return i;
}

template <class T> int eeRead(int ee, T& value)
{
byte* p = (byte*)(void*)&value;
int i;
Wire.beginTransmission(DEVICE);
Wire.send((int)(ee >> 8)); // MSB
Wire.send((int)(ee & 0xFF)); // LSB
Wire.endTransmission();
Wire.requestFrom(DEVICE,sizeof(value));
for (i = 0; i < sizeof(value); i++)
if(Wire.available())
*p++ = Wire.receive();
return i;
}

The following example uses a data structure to better organize variables.


#include <Wire.h>
#include "eepromi2c.h"

struct config
{
long targetLat;
long targetLon;
float fNum;
bool first;
int attempts;
} config;

void setup()
{

Serial.begin(9600);

//config some of the variables during to be saved. 
config.targetLat = 4957127;
config.targetLon = 6743421;
config.first = false;
config.attempts = 30;
config.fNum = 2.23;
eeWrite(0,config);
delay (30);
}

void loop()
{

//change the variables within the strucutre to show the read worked
config.targetLat =0;
config.targetLon = 0;
config.first = true;
config.fNum = 0.0;
config.attempts = 0;


eeRead(0,config);
delay(30);

Serial.print("lat = ");
Serial.println(config.targetLat);
Serial.print("lon =");
Serial.println(config.targetLon);

Serial.print("first");
Serial.println(config.first);

Serial.print("float");
Serial.println(config.fNum);

Serial.print("attempts = ");
Serial.println(config.attempts);

delay(1000);
}


9 comments

  • hi, your code seems to be the code that i need to store a strct data in a 24LC64.

    but it doesn’t run in my nano with the eeprom. i run it in arduino 1.01, changing #include with #include .
    (if i comment the eeWrite ad eeRead lines of the example, the code work well)

    could you verify if anything else if missing?

    best regards, pescadito

    • TheCreator

      Hey pescadito,

      I looked through the code, i did notice that the structure was named config_t when it should have been config. Other than that there are a few other possibilities. In Arduino 1.0 the wire library was changed. In addition, they also changed the naming of the header file from Wprogram.h to Arduino.h . I do not have a nano, and I’m not sure if the hardware would make a difference when all I am using is standard c++ operations and included header files that are unmodified.

      • Hello I am new to this and I’m doing my first steps, your code has saved me, was weighing more than a week trying to save a structure in EEPROM when I mistake not mistake me something else, your code is clean and simply brilliant, perfect thanks

  • Fabricio

    DonĀ“t forget to put Wire.begin(); on the first line of setup()

  • mike powers

    Still having problems with my code. help!

    //Arduino 1.0.4
    //stores values from DHT22 in ext eeprom as doubles
    #include
    #include “eepromi2c.h”
    #include “DHT.h”
    #define DHTPIN 6 //what pin we’re connected to
    #define DHTTYPE DHT22 //DHT 22 (AM2302)
    DHT dht(DHTPIN, DHTTYPE);
    int d = 1000;
    double h;
    double f;
    double t;
    double y=200;

    struct config {
    double fNum; //float fNum;
    double hNum;
    }
    config;

    void setup() {
    dht.begin();
    Wire.begin();
    Serial.begin(9600);
    Serial.flush(); //clears serial buffer
    delay(500);

    for (int x=0; x<=116; x=x+4 ) {

    t = dht.readTemperature();
    config.fNum = (9.0/5.0 * t) + 32.0;
    eeWrite(x,config); //(memory start local, config)

    config.hNum = dht.readHumidity();
    eeWrite(y,config); //(memory start local, config)
    y=y+4;

    delay(d);
    }

    y = 200;
    for (int x=0; x<=116; x=x+4 ) {
    eeRead(x,config);
    delay(30);
    eeRead(y,config);
    delay(30);
    y=y+4;
    results(x);
    }
    }

    void loop() {
    }

    int results(int x) {
    Serial.print(x);
    Serial.print("\t");
    Serial.print(config.fNum, 1);
    Serial.print("\t");
    Serial.println(config.hNum, 1);
    }

  • mike powers

    After modifying the library and my code, it works perfectly. thanks

    //Arduino 1.0.4
    //stores values from DHT22 in ext eeprom as doubles
    #include
    #include “eepromi2c.h”
    #include “DHT.h”
    #define DHTPIN 6 //what pin we’re connected to
    #define DHTTYPE DHT22 //DHT 22 (AM2302)
    DHT dht(DHTPIN, DHTTYPE);
    double d = 20000;
    double h;
    double f;
    double t;
    double y = 0;
    double k = 0;

    struct config {
    double fNum; //float fNum;
    double hNum;
    }
    config;

    void setup() {
    dht.begin();
    Wire.begin();
    Serial.begin(9600);
    Serial.flush(); //clears serial buffer
    delay(1000);
    for (int x=1; x<=30; x++ ) {
    t = dht.readTemperature();
    config.fNum = (9.0/5.0 * t) + 32.0;
    eeWrite(k,config); //(memory start local, config)
    k = k + 4;
    y = 200;
    config.hNum = dht.readHumidity();
    eeWrite(y,config); //(memory start local, config)
    y = y + 4;
    delay(d);
    Serial.print(x);
    Serial.print("\t");
    Serial.print(config.fNum,1);
    Serial.print("\t");
    Serial.println(config.hNum,1);
    }
    }

    void loop() {
    }

  • Hello! I am just starting a project in which I have a use for a small eeprom to hold a small number as a board identifier. I came across this page in my Google search. Does anyone have a python port of this? Can this be compiled and used with python perhaps? Any ideas? Thank you!

    • TheCreator

      Hey John,

      This particular code is for the Arduino hardware platform utilizing I2C protocol. So to answer your second question, no, it will not be interpreted by Python. How exactly are you planing on writing to the EEPROM? Also, what eeprom are you using?

      If you are using the Arduino and python together over a serial connection you could just have your Arduino sketch listen on the serial line for a certain code that python sends to it. Like send “BoardID= xxx” over the serial connection and just have the arduino sketch parse that data, then use the function i provided to save the board number into your eeprom. If you provide hardware specs / and code i can help a little more. good luck.

Leave a Reply

Your email address will not be published. Required fields are marked *