writing long number to external EEPROM

I'm using an external EEPROM for storing data for my app using this code:

void writeEEPROM(int deviceaddress, unsigned int eeaddress, byte data ) {
  Wire.beginTransmission(deviceaddress);
  Wire.write((int)(eeaddress >> 8));   // MSB
  Wire.write((int)(eeaddress & 0xFF)); // LSB
  Wire.write(data);
  Wire.endTransmission();
  delay(5);}
byte readEEPROM(int deviceaddress, unsigned int eeaddress ) {
  byte rdata = 0xFF;
  Wire.beginTransmission(deviceaddress);
  Wire.write((int)(eeaddress >> 8));   // MSB
  Wire.write((int)(eeaddress & 0xFF)); // LSB
  Wire.endTransmission();
  Wire.requestFrom(deviceaddress,1);
  if (Wire.available()) rdata = Wire.read();
  return rdata;
  }

So far it works fine, because I only needed to store bytes.
But now I want to store time in seconds, so I need to store a long.
I've found EEPROMWritelong and tried to use it for my external EEPROM:

void EEPROMWritelong(int deviceaddress, unsigned int eeaddress, long value) {
  Wire.beginTransmission(deviceaddress);
  byte four = (value & 0xFF);
  byte three = ((value >> 8) & 0xFF);
  byte two = ((value >> 16) & 0xFF);
  byte one = ((value >> 24) & 0xFF);
  Wire.write(eeaddress, four);
  Wire.write(eeaddress + 1, three);
  Wire.write(eeaddress + 2, two);
  Wire.write(eeaddress + 3, one);
  Wire.endTransmission();
  delay(5);}
long EEPROMReadlong(int deviceaddress, long eeaddress) {
  Wire.beginTransmission(deviceaddress);
  long four = Wire.read(address);
  long three = Wire.read(address + 1);
  long two = Wire.read(address + 2);
  long one = Wire.read(address + 3);
  return ((four << 0) & 0xFF) + ((three << 8) & 0xFFFF) + ((two << 16) & 0xFFFFFF) + ((one << 24) & 0xFFFFFFFF);
  }

But this gives an error:

call of overloaded 'write(unsigned int&, byte&)' is ambiguous

Can someone explain to me what this means, and how to solve it?

If you just use EEPROM.put() and EEPROM.get() you're done :wink:
Sorry!

septillion:
If you just use EEPROM.put() and EEPROM.get() you're done :wink:

How can I persuade EEPROM to work with external EEPROMs?

Why do I always seem to miss the external part! :disappointed_relieved: Sorry! But, in my defense, you could have a look at how EEPROM.put() and EEPROM.get() do it :roll_eyes:

So far it works fine, because I only needed to store bytes.

You mean bytes like one, two, three, and four?

PaulS:
You mean bytes like one, two, three, and four?

No, sorry for the confusion, but I meant numbers from 0 to 254.

Coos:
No, sorry for the confusion, but I meant numbers from 0 to 254.

Since those values are all byte sized, I don't see the issue. Your second code breaks the long into 4 bytes. Write the 4 bytes, one at a time, just like you write the one byte.

PaulS:
Since those values are all byte sized, I don't see the issue. Your second code breaks the long into 4 bytes. Write the 4 bytes, one at a time, just like you write the one byte.

Then why doesn't my second code compile?

Her is my entire code:

#include "Wire.h"
#define EEPROM_DEVICE_ADDRESS 0x50

unsigned int EEPROM_ADDRESS = 0;

void setup() {
  Wire.begin();
  Serial.begin(9600);
  //  writeEEPROM(EEPROM_DEVICE_ADDRESS, EEPROM_ADDRESS, 123);
  EEPROMWritelong(EEPROM_DEVICE_ADDRESS, 0, 43140);
 }
void writeEEPROM(int deviceaddress, unsigned int eeaddress, byte data ) {
  Wire.beginTransmission(deviceaddress);
  Wire.write((int)(eeaddress >> 8));   // MSB
  Wire.write((int)(eeaddress & 0xFF)); // LSB
  Wire.write(data);
  Wire.endTransmission();
  delay(5);
  }
