Multiple bytes read of I2C

Hello everyone

I want to make arduino read read 3 bytes(values of 3-axis) from the accelerometer (i2c bus) :
device address: 0x1D
3 register addresses:
X----0x06 Y----0x07 Z----0x08

And here is my code:

#include <Wire.h>
int address = 0x1D >> 1;
 int reading;
void setup()
  Wire.begin(); // join i2c bus (address optional for master)
void loop() {
  Wire.requestFrom(address, 3);
   if(3 <= Wire.available())    // if 3 bytes were received
    reading = Wire.receive();  // receive high byte (overwrites previous reading)
    reading = reading << 8;    // shift high byte to be high 8 bits
    reading += Wire.receive(); // receive low byte as lower 8 bits
    reading = reading << 8; 
    reading = reading << 8; 
    reading /= 10;
    Serial.println(reading);   // print the reading


But nothing appeared on the serial monitor…
Could anyone help me… =(


You request three bytes, wait for three to arrive, and only read two?!?

Thanks man. I have modified the code. But it's just a clerical error....

The computer tries to do exactly what you say, clerical error or not.

Your code is written such that if the reply does not arrive win the few milliseconds after you make the request, the request is just repeated. Perhaps you should allow some time for the data to arrive before you give up.

Instead of: if(Wire.available() >= 3) you could put in a while((Wire.avaialble() < 3) loop.

Tried with your suggestion. All zeros flash without delay............... Anyhow, much better than nothing.

in my opinion, each data has an ack/nack. So, if shifting them by 9 bits would be better?

I really dont want to give up........

First off, you have to make sure your device will SEND you three bytes when you ask for register 0x06. The data sheet will have this answer. Perhaps it wants you to make three calls, one to each address.

So, here is an example of something I've written that has been bulletproof for shuttling volumes of data around via I2C.

uint16_t M24LC256::ReadChunk(uint16_t location, uint16_t length, uint8_t* data)
    uint16_t bytes_received = 0;
    uint16_t bytes_requested = min(length,16);

    Wire.send((uint8_t)(location >> 8));
    Wire.send((uint8_t)(location & 0xff));


    uint16_t remaining = bytes_requested;
    uint8_t* next = data;

    while (Wire.available() && remaining--)
        *next++ = Wire.receive();

    return bytes_received;

It's a little more complex than your situation, but hopefully illustrative. This assumes that Wire.available() turns true immediately, and stays true the entire length of the receive() calls. I think the Wire.requestFrom() call blocks until all of the data is in the buffer, so available() is just giving you the state of internal buffers.