i2c EEPROM using extEEPROM library

I'm trying to write to external eeprom using the extEEPROM library. In the eeWRITE function I cannot get the last three bytes to write, the following is what I get on the monitor

Writing...
data[0]@write = 1100101
data[1]@write = 0
data[2]@write = 0
data[3]@write = 0
writing[0] = 1100101
writing[1] = 0
writing[2] = 0
writing[3] = 0
totalCOUNTS @ write = 234597

I have exhausted my knowledge base and would appreciate your help
Attached is the complete code.

Thanks
Bill

//Test extEEPROM library.
//Writes the EEPROM full of 32-bit integers and reads them back to verify.
//Wire a button from digital pin 6 to ground, this is used as a start button
//so the sketch doesn't do unnecessary EEPROM writes every time it's reset.
//Jack Christensen 09Jul2014
//Paolo Paolucci 17Mar2016 (fix 28Jun2017)
//2/2/2018 - Modified by WJL for testing

#include <extEEPROM.h>    //https://github.com/PaoloP74/extEEPROM

//One 24LC256 EEPROMs on the bus
const uint32_t totalKBytes = 32;         //for read and write test functions
extEEPROM eep(kbits_256, 1, 64, 0x50);         //device size, number of devices, page size

uint8_t data[4];

int RAIN = 2;
int RAIN_C;             //Rain counts stored in EEPROM and sent to xbee
int COUNT;
int lastCOUNT;
uint32_t totalCOUNTS;
int reset_rain = 9;  
int reset_rain_counter;
uint8_t btst[4];
uint32_t addr;

void setup(void)
{
  Serial.begin(115200);
  uint8_t eepStatus = eep.begin(eep.twiClock400kHz);   //go fast!

  pinMode(RAIN , INPUT_PULLUP);
  pinMode(reset_rain , INPUT_PULLUP);
  
  if (eepStatus) 
  {
    Serial.print(F("extEEPROM.begin() failed, status = "));
    Serial.println(eepStatus);
    while (1);
  }
  Serial.println("FILE NAME = WJL_eepromTest");

  eeRead();
  Serial.print("totalCOUNTS[]@setup = ");Serial.println(totalCOUNTS);
}

void loop(void)
{
  //Serial.println("STARTING");
  reset_rain_counter = digitalRead(reset_rain);
  if (reset_rain_counter == LOW)
  {
    Serial.println(reset_rain_counter);
    reset_counter();
  }
  COUNT = digitalRead(RAIN);
  if (COUNT != lastCOUNT)
  {
    if (COUNT == LOW)
    {
      totalCOUNTS = totalCOUNTS + 1;
      Serial.print("TOTAL COUNTS@COUNT = ");Serial.println(totalCOUNTS);
      eeWrite();
      delay(200);
    }
    else
    {
    }
    delay(50);
  }
  lastCOUNT = COUNT;  
}


//write test data (32-bit integers) to eeprom, "chunk" bytes at a time
void eeWrite()
{
  Serial.println(F("Writing..."));

  data[0] = (totalCOUNTS & 0xFF);
  Serial.print("data[0]@write = ");Serial.println(data[0],BIN);
  data[1] = (totalCOUNTS & 0xFF >> 8);
  Serial.print("data[1]@write = ");Serial.println(data[1],BIN);
  data[2] = (totalCOUNTS & 0xFF >> 16);
  Serial.print("data[2]@write = ");Serial.println(data[2],BIN);
  data[3] = (totalCOUNTS & 0xFF >> 24);
  Serial.print("data[3]@write = ");Serial.println(data[3],BIN);

  eep.write(0, data[0], 1);
  Serial.print("writing[0] = ");Serial.println(data[0],BIN);
  eep.write(1, data[1], 1);
  Serial.print("writing[1] = ");Serial.println(data[1],BIN);
  eep.write(2, data[2], 1);
  Serial.print("writing[2] = ");Serial.println(data[2],BIN);
  eep.write(3, data[3], 1);
  Serial.print("writing[3] = ");Serial.println(data[3],BIN);
 
    
  Serial.print("totalCOUNTS @ write = ");Serial.println(totalCOUNTS); 
}