byte readEEPROM(int deviceaddress, unsigned int eeaddress ) {
  byte rdata = 0xFF;
  Wire.beginTransmission(deviceaddress);
  Wire.write((int)(eeaddress >> 8));   // MSB
  Wire.write((int)(eeaddress & 0xFF)); // LSB
  Wire.endTransmission();
  Wire.requestFrom(deviceaddress,1);
  if (Wire.available()) rdata = Wire.read();
  return rdata;
  }
void EEPROMWritelong(int deviceaddress, unsigned int address, long value) {
  Wire.beginTransmission(deviceaddress);
  byte four = (value & 0xFF);
  byte three = ((value >> 8) & 0xFF);
  byte two = ((value >> 16) & 0xFF);
  byte one = ((value >> 24) & 0xFF);
  Wire.write(address, four);
  Wire.write(address + 1, three);
  Wire.write(address + 2, two);
  Wire.write(address + 3, one);
  Wire.endTransmission();
  delay(5);
  }
long EEPROMReadlong(int deviceaddress, long address) {
  Wire.beginTransmission(deviceaddress);
  long four = Wire.read(address);
  long three = Wire.read(address + 1);
  long two = Wire.read(address + 2);
  long one = Wire.read(address + 3);
  return ((four << 0) & 0xFF) + ((three << 8) & 0xFFFF) + ((two << 16) & 0xFFFFFF) + ((one << 24) & 0xFFFFFFFF);
  }

void loop() {
  Serial.println(readEEPROM(EEPROM_DEVICE_ADDRESS, EEPROM_ADDRESS), DEC);
  delay(1000); // every second

}

If you're uncomfortable with bit-shifting, you could use a union:

union {
   byte val[sizeof(long)];
   long number;
} myUnion;

// ...some code...

   int i;
   long valueToSave = 123L;

   myUnion.number = valueToSave;   // Shove into the union...
   for (i = 0; i < sizeof(long); i++){
      Wire.write(baseAddress + i, myUnion.val[i]);   // Assume baseAddress set somewhere...
   }

Reading the data back just reverses the process.

Look at your first snippet of code. How many statements does it take to write ONE byte of data to the external EEPROM?

Look at your second snippet. How many statements are you using to write 4 bytes of data?

If the answer to the first question is n, and the answer to the second question is not 4 times n, then the second code is obviously wrong.

Since you have working code for writing one byte, the smart thing to do, after breaking the long into 4 bytes, is to call that function 4 times.

Thanks Paul, for pointing me in the right direction.
I guess my real problem is that I don't really know what I'm doing, but I think I've got it now:

void EEPROMWritelong(int deviceaddress, unsigned int address, long data) {
  Wire.beginTransmission(deviceaddress);
  byte splitData[4] = {(data & 0xFF),
                       ((data >> 8) & 0xFF),
                       ((data >> 16) & 0xFF),
                       ((data >> 24) & 0xFF)};
  Wire.write((int)(address >> 8));   // MSB
  Wire.write((int)(address & 0xFF)); // LSB
  for (byte x = 0; x < 4; x++){
    Wire.write(splitData[x]);
  }
  Wire.endTransmission();
  delay(5);
}
long EEPROMReadlong(int deviceaddress, long address) {
  long joinData[4];
  for (byte x = 0; x<4; x++){
    byte rdata = 0xFF;
    Wire.beginTransmission(deviceaddress);
    Wire.write((int)((address + x) >> 8));   // MSB
    Wire.write((int)((address + x) & 0xFF)); // LSB
    Wire.endTransmission();
    Wire.requestFrom(deviceaddress,1);
    if (Wire.available()) joinData[x] = Wire.read();
  }
  return ((joinData[0] << 0) & 0xFF) + ((joinData[1] << 8) & 0xFFFF) + ((joinData[2] << 16) & 0xFFFFFF) + ((joinData[3] << 24) & 0xFFFFFFFF);
}