Does requestFrom increment 24c04 counter?

Hi, I have EEPROM 24c04 connected (through i2c) to iduino, comment section contains all details re pin connections, I use only the first memory block in this example. For testing purposes 24c04 was filled only by sample data. Process of reading is simple: Wire.request asks for certain amount of bytes, subsequently these bytes are being read by Wire.receive(). But when new set of data is requested, it skips always one byte after the sequence: in following example the memory is filled by decreasing content ff-00 (0xFF, 0xFE, 0xFD…00) etc. Wire.request requests 8 bytes of data (variable howmany=8) in multiple reading cycles. Printout of memeory content is then:
0: FF FE FD FC FB FA F9 F8
1: F6 F5 F4 F3 F2 F1 F0 EF
2: ED EC EB EA E9 E8 E7 E6
3: E4 E3 E2 E1 E0 DF DE DD
which means missing F7,EE, E5 etc.

or if you shorten amount of data wanted at once to 7 bytes only, it looks:
0: FF FE FD FC FB FA F9
1: F7 F6 F5 F4 F3 F2 F1
2: EF EE ED EC EB EA E9
3: E7 E6 E5 E4 E3 E2 E1
which means missing F8, F0, E8 etc.

Analogically when howmany=1, it looks:
0: FF
1: FD
2: FB
3: F9
4: F7
5: F5
6: F3

The problem is that in the first example I lose F7,EE, E5 etc., in second I lose F8, F0, E8 etc. in the last example I see every second byte only. Is Wire.requestFrom written somehow incorrectly (because it increments internal counter for position of cell being read without possibility to read it) and/or simply this is not proper way of reading data? Of course I can track index of memory location in some another variable and adjust addr accordingly just before requestFrom, but I would expect incrementing step-by-step and/or maybe I do something wrong. I played with different values of howmany for requestFrom and different for receive in both directions (+1 or -1), but no success. Definitely it does not seem for the problem with receive function, as it reads data correctly consecutively regardless how it is used.

Complete commented code follows:

#include <Wire.h>

// 24C04 pins assignment:
// 1 (PRE) write protection not connected
// 2,3,4   E1,E2,VSS  =  GND
// 5,6 SDA, SCL connected to Analog 4, Analog 5 of Arduino
// 7 MODE or  /WC = GND. 
// 8 VCC
// 24c04 contains 2 blocks, each 256x8
//  I2C device address is 1 0 1 0 E2 E1 block  R/W.          E1/2 = 0 (GND).    
// I2C device  memory is 0x50 for the first block or 0x51 2nd one. 
// new memory contains 0xFF everywhere


int addr = 0x50;     // address 1st block
int addr2 =0x51;     // address 2nd block
long int howmany=7;    //how many bytes to be read
byte data[100];      //array to store data, max 100 bytes to read
int i,j=0;           // variables for cycles

void setup() {
  Wire.begin(addr);    //  i2c bus start

  Serial.begin(9600);       //

    Wire.beginTransmission(addr);      //restart of address to zero
    Wire.send(0);                        
    Wire.endTransmission();

/* 
//               --------------------------------------------------------

//               utility to write some sample data to memory. If addr replaced by addr2, then to 2nd block. To activate write function, 
//                unmark this section
   
    for (i=0; i<256;i++) {
    Wire.beginTransmission(addr);        
    Wire.send(i);                     //send address to buffer (0 is beginning)
    Wire.send(255-i);                     // send content to buffer, examples 'i' or '255-i' or '0xFA'
    Wire.endTransmission();                  //actual write
    delay (10);                         // technical delay to complete write
 }
 //               -------------------------------------------
 */
  

    Wire.beginTransmission(addr);          //restart of address to zero
    Wire.send(0);
    Wire.endTransmission();

}

void loop() {
  Wire.requestFrom(addr,howmany);               //request to read 'howmany' bytes

  do {
   for (j=0;j<howmany;j++) {
      data[j]=Wire.receive();                // reading howmany bytes if available to array data[]
   }
 } while(Wire.available());               


     if (i<10) {                              // indent of line counter for better readability. One line contains 'howmany' data.
            Serial.print(" ");
     }
      Serial.print(i);                        // line counter
      Serial.print(":   ");                
   for (j=0;j<howmany;j++) {                  // printout of collected data
      Serial.print(data[j],HEX);
      Serial.print("   ");
   }                
Serial.println();                            // end of line

    i++;                                     // increment of line counter

  delay(200);                                
  }

Thanks for help, Peter.

Hi Peter,

The 24C04 (http://www.st.com/stonline/products/literature/ds/5067/m24c04-r.pdf) has three basic read modes. These, and the flow of data are described on page 17 of that PDF file.

I dont have an EEPROM on my desk right now, but your code seems sensible. But you need to make sure that you have sufficient pull-up current, the internal pull-ups int eh ATmega168 are only suitable for very low speed, 10kHz maybe, and for a chip in close proximity to the CPU. For I2C you will be using Analog pins 4 & 5, both of these should be pulled up to the 5V rail with 2.2K, although 4.7K may work as well.

John
http://www.siliconrailway.com home of LEDuino

According to 24L04 datasheet "To provide sequential reads, the 24XX04 contains an internal Address Pointer that is incremented by one upon completion of each operation. This Address Pointer allows the entire memory contents to be serially read during one operation.". But the spec does not garantee anyting about wrap around over 255 (block lenght), so I suspect that the problem is there. I obtain completely normal operation by adding restart transmission which re-initialize the 24L04 pointer after reading byte 255.