Go Down

Topic: EEPROM I2C communication: RESOLVED (Read 727 times) previous topic - next topic

Jul 03, 2013, 09:19 pm Last Edit: Jul 08, 2013, 03:41 pm by them_russians Reason: 1
Hey guys,

I'm having some trouble with I2C writing/reading to the EEPROM. I am attempting to save data to an external eeprom chip. I have found the following code and am trying to decipher it:

Code: [Select]
#include <Arduino.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;
unsigned int i;

Wire.beginTransmission(DEVICE);
Wire.write((int)(ee >> 8)); // MSB
Wire.write((int)(ee & 0xFF)); // LSB
for (i = 0; i < sizeof(value); i++)
 Wire.write(*p++);
Wire.endTransmission();
return i;
}

template <class T> int eeRead(int ee, T& value)
{
byte* p = (byte*)(void*)&value;
unsigned int i;

Wire.beginTransmission(DEVICE);
Wire.write((int)(ee >> 8)); // MSB
Wire.write((int)(ee & 0xFF)); // LSB
Wire.endTransmission();
Wire.requestFrom(DEVICE,sizeof(value));
for (i = 0; i < sizeof(value); i++)
 if(Wire.available())
   *p++ = Wire.read();
return i;
}


Code: [Select]
#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);
}


However, when i run it, i get this:

lat = 0
lon =0
first1
float0.00
attempts = 0


These are the variable values after they were changed in "void loop". However, since I am doing an eeRead right before my printing lines, shouldnt the values that get printed be the ones that were written to the eeprom in the setup?

Thanks for the advice.

el_supremo

Both of those functions return the number of bytes read or written. First thing to try is to print out both of them.
If they both report the correct number, I'd guess that it is a wiring error.
One thing to also try is an I2C bus scanner to make sure that the EEPROM is detectable on the bus.
http://playground.arduino.cc/Main/I2cScanner

Which Arduino are you using?

Pete


Both of those functions return the number of bytes read or written. First thing to try is to print out both of them.
If they both report the correct number, I'd guess that it is a wiring error.
One thing to also try is an I2C bus scanner to make sure that the EEPROM is detectable on the bus.
http://playground.arduino.cc/Main/I2cScanner

Which Arduino are you using?

Pete


Hey Pete,

I have scanned for the EEPROM and it located it at the location I specified. I also printed both total of bytes out and both the read and write commands show 15 which is expected from the data types declared in the structure. I do not believe that there is wiring error because I was able to use external EEPROM to write/read individual bytes. However, I am looking to write/read structures and so that is why I am trying to figure out this code. The arduino I am using is a Nano v3.1 AT mega328 and the external EEPROM can be found here: https://www.sparkfun.com/products/525

Thanks

el_supremo

You need to put
Wire.begin()
in setup before using the EEPROM.

Pete


You need to put
Wire.begin()
in setup before using the EEPROM.

Pete


Hey Pete, I added the wire.begin() and specified my address as a paramater yet I am still having the same issue of printing the new variable values and not the ones i saved earlier. I will attach an updated version of my code. Do you see anything else that could potentially cause this issue? Thanks!

Code: [Select]
#include <Wire.h>
#include "eepromi2c.h"

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

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

}

void loop()
{
//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);

//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);
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);
}

el_supremo

Your code works for me.
If an I2C scanner sees the address of the EEPROM the code should work.

Pete

#6
Jul 08, 2013, 03:13 pm Last Edit: Jul 08, 2013, 03:19 pm by them_russians Reason: 1

Your code works for me.
If an I2C scanner sees the address of the EEPROM the code should work.

Pete


can you show me what your output was? I ran the following code and found out that my address was 0x50:

Code: [Select]
#include <Wire.h>


void setup()
{
  Wire.begin();

  Serial.begin(9600);
  Serial.println("\nI2C Scanner");
}


void loop()
{
  byte error, address;
  int nDevices;

  Serial.println("Scanning...");

  nDevices = 0;
  for(address = 1; address < 127; address++ )
  {
    // The i2c_scanner uses the return value of
    // the Write.endTransmisstion to see if
    // a device did acknowledge to the address.
    Wire.beginTransmission(address);
    error = Wire.endTransmission();

    if (error == 0)
    {
      Serial.print("I2C device found at address 0x");
      if (address<16)
        Serial.print("0");
      Serial.print(address,HEX);
      Serial.println("  !");

      nDevices++;
    }
    else if (error==4)
    {
      Serial.print("Unknow error at address 0x");
      if (address<16)
        Serial.print("0");
      Serial.println(address,HEX);
    }   
  }
  if (nDevices == 0)
    Serial.println("No I2C devices found\n");
  else
    Serial.println("done\n");

  delay(5000);           // wait 5 seconds for next scan
}


Then I used the following header file:

Code: [Select]
#include <Arduino.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;
unsigned int i;

Wire.beginTransmission(DEVICE);
Wire.write((int)(ee >> 8)); // MSB
Wire.write((int)(ee & 0xFF)); // LSB
for (i = 0; i < sizeof(value); i++)
  Wire.write(*p++);
Wire.endTransmission();
return i;
}

template <class T> int eeRead(int ee, T& value)
{
byte* p = (byte*)(void*)&value;
unsigned int i;

Wire.beginTransmission(DEVICE);
Wire.write((int)(ee >> 8)); // MSB
Wire.write((int)(ee & 0xFF)); // LSB
Wire.endTransmission();
Wire.requestFrom(DEVICE,sizeof(value));
for (i = 0; i < sizeof(value); i++)
  if(Wire.available())
    *p++ = Wire.read();
return i;
}


And the following main code:
Code: [Select]
#include <Wire.h>
#include "eepromi2c.h"

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

void setup()
{
Wire.begin(0x50);
Serial.begin(9600);

}

void loop()
{
//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);

//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);
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);
}


My serial monitor still printed:

lat = 0
lon =0
first1
float0.00
attempts = 0

I believe that this is wrong since we are not reading the values from the eeprom that we printed to there initially.


Thanks!


Your code works for me.
If an I2C scanner sees the address of the EEPROM the code should work.

Pete


I finally figured out what I was doing wrong. For some reason I removed the delay after my write command so I dont think it was getting a chance to finish the writing to the chip. Thanks for all of your help Pete!

Go Up