//read test data (32-bit integers) from eeprom, "chunk" bytes at a time
void eeRead()
{
  Serial.println(F("Reading..."));

  for(addr = 0;addr < 4; addr++)
  {
    eep.read(addr, btst, 4);
  }
    Serial.print("btst([0] = ");Serial.println(btst[0],BIN);
    Serial.print("btst([1] = ");Serial.println(btst[1],BIN);
    Serial.print("btst([2] = ");Serial.println(btst[2],BIN);
    Serial.print("btst([3] = ");Serial.println(btst[3],BIN);
    
    totalCOUNTS = uint32_t(btst[0]) | uint32_t(btst[1] << 8) | uint32_t(btst[2] << 16) | uint32_t (btst[3] <<24);
    Serial.print("totalCOUNTS@read = ");Serial.println(totalCOUNTS);
}

void reset_counter()
{
  Serial.println("AT RESET COUNTER");
  totalCOUNTS = 234567;
  Serial.print("totalCOUNTS = ");Serial.println(totalCOUNTS,BIN);
  eeWrite();
  delay(2000);
}

totalCOUNTS & 0xFF >> 8

Based on C operator precedence... you're rightshifting 0xFF by 8 bits - so it's now 0. Anything bitwise and'ed with 0 is 0.

(totalCOUNTS >>8) & 0xFF

is what you wanted - bitshift the what you're starting with, then bitwise and it with 0xFF.

Similarly, casting AFTER shifting might be a problem:

  totalCOUNTS = uint32_t(btst[0]) | uint32_t(btst[1] << 8) | uint32_t(btst[2] << 16) | uint32_t (btst[3] << 24);

If you shift a byte more than 8 bits you will end up with 0. Cast the byte to uint32_t first, then shift:

  totalCOUNTS = (uint32_t (btst[0])) | (uint32_t(btst[1]) << 8) | (uint32_t (btst[2]) << 16) | (uint32_t (btst[3]) << 24);

Another way to write it that doesn't require casts:

  totalCOUNTS = btst[3];
    totalCOUNTS = (totalCOUNTS << 8) | btst[2];
    totalCOUNTS = (totalCOUNTS << 8) | btst[1];
    totalCOUNTS = (totalCOUNTS << 8) | btst[0];
1 Like

I recommend you turn up the warning level in Preferences so you would see the warnings that will let you know that your shift operations are a problem:

Build options changed, rebuilding all
/Users/john/Documents/Arduino/sketch_dec10a/sketch_dec10a.ino: In function 'void eeWrite()':
/Users/john/Documents/Arduino/sketch_dec10a/sketch_dec10a.ino:84:36: warning: right shift count >= width of type
   data[2] = (totalCOUNTS & 0xFF >> 16);
                                    ^
/Users/john/Documents/Arduino/sketch_dec10a/sketch_dec10a.ino:86:36: warning: right shift count >= width of type
   data[3] = (totalCOUNTS & 0xFF >> 24);
                                    ^
/Users/john/Documents/Arduino/sketch_dec10a/sketch_dec10a.ino:89:22: warning: invalid conversion from 'uint8_t {aka unsigned char}' to 'byte* {aka unsigned char*}' [-fpermissive]
   eep.write(0, data[0], 1);
                      ^
In file included from /Users/john/Documents/Arduino/sketch_dec10a/sketch_dec10a.ino:9:0:
/Users/john/Documents/Arduino/libraries/extEEPROM/extEEPROM.h:96:7: note: initializing argument 2 of 'byte extEEPROM::write(long unsigned int, byte*, unsigned int)'
  byte write(unsigned long addr, byte *values, unsigned int nBytes);
       ^
/Users/john/Documents/Arduino/sketch_dec10a/sketch_dec10a.ino:91:22: warning: invalid conversion from 'uint8_t {aka unsigned char}' to 'byte* {aka unsigned char*}' [-fpermissive]
   eep.write(1, data[1], 1);
                      ^
In file included from /Users/john/Documents/Arduino/sketch_dec10a/sketch_dec10a.ino:9:0:
/Users/john/Documents/Arduino/libraries/extEEPROM/extEEPROM.h:96:7: note: initializing argument 2 of 'byte extEEPROM::write(long unsigned int, byte*, unsigned int)'
  byte write(unsigned long addr, byte *values, unsigned int nBytes);
       ^
