1

I am reading data from a 24LC1025 over I2C with an Arduino and then outputing that data to my PC through the Serial interface. The EEPROM chip is seperated into two pages and at address 65535 [0x0FFFF] it switches over to the second page sending [0x10000 through 0x1FFFF] I had it working by reading each address with a random read:

#include <Wire.h>

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

void setup() {
  Wire.begin(); // initialise the connection
  Serial.begin(9600);
  delay(100); //add a small delay
  Serial.println("Arduino Group Delay Read Program");

  for (unsigned long i = 0; i < 128000; i++){
    Serial.print(i);
    Serial.print(",");
    byte a = i2c_eeprom_read_byte(0x50, i);
    Serial.println(a, BIN);
  }
}

void loop() {
  //
}

To reduce overhead and speed up the process I am now using the code below:

#include <Wire.h>

byte bytes[32];

void i2c_eeprom_read_buffer( int deviceaddress, unsigned long eeaddress, byte *buffer, int length ) {
    Wire.beginTransmission(deviceaddress);
    Wire.write((eeaddress >> 8)); // MSB
    Wire.write((eeaddress & 0xFF)); // LSB
    Wire.endTransmission();
    Wire.requestFrom(deviceaddress,length);
    int c = 0;
    for ( c = 0; c < length; c++ )
        if (Wire.available()) buffer[c] = Wire.read();
}

void setup() {
  Wire.setClock(400000); // 400kHz
  Wire.begin(); // initialise the connection
  Serial.begin(250000);
  delay(100); //add a small delay
  Serial.println("Arduino Group Delay Read Program");

  for (unsigned int i = 0; i < 128000;){
    i2c_eeprom_read_buffer(0x50, i, (byte *)bytes, 32);
    for (int j = 0; j < 32; j++){
      Serial.print(i);
      Serial.print(",");
      Serial.println(bytes[j], BIN);
      i++;
    }
  }
}

void loop() {
  // 
}

Unfortunately, the program now loops at the page boundary back to the start of the address range. Here is a sample of the output:

65500,1110100
65501,1101000
65502,1101001
65503,1110011
65504,100000
65505,1101001
65506,1110011
65507,100000
65508,1100100
65509,1100001
65510,1110100
65511,1100001
65512,100000
65513,1100110
65514,1110010
65515,1101111
65516,1101101
65517,100000
65518,1110100
65519,1101000
65520,1100101
65521,100000
65522,1100101
65523,1100101
65524,1110000
65525,1110010
65526,1101111
65527,1101101
65528,0
65529,11111111
65530,11111111
65531,11111111
65532,11111111
65533,11111111
65534,11111111
65535,11111111
0,0
1,0
2,1
3,110000
4,111000
5,111001
6,110110
7,110001
8,111001
9,1000001
10,101110
11,1011000
12,110001
13,110001
14,1010110
15,1011001
16,110001
17,110111
18,110100
19,110001
20,1110100
21,1101000
22,1101001
23,1110011
24,100000
25,1101001
26,1110011
27,100000
28,1100100
29,1100001
30,1110100
31,1100001
32,100000
33,1100110
34,1110010
35,1101111
36,1101101
37,100000
38,1110100
39,1101000
40,1100101
41,100000
42,1100101
43,1100101
44,1110000
45,1110010
46,1101111
47,1101101
48,0
49,111001
50,100010
51,11010010
52,110101
53,1001000
54,11101011
55,11000000
56,110101
57,11101011
58,1011100
59,10010100
60,110101
61,100000
62,10100011
63,1110110
64,10110100
65,10110001
66,1111010
67,11100000
68,10110110
69,101100
70,11010110

I could see how an error in the code could cause the second page to display the first page's values, but there is nothing in the code that should cause the counter itself to loop. Any idea what could be causing this?

Edit: For anyone who is working a similar issue, here is the code that I ended up with once I solved this issue and then dealt with the page boundary problem (line 4):

#include <Wire.h>

byte i2c_eeprom_read_byte( int deviceaddress, unsigned long eeaddress ) {
  byte rdata = 0xFF;
   if( eeaddress > 65535 ){
    deviceaddress = deviceaddress | B00000100;
    eeaddress = eeaddress & 0xFFFF;
    }
  Wire.beginTransmission(deviceaddress);
  Wire.write((eeaddress >> 8));   // MSB
  Wire.write((eeaddress & 0xFF)); // LSB
  Wire.endTransmission();
  Wire.requestFrom(deviceaddress,1);
  if (Wire.available()) rdata = Wire.read();
  return rdata;
}

void setup() {
  Wire.setClock(400000);  
  Wire.begin(); // initialise the connection
  Serial.begin(115200);
  delay(100); //add a small delay
  Serial.println("Arduino Group Delay Read Program");

  for (unsigned long i = 0; i < 128000; i++){
    Serial.print(i);
    Serial.print(",");
    byte a = i2c_eeprom_read_byte(0x50, i);
    Serial.println(a, BIN);
  }
}

void loop() {
}

Note that this last code will work with the i2c_eeprom_read_buffer function as well as long as you add the if statement starting at line 4.

2
for (unsigned int i = 0; i < 128000;){

An unsigned int can only count from 0 to 65536 on an 8-bit system... You need that to be an unsigned long, or better, a uint32_t (better because it's guaranteed to be an unsigned 32-bit value on any platform regardless of how wide its registers are).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.