Wrong Reading with 24LC512

Hi everyone

I have a problem when I want to write Accelerometer Dats and save into External RAM (24LC512).
I follow the code from this: Arduino Playground - I2CEEPROM

In serial monitor I want to show the result while sending and receiving. And the received data were wrong except the last address.
When I change to send 10 addresses, the result will correct only the last address.

I need some help of this problem.

Thank you very much.

Hi,
Welcome to the forum.

Please read the first post in any forum entitled how to use this forum.
http://forum.arduino.cc/index.php/topic,148850.0.html then look down to item #7 about how to post your code.
It will be formatted in a scrolling window that makes it easier to read.

We need to see your code, please.

Thanks.. Tom... :slight_smile:

Thank you, this is the code that I use.

#include "Wire.h"
#include "I2Cdev.h"
#include "MPU6050.h"

extern "C" { 
  #include "utility/twi.h"  // from Wire library, so we can do bus scanning
}
#define I2C_ADDRESS 0x50
#define TCAADDR 0x70
#define MPU1ADDR 1
#define MPU2ADDR 2
#define MPU3ADDR 3
MPU6050 mpu1; MPU6050 mpu2; MPU6050 mpu3;

long previousMillis = 0;        // will store last time LED was updated
long interval = 20;           // interval at which to blink (milliseconds)

void tcaselect(uint8_t i) 
{ 
  if (i > 7) {return;}
  Wire.beginTransmission(TCAADDR);
  Wire.write(1 << i);
  Wire.endTransmission();  
}

void setup() 
{ 
  while (!Serial);
  delay(1000);

  Wire.begin();
  Serial.begin(115200);
  Serial.println("\nTCAScanner ready!");
  for (uint8_t t = 0; t < 8; t++) 
  {
    tcaselect(t);
    Serial.print("TCA Port #"); Serial.println(t);

    for (uint8_t addr = 0; addr <= 127; addr++) 
    {
      if (addr == TCAADDR) continue;
      uint8_t data;
      if (! twi_writeTo(addr, &data, 0, 1, 1)) 
      {
        Serial.print("Found I2C 0x");  Serial.println(addr, HEX);
        Serial.print("CONNECT 0x0") ; Serial.println(t);
      }
    }
  } 
  Serial.println("\ndone");
  
  
  Serial.println("\nInitialize MPU6050");

  tcaselect(1);
  while(!mpu1.begin(MPU6050_SCALE_2000DPS, MPU6050_RANGE_2G))
  {
    Serial.println("Could not find a valid MPU6050 sensor, check wiring!");
    delay(500);
  }
  Serial.println("MPU6050-1 Ready!!!");
  
  tcaselect(2);
  while(!mpu2.begin(MPU6050_SCALE_2000DPS, MPU6050_RANGE_2G))
  {
    Serial.println("Could not find a valid MPU6050 sensor, check wiring!");
    delay(500);
  }
  Serial.println("MPU6050-2 Ready!!!");
  
  tcaselect(3);
  while(!mpu3.begin(MPU6050_SCALE_2000DPS, MPU6050_RANGE_2G))
  {
    Serial.println("Could not find a valid MPU6050 sensor, check wiring!");
    delay(500);
  }
  Serial.println("MPU6050-3 Ready!!!");
  
  delay(2000);
  
  Serial.println("Start the Program");
}


Vector displayData(MPU6050 sensor,int tca) 
{ 
  tcaselect(tca); // Read normalized values 
  Vector norm = mpu1.readRawAccel();
  Wire.endTransmission();
  return norm;
}

byte Acc[42];
int AccX,AccY,AccZ = 0;
int AccAddress = 0;
int count = 0;
int ReadStatus = 0;
Vector result;

