Arduino Stack Exchange is a question and answer site for developers of open-source hardware and software that is compatible with Arduino. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

I am trying to read an EEPROM chip that supports the I2C protocol (cannot tell the IC model number as it is not printed). For sure it supports the I2C protocol, since I wrote a code to detect it using the I2C library and the device address I got it return is 0x51. Now I am trying to write a code that reads data from this IC chip. The code is as follows:

#include <Wire.h>

int addr = 0;

void setup() {
    Wire.begin(); // initialise the connection
    Serial.begin(9600);
    while (!Serial) {}
    delay(100);
}

void loop() {
  byte deviceAddress = 0x51;
  byte data = readData(addr, deviceAddress);
  Serial.print(data, HEX);
  Serial.print(" ");
  addr++;
  if(addr%16 == 0) {
     Serial.print('\n');
  }
  // check for 1Kbits first
  if (addr%128 == 0) {
     Serial.println("round complete");
     Serial.println();
     addr = 0;
  }
  delay(100);
}

byte readData(int address, int deviceAddress) {
  // sending device address
  Wire.beginTransmission(deviceAddress);
  Wire.write(address);
  Wire.endTransmission();
  Wire.requestFrom((short int)deviceAddress, 1);
  if(Wire.available()) {
    byte data = Wire.read();
    return data;  
  }
  return 0xAA; // random data
}

The problem I am facing is, I get back the address (from which I want to read the data) as the data itself (For e.g. read(0) returns 0, read(1) returns 1 and so on). I even tried to debug the I2C communication using the logic analyzer (Saleae logic in this case). A screenshot is shown below.

enter image description here

The screenshot shows the logic for a read operation from a single address (0x78), but the story holds for each and every address i.e. I get back the address instead of the data from the address.

The output of the above code is as follows:

0 1 2 3 4 5 6 7 8 9 A B C D E F
10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F
20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F
30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F
40 41 42 43 44 45 46 47 48 49 4A 4B 4C 4D 4E 4F
50 51 52 53 54 55 56 57 58 59 5A 5B 5C 5D 5E 5F
60 61 62 63 64 65 66 67 68 69 6A 6B 6C 6D 6E 6F
70 71 72 73 74 75 76 77 78 79 7A 7B 7C 7D 7E 7F
round complete

Can you help me identifying what possibly I am doing wrong here?

Thanks.

share|improve this question
    
How about using a 16-bit address? Here is a link to a driver that I have written for Cosa; github.com/mikaelpatel/Cosa/blob/master/libraries/AT24CXX/… – Mikael Patel Mar 11 '16 at 23:07
    
How many legs (pins) does the chip have? – Nick Gammon Mar 12 '16 at 5:05
    
I agree with Mikael too, you could try sending a 16-bit address. For example, send a zero first, then an address. In any case, can you be certain that the chip does not happen to have 0x00, 0x01, etc. inside its memory? – Nick Gammon Mar 12 '16 at 5:08
    
@MikaelPatel: I will give a try with 16-bit address and let you know what the results are. – MayankTUM Mar 13 '16 at 20:43
    
@NickGammon: Just to make sure that the contents are not 0x00, 0x01, etc. I tried to perform a write operation to the chip. But the result for reading after a write, remains the same. Maybe I have to try using 16-bit addresses as you suggested as well. – MayankTUM Mar 13 '16 at 20:45

You need to pass the address as two bytes, one by one.

Do not do:

Wire.write(address);

Rather, do:

Wire.write((uint8_t)(address >> 8)); // MSB
Wire.write((uint8_t)(address & 0xFF)); // LSB
share|improve this answer

Without the specific chip info this will be difficult.

However, my experience with EEPROMs and I2C is that the first action is to write a command, then write the parameter(s) for that command, then read the response.

Often, there is a status register in the EEPROM that needs to be read (by writing a command, then reading the response) to determine if the EEPROM is ready to receive a different command, like writing to set the address for a read/or/write, then the actual read command.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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