/Users/john/Documents/Arduino/sketch_dec10a/sketch_dec10a.ino:93:22: warning: invalid conversion from 'uint8_t {aka unsigned char}' to 'byte* {aka unsigned char*}' [-fpermissive]
   eep.write(2, data[2], 1);
                      ^
In file included from /Users/john/Documents/Arduino/sketch_dec10a/sketch_dec10a.ino:9:0:
/Users/john/Documents/Arduino/libraries/extEEPROM/extEEPROM.h:96:7: note: initializing argument 2 of 'byte extEEPROM::write(long unsigned int, byte*, unsigned int)'
  byte write(unsigned long addr, byte *values, unsigned int nBytes);
       ^
/Users/john/Documents/Arduino/sketch_dec10a/sketch_dec10a.ino:95:22: warning: invalid conversion from 'uint8_t {aka unsigned char}' to 'byte* {aka unsigned char*}' [-fpermissive]
   eep.write(3, data[3], 1);
                      ^
In file included from /Users/john/Documents/Arduino/sketch_dec10a/sketch_dec10a.ino:9:0:
/Users/john/Documents/Arduino/libraries/extEEPROM/extEEPROM.h:96:7: note: initializing argument 2 of 'byte extEEPROM::write(long unsigned int, byte*, unsigned int)'
  byte write(unsigned long addr, byte *values, unsigned int nBytes);
       ^
/Users/john/Documents/Arduino/sketch_dec10a/sketch_dec10a.ino: In function 'void eeRead()':
/Users/john/Documents/Arduino/sketch_dec10a/sketch_dec10a.ino:116:82: warning: left shift count >= width of type
   totalCOUNTS = uint32_t(btst[0]) | uint32_t(btst[1] << 8) | uint32_t(btst[2] << 16) | uint32_t (btst[3] << 24);
                                                                                  ^
/Users/john/Documents/Arduino/sketch_dec10a/sketch_dec10a.ino:116:109: warning: left shift count >= width of type
   totalCOUNTS = uint32_t(btst[0]) | uint32_t(btst[1] << 8) | uint32_t(btst[2] << 16) | uint32_t (btst[3] << 24);
                                                                                                             ^
Archiving built core (caching) in: /var/folders/cs/p6yz0z1m8xj9lf0059b_lzw00000gn/T/arduino_cache_599162/core/core_arduino_avr_uno_c6119716457e3f542715c34cf645983e.a
Sketch uses 6080 bytes (18%) of program storage space. Maximum is 32256 bytes.
Global variables use 753 bytes (36%) of dynamic memory, leaving 1295 bytes for local variables. Maximum is 2048 bytes.

Thanks for replys
Dr Wasser; your post fixed my first problem.
I added the changes suggested by John but cant get read to work.

I have included the latest code and this is what I am getting on the monitor.
The code is now writing correctly to eeprom but it is not reading it correctly

FILE NAME = WJL_eepromTest // I reset pro mini
Reading...
btst([0] = 1101100
btst([1] = 100000
btst([2] = 1101001
btst([3] = 1110011
totalCOUNTS@read = 1814063475
totalCOUNTS[]@setup = 1814063475

0 //I pulled pin 9 low to go to reset_counter()
AT RESET COUNTER
totalCOUNTS = 111001010001000111
Writing...
data[0]@write = 1000111
data[1]@write = 10010100
data[2]@write = 11
data[3]@write = 0
writing[0] = 1000111
writing[1] = 10010100
writing[2] = 11
writing[3] = 0
totalCOUNTS @ write = 234567

FILE NAME = WJL_eepromTest //reset again to see what go writted.
Reading...
btst([0] = 1101100
btst([1] = 100000
btst([2] = 1101001
btst([3] = 1110011
totalCOUNTS@read = 1814063475
totalCOUNTS[]@setup = 1814063475

Thanks again for your help

Bill

//Test extEEPROM library.
//Writes the EEPROM full of 32-bit integers and reads them back to verify.
//Wire a button from digital pin 6 to ground, this is used as a start button
//so the sketch doesn't do unnecessary EEPROM writes every time it's reset.
//Jack Christensen 09Jul2014
//Paolo Paolucci 17Mar2016 (fix 28Jun2017)
//2/2/2018 - Modified by WJL for testing

#include <extEEPROM.h>    //https://github.com/PaoloP74/extEEPROM

//One 24LC256 EEPROMs on the bus
const uint32_t totalKBytes = 32;         //for read and write test functions
extEEPROM eep(kbits_256, 1, 64, 0x50);         //device size, number of devices, page size

int RAIN = 2;
int RAIN_C;             //Rain counts stored in EEPROM and sent to xbee
int COUNT;
int lastCOUNT;
uint32_t totalCOUNTS;
int reset_rain = 9;  
int reset_rain_counter;
byte btst[4];
byte data[4];
uint32_t addr;

void setup(void)
{
  Serial.begin(115200);
  uint8_t eepStatus = eep.begin(eep.twiClock400kHz);   //go fast!

  pinMode(RAIN , INPUT_PULLUP);
  pinMode(reset_rain , INPUT_PULLUP);
  
  if (eepStatus) 
  {
    Serial.print(F("extEEPROM.begin() failed, status = "));
    Serial.println(eepStatus);
    while (1);
  }
  Serial.println("FILE NAME = WJL_eepromTest");

  eeRead();
  Serial.print("totalCOUNTS[]@setup = ");Serial.println(totalCOUNTS);
}

void loop(void)
{
  //Serial.println("STARTING");
  reset_rain_counter = digitalRead(reset_rain);
  if (reset_rain_counter == LOW)
  {
    Serial.println(reset_rain_counter);
    reset_counter();
  }
  COUNT = digitalRead(RAIN);
  if (COUNT != lastCOUNT)
  {
    if (COUNT == LOW)
    {
      totalCOUNTS = totalCOUNTS + 1;
      Serial.print("TOTAL COUNTS@COUNT = ");Serial.println(totalCOUNTS);
      eeWrite();
      delay(200);
    }
    else
    {
    }
    delay(50);
  }
  lastCOUNT = COUNT;  
}


//write test data (32-bit integers) to eeprom, "chunk" bytes at a time
void eeWrite()
{
  Serial.println(F("Writing..."));

  data[0] = (totalCOUNTS & 0xFF);
  Serial.print("data[0]@write = ");Serial.println(data[0],BIN);
  data[1] = ((totalCOUNTS >> 8) & 0xFF);
  Serial.print("data[1]@write = ");Serial.println(data[1],BIN);
  data[2] = ((totalCOUNTS >>16)& 0xFF);
  Serial.print("data[2]@write = ");Serial.println(data[2],BIN);
  data[3] = ((totalCOUNTS >> 24)& 0xFF);
  Serial.print("data[3]@write = ");Serial.println(data[3],BIN);

  eep.write(0, data, 1);
  
  Serial.print("writing[0] = ");Serial.println(data[0],BIN);
  eep.write(1, data[1], 1);
  Serial.print("writing[1] = ");Serial.println(data[1],BIN);
  eep.write(2, data[2], 1);
  Serial.print("writing[2] = ");Serial.println(data[2],BIN);
  eep.write(3, data[3], 1);
  Serial.print("writing[3] = ");Serial.println(data[3],BIN);
 
    
  Serial.print("totalCOUNTS @ write = ");Serial.println(totalCOUNTS); 
}

//read test data (32-bit integers) from eeprom, "chunk" bytes at a time
void eeRead()
{
  Serial.println(F("Reading..."));

  for(addr = 0;addr < 4; addr++)
  {
    eep.read(addr, btst, 4);
  }
    Serial.print("btst([0] = ");Serial.println(btst[0],BIN);
    Serial.print("btst([1] = ");Serial.println(btst[1],BIN);
    Serial.print("btst([2] = ");Serial.println(btst[2],BIN);
    Serial.print("btst([3] = ");Serial.println(btst[3],BIN);
    
    //totalCOUNTS = (uint32_t(btst[3])) | (uint32_t(btst[3]) << 8) |( uint32_t(btst[1]) << 16) | (uint32_t (btst[0]) <<24);
    totalCOUNTS = btst[0];
    totalCOUNTS = (totalCOUNTS << 8) | btst[1];
    totalCOUNTS = (totalCOUNTS << 8) | btst[2];
    totalCOUNTS = (totalCOUNTS << 8) | btst[3]; 
    Serial.print("totalCOUNTS@read = ");Serial.println(totalCOUNTS);
}

void reset_counter()
{
  Serial.println("AT RESET COUNTER");
  totalCOUNTS = 234567;
  Serial.print("totalCOUNTS = ");Serial.println(totalCOUNTS,BIN);
  eeWrite();
  delay(2000);
}

Again, TURN UP YOUR WARNING LEVEL. Your code still has warnings:

/Users/john/Documents/Arduino/sketch_dec10a/sketch_dec10a.ino:91:22: warning: invalid conversion from 'byte {aka unsigned char}' to 'byte* {aka unsigned char*}' [-fpermissive]
   eep.write(1, data[1], 1);
                      ^


/Users/john/Documents/Arduino/sketch_dec10a/sketch_dec10a.ino:93:22: warning: invalid conversion from 'byte {aka unsigned char}' to 'byte* {aka unsigned char*}' [-fpermissive]
   eep.write(2, data[2], 1);
                      ^


/Users/john/Documents/Arduino/sketch_dec10a/sketch_dec10a.ino:95:22: warning: invalid conversion from 'byte {aka unsigned char}' to 'byte* {aka unsigned char*}' [-fpermissive]
   eep.write(3, data[3], 1);
                      ^

If you look at lines 88-96...

  eep.write(0, data, 1);
  
  Serial.print("writing[0] = ");Serial.println(data[0],BIN);
  eep.write(1, data[1], 1);
  Serial.print("writing[1] = ");Serial.println(data[1],BIN);
  eep.write(2, data[2], 1);
  Serial.print("writing[2] = ");Serial.println(data[2],BIN);
  eep.write(3, data[3], 1);
  Serial.print("writing[3] = ");Serial.println(data[3],BIN);

Note that if you changed 'data' to 'data[0]' in line 88 you would get a warning about that, too. You can't interchange 'byte' and 'byte pointer' because they are two different things.

The eep.write() function you are using takes a byte pointer and number of bytes. You COULD just say:
eep.write(0, data, 4); and write all four in one call.

If you really want to write them each separately, you need to generate the address of each byte. The way to express that is:

   eep.write(2, &data[0], 1);
   eep.write(2, &data[1], 1);
   eep.write(2, &data[2], 1);
   eep.write(2, &data[3], 1);

OR

   eep.write(2, data+0, 1);
   eep.write(2, data+1, 1);
   eep.write(2, data+2, 1);
   eep.write(2, data+3, 1);

Your syntax is a little confused between your functions and the underlying library functions.
For example

eep.write(1, data[1], 1)

should be

 eep.write(1, data[1]);

On the read side

don't use the block read within the for loop

for(addr = 0;addr < 4; addr++)
  {
    eep.read(addr, btst, 4);
  }

instead

for(addr = 0;addr < 4; addr++)
  {
    btst[addr] = eep.read(addr);
  }

Finally, the byte order in your reconstruction is wrong

totalCOUNTS = btst[3];
    totalCOUNTS = (totalCOUNTS << 8) | btst[2];
    totalCOUNTS = (totalCOUNTS << 8) | btst[1];
    totalCOUNTS = (totalCOUNTS << 8) | btst[0]; 
    Serial.print("totalCOUNTS@read = ");Serial.println(totalCOUNTS);
//Test extEEPROM library.
//Writes the EEPROM full of 32-bit integers and reads them back to verify.
//Wire a button from digital pin 6 to ground, this is used as a start button
//so the sketch doesn't do unnecessary EEPROM writes every time it's reset.
//Jack Christensen 09Jul2014
//Paolo Paolucci 17Mar2016 (fix 28Jun2017)
//2/2/2018 - Modified by WJL for testing

#include <extEEPROM.h>    //https://github.com/PaoloP74/extEEPROM

//One 24LC256 EEPROMs on the bus
const uint32_t totalKBytes = 32;         //for read and write test functions
extEEPROM eep(kbits_256, 1, 64, 0x50);         //device size, number of devices, page size

int RAIN = 2;
int RAIN_C;             //Rain counts stored in EEPROM and sent to xbee
int COUNT;
int lastCOUNT;
uint32_t totalCOUNTS;
int reset_rain = 9;
int reset_rain_counter;
byte btst[4];
byte data[4];
uint32_t addr;

void setup(void)
{
  Serial.begin(115200);
  uint8_t eepStatus = eep.begin(eep.twiClock400kHz);   //go fast!

  pinMode(RAIN , INPUT_PULLUP);
  pinMode(reset_rain , INPUT_PULLUP);

  if (eepStatus)
  {
    Serial.print(F("extEEPROM.begin() failed, status = "));
    Serial.println(eepStatus);
    while (1);
  }
  Serial.println("FILE NAME = WJL_eepromTest");

  eeRead();
  Serial.print("totalCOUNTS[]@setup = "); Serial.println(totalCOUNTS);
}

void loop(void)
{
  //Serial.println("STARTING");
  reset_rain_counter = digitalRead(reset_rain);
  if (reset_rain_counter == LOW)
  {
    Serial.println(reset_rain_counter);
    reset_counter();
  }
  COUNT = digitalRead(RAIN);
  if (COUNT != lastCOUNT)
  {
    if (COUNT == LOW)
    {
      totalCOUNTS = totalCOUNTS + 1;
      Serial.print("TOTAL COUNTS@COUNT = "); Serial.println(totalCOUNTS);
      eeWrite();
      delay(200);
    }
    else
    {
    }
    delay(50);
  }
  lastCOUNT = COUNT;
}


//write test data (32-bit integers) to eeprom, "chunk" bytes at a time
void eeWrite()
{
  Serial.println(F("Writing..."));

  data[0] = (totalCOUNTS & 0xFF);
  Serial.print("data[0]@write = "); Serial.println(data[0], BIN);
  data[1] = ((totalCOUNTS >> 8) & 0xFF);
  Serial.print("data[1]@write = "); Serial.println(data[1], BIN);
  data[2] = ((totalCOUNTS >> 16) & 0xFF);
  Serial.print("data[2]@write = "); Serial.println(data[2], BIN);
  data[3] = ((totalCOUNTS >> 24) & 0xFF);
  Serial.print("data[3]@write = "); Serial.println(data[3], BIN);

  eep.write(0, data[0]);
  Serial.print("writing[0] = "); Serial.println(data[0], BIN);
  eep.write(1, data[1]);
  Serial.print("writing[1] = "); Serial.println(data[1], BIN);
  eep.write(2, data[2]);
  Serial.print("writing[2] = "); Serial.println(data[2], BIN);
  eep.write(3, data[3]);
  Serial.print("writing[3] = "); Serial.println(data[3], BIN);

  Serial.print("totalCOUNTS @ write = "); Serial.println(totalCOUNTS);
}

//read test data (32-bit integers) from eeprom, "chunk" bytes at a time
void eeRead()
{
  Serial.println(F("Reading..."));

  for (addr = 0; addr < 4; addr++)
  {
    btst[addr] = eep.read(addr);
  }
  Serial.print("btst([0] = "); Serial.println(btst[0], BIN);
  Serial.print("btst([1] = "); Serial.println(btst[1], BIN);
  Serial.print("btst([2] = "); Serial.println(btst[2], BIN);
  Serial.print("btst([3] = "); Serial.println(btst[3], BIN);

  // totalCOUNTS = (uint32_t(btst[3])) | (uint32_t(btst[3]) << 8) |( uint32_t(btst[1]) << 16) | (uint32_t (btst[0]) <<24);
  totalCOUNTS = btst[3];
  totalCOUNTS = (totalCOUNTS << 8) | btst[2];
  totalCOUNTS = (totalCOUNTS << 8) | btst[1];
  totalCOUNTS = (totalCOUNTS << 8) | btst[0];
  Serial.print("totalCOUNTS@read = "); Serial.println(totalCOUNTS);
}

void reset_counter()
{
  Serial.println("AT RESET COUNTER");
  totalCOUNTS = 234567;
  Serial.print("totalCOUNTS = "); Serial.println(totalCOUNTS, BIN);
  eeWrite();
  delay(2000);
}