Pages: [1]   Go Down
Author Topic: EEPROM I2C communication: RESOLVED  (Read 607 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Newbie
*
Karma: 0
Posts: 9
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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:
#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:
#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.
« Last Edit: July 08, 2013, 08:41:44 am by them_russians » Logged

Offline Offline
Edison Member
*
Karma: 48
Posts: 1636
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 9
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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
Logged

Offline Offline
Edison Member
*
Karma: 48
Posts: 1636
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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

Pete
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 9
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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:
#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);
}
Logged

Offline Offline
Edison Member
*
Karma: 48
Posts: 1636
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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

Pete
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 9
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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:
#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:
#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:
#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!
« Last Edit: July 08, 2013, 08:19:58 am by them_russians » Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 9
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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!
Logged

Pages: [1]   Go Up
Jump to: