# BitMath - Converting Between Long and Bytes (Storing Data on EEPROM)

New question: Can someone help me figure out what I am doing wrong? I want to send a long to my external EEPROM. I store it as a string of bytes by using bitshift operators. Then I want to read these bytes back and reassemble them into a long. My math is not correct - I can reproduce 0 but the other values I generate are all over the place.

Specifically, here is a code snippet I was using to test my math. I take 4 values out of my 1D array of longs and put them into an array of 4 bytes using bit shift. I then try to undo what I did and print out the value.

`````` Serial.println("Data prepared!");
for (i=0; i<4; i++){
Time = TimeVector[i];

Serial.println(Time);

Page = (byte) Time;
Page = (byte) Time >> 8;
Page = (byte) Time >> 16;
Page = (byte) Time >> 24;

Time = 0;
Time = Time | Page;
Time = Time << 8;
Time = Time | Page;
Time = Time << 8;
Time = Time | Page;
Time = Time << 8;
Time = Time | Page;

Serial.println("Reconstructed time: ");
Serial.println(Time);
Serial.println();
``````

I am working with an Arduino DUE, which has two separate I2C buses. I’m using SCL1 and SDA1, both with external pull-up resistors.

I need to store a large amount of data on the EEPROM to be preserved between power cycles. I have an array of bytes whose total size is 4320 bytes and I have what I call a “vector” (not vector in C++ terms) that consists of a single dimensional array of 720 longs for a size 2880 bytes. The EEPROM is the typical 24LC256T and the functions I stole from the Arduino Playground tutorial on I2C EEPROM.

Previously, I posted here about problems with the amount of time it was taking to write to the EEPROM after doing nothing except removing a few Serial.print debugging statements. I’m still not sure what the problem was, but shortly there after the driver for the board disappeared and I couldn’t communicate. I rebooted my PC and re-installed the driver for the DUE and now everything is working like it should.

``````  #include <Wire.h> //I2C library

byte dataArray;
long TimeVector;
int i = 0;
int j = 0;
int k = 0;
byte dataByte = 0;
char timeStr;
long Time = 0;
byte Page;

int rdata = data;
Wire1.write(rdata);
Wire1.endTransmission();
}

// WARNING: address is a page address, 6-bit end will wrap around
// also, data can be maximum of about 30 bytes, because the Wire1 library has a buffer of 32 bytes
void i2c_eeprom_write_page( int deviceaddress, unsigned int eeaddresspage, byte* data, byte length ) {
byte c;
for ( c = 0; c < length; c++)
Wire1.write(data[c]);
Wire1.endTransmission();
}

byte rdata = 0xFF;
Wire1.endTransmission();
return rdata;
}

// maybe let's not read more than 30 or 32 bytes at a time!
Wire1.endTransmission();
int c = 0;
for ( c = 0; c < length; c++ )
}

void setup()
{
Wire1.begin(); // initialise the connection
Serial.begin(9600);
Serial.println("Preparing time data:");
for (i=0; i<720; i++){
TimeVector[i] = i*1000;
}

Serial.println("Data prepared!");
for (i=0; i<4; i++){
Time = TimeVector[i];

Serial.println(Time);

Page = (byte) Time;
Page = (byte) Time >> 8;
Page = (byte) Time >> 16;
Page = (byte) Time >> 24;

Time = 0;
Time = Time | Page;
Time = Time << 8;
Time = Time | Page;
Time = Time << 8;
Time = Time | Page;
Time = Time << 8;
Time = Time | Page;

Serial.println("Reconstructed time: ");
Serial.println(Time);
Serial.println();

i2c_eeprom_write_page(0x50, address, Page, sizeof(Page)); // write to EEPROM
}
}

void loop()
{
{
Time = 0;
for (i = 0; i < 4; ++i){
Time = Time | dataByte;
Time = Time << 8;
}
Serial.println(Time);
}
Serial.println(" ");
delay(2000);

}
``````

Fixed it… this seems to work properly:

``````      Page = Time;
Page = Time >> 8;
Page = Time >> 16;
Page = Time >> 24;

/*   DEBUGGING PRINT OUT
Serial.println("Page bytes: ");
for(j = 0; j < 4; ++j){
Serial.println(Page[j], BIN);
}
Serial.println();
*/
Time = 0;
Time = Time | Page;
Time = Time << 8;
Time = Time | Page;
Time = Time << 8;
Time = Time | Page;
Time = Time << 8;
Time = Time | Page;
``````

You -could- read the long directly from RAM as 4 bytes in a row using a byte pointer.

``````void setup()
{
Serial.begin(9600);

long fourBytes = 0x12345678; // using hex instead of binary

// note that:
// as long as you put them back in the order you get the bytes
// it doesn't matter what order you store them, but low to high
// would make more sense as that is how the long is in RAM

Serial.println( "Page bytes: " );
// here printing the long in high byte to low byte order.
byte *oneByte = ( byte * ) &fourBytes;
oneByte += 3; // points to the high byte first

while ( oneByte >= ( byte * ) &fourBytes )
{
Serial.println( *( oneByte-- ), HEX );
}
Serial.println();
}

void loop() {
}
``````

Definitely do the pointer thing. Also use sizeof(variable) if you want some flexibility.

Thanks, folks!