void loop() 
{ 
  unsigned long currentMillis = millis();
  if(currentMillis - previousMillis > interval) 
  {
    previousMillis = currentMillis;  
   
   if(ReadStatus==0)
   {
      Serial.print("Send Channel : ");
      Serial.println(AccAddress);

//**************************  MPU-6050 Ch.1  ***************************//
      result = displayData(mpu1,MPU1ADDR); 
      AccX=result.XAxis;AccY=result.YAxis;AccZ=result.ZAxis;
      Acc[count]=(AccX >> 8);
      count++;
      Acc[count]=(AccX & 0x00FF);
      count++;
      Acc[count]=(AccY >> 8);
      count++;
      Acc[count]=(AccY & 0x00FF);
      count++;
      Acc[count]=(AccZ >> 8);
      count++;
      Acc[count]=(AccZ & 0x00FF);
      count++;
      
      Serial.print(AccX);
      Serial.print(" ");
      Serial.print(AccY);
      Serial.print(" ");
      Serial.print(AccZ);
      Serial.print(" ");
      
//**************************  MPU-6050 Ch.2  ***************************//
      result = displayData(mpu2,MPU2ADDR); 
      AccX=result.XAxis;AccY=result.YAxis;AccZ=result.ZAxis;
      Acc[count]=(AccX >> 8);
      count++;
      Acc[count]=(AccX & 0x00FF);
      count++;
      Acc[count]=(AccY >> 8);
      count++;
      Acc[count]=(AccY & 0x00FF);
      count++;
      Acc[count]=(AccZ >> 8);
      count++;
      Acc[count]=(AccZ & 0x00FF);
      count++;
      
      Serial.print(AccX);
      Serial.print(" ");
      Serial.print(AccY);
      Serial.print(" ");
      Serial.print(AccZ);
      Serial.print(" ");
//**************************  MPU-6050 Ch.3  ***************************//
      result = displayData(mpu3,MPU3ADDR); 
      AccX=result.XAxis;AccY=result.YAxis;AccZ=result.ZAxis;
      Acc[count]=(AccX >> 8);
      count++;
      Acc[count]=(AccX & 0x00FF);
      count++;
      Acc[count]=(AccY >> 8);
      count++;
      Acc[count]=(AccY & 0x00FF);
      count++;
      Acc[count]=(AccZ >> 8);
      count++;
      Acc[count]=(AccZ & 0x00FF);
      count++;
 
      Serial.print(AccX);
      Serial.print(" ");
      Serial.print(AccY);
      Serial.print(" ");
      Serial.print(AccZ);
      Serial.println(" ");
      

//**************************  Start Sending Data   ***************************//   
      tcaselect(0);
      i2c_eeprom_write_page(I2C_ADDRESS, AccAddress,Acc, count); //
      AccAddress++;
      count=0;
      if(AccAddress >=5)
      {
         ReadStatus=1; 
         Serial.println("Send Finished");
      }
   }
//**************************  Start Reading Data   ***************************//    
   else if(ReadStatus==1)
   {
      for(int ReadAddress=0; ReadAddress<5; ReadAddress++)
      {
        Serial.print("Read form channel : ");
        Serial.println(ReadAddress);
        byte PageRead[18]={};
        tcaselect(0);
        i2c_eeprom_read_buffer(I2C_ADDRESS, ReadAddress, PageRead, 18);
        for (int i=0; i<18; i=i+2)
        {
          int b = (PageRead[i]<<8)|(PageRead[i+1]);
          Serial.print(b);    // display the array read
          Serial.print(" ");
        }
        Serial.println("");
      }
      ReadStatus=2;
   }

  }
  

}

)
void i2c_eeprom_write_page( int deviceaddress, int eeaddresspage, byte *data, byte length )
{
  Wire.beginTransmission(deviceaddress);
  Wire.write((int)(eeaddresspage >> 8)); // Address High Byte
  Wire.write((int)(eeaddresspage & 0xFF)); // Address Low Byte
  for (int c = 0; c < length; c++)
  {
    Wire.write(data[c]);
  }
  Wire.endTransmission();
  delay(15);                           // need some delay
}

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

  delay(20);
}
  for ( int c = 0; c < length; c++ )
  {
    if (Wire.available()) buffer[c] = Wire.read();
  }

And if there's nothing available . . ?

I tried to do like this.

  for ( int c = 0; c < length; c++ )
  {
    if (Wire.available()==false)
    { 
      buffer[c] = Wire.read();
    }
  }

and the result show like this

Read form channel : 0
0 0 0 0 0 0 0 0 0 
Read form channel : 1
0 0 0 0 0 0 0 0 0 
Read form channel : 2
0 0 0 0 0 0 0 0 0 
Read form channel : 3
0 0 0 0 0 0 0 0 0 
Read form channel : 4
0 0 0 0 0 0 0 0 0

See reply #3 again. If, on any given pass through the for loop, data has not arrived, you increment c anyway. NOT a good idea.

Hi PaulS

Thank you for supporting me. I changed my code like this. if "Wire unavailable" the buffer must equal 0 right?

  for ( int c = 0; c < length; c++ )
  {
    if (Wire.available())
    { 
      buffer[c] = Wire.read();
    }
    else
    {
      buffer[c] = 0;
    }
  }

And the result show like this. It means the Wire Available.

Start the Program
Send Channel : 0
6124 -2728 15260 7824 -14936 1752 14904 -7592 1728 
Send Channel : 1
6092 -2728 15072 7772 -15016 1644 14904 -7664 1684 
Send Channel : 2
6088 -2768 15184 7716 -14924 1700 14888 -7616 1616 
Send Channel : 3
6124 -2684 15252 7788 -14940 1788 14876 -7612 1520 
Send Channel : 4
6124 -2712 15376 7704 -14820 1604 14844 -7640 1496 
Send Finished
Read form channel : 0
5911 5911 6124 -2712 15376 7704 -14820 1604 14844 
Read form channel : 1
5911 5911 -4875 26684 4126 6342 7174 17465 -798 
Read form channel : 2
5911 6124 -2712 15376 7704 -14820 1604 14844 -7640 
Read form channel : 3
5911 -4875 26684 4126 6342 7174 17465 -798 10245 
Read form channel : 4
6124 -2712 15376 7704 -14820 1604 14844 -7640 1496

It means the Wire Available.

Sure. But, you stored the data from Wire in a byte array. That output is NOT byte data.

Hi PaulS

Thank you. But can you see the result?

Why the last channel(Ch.4) of reading got the correct result compare with "Send channel 4"?

I don't understand that if I change to only 1 address for writing and reading , the result is correct.

Start the Program
Send Channel : 0
6096 -2968 15172 7756 -15020 1588 14912 -7752 1680 
Send Finished
Read form channel : 0
6096 -2968 15172 7756 -15020 1588 14912 -7752 1680
Vector displayData(MPU6050 sensor,int tca)
{
  tcaselect(tca); // Read normalized values
  Vector norm = mpu1.readRawAccel();
  Wire.endTransmission();
  return norm;
}

Why is there a call to Wire.endTransmission() in this function?

          int b = (PageRead[i]<<8)|(PageRead[i+1]);

PageRead[ i ] is a byte - an 8 bit value. What is the value when you've shifted those 8 bits 8 places to the left?

Print the bytes being written to the chip. Print the bytes being read back from the chip. Stop trying to use the data before you KNOW it is right. When you KNOW that what you read is what you wrote, THEN you can manipulate the data you read. If you don't get the data you read to convert back to what you wrote, then you'll know that the problem is the conversion on the way out or on the way back in.

Right now, you are trying to troubleshoot way too much code.

Dear PaulS

I apologize that I didn't explain the hardware to you.
I use I2C-multiplexing for acquiring data from 3 Accelerometers and I connect 24LC512 into the I2C-multiplexing.

Vector displayData(MPU6050 sensor,int tca)
{
  tcaselect(tca); // Read normalized values
  Vector norm = mpu1.readRawAccel();
  Wire.endTransmission();
  return norm;
}

I wrote Wire.endTransmission(); because I think after acquired the data from Accelerometer then it should end the transmission before start in the next acquire of another channel.

int b = (PageRead[i]<<8)|(PageRead[i+1]);

I try to send 16 bits integer of Accelerometer data by seperate 8-bit high and low. And after read the data from 24LC512 I must combine it together to 16-bit integer result.

Thank you for helping me.

I wrote Wire.endTransmission(); because I think after acquired the data from Accelerometer then it should end the transmission before start in the next acquire of another channel.

Every endTransmission() call needs to be paired with a beginTransmission() call. It is what actually sends the data to the device. Where is the corresponding beginTransmission() call?

Solved !!!

Thank you for supporting me.

The problem appear when I wanna sent data byte more than 128 bytes (from the datasheet).
The data after 128 bytes will lost so I try to send the data less than 128 bytes per time.