Confused about reading data I2C

Hello,

I have a question regarding a piece of code I’ve written. I added something I googled in order to get it to work but I don’t know why I need that to get it to work.

Wire.beginTransmission(0x10);
  Wire.write(5);
  >>>>Wire.endTransmission(false);<<<<
  Wire.requestFrom(0x10, 2);
  data = Wire.read();
  data |= Wire.read() << 8;
  Wire.endTransmission();

Without the indicated part it won’t work and just output 0, and I do not understand why.

Page 4 of the spec sheet shows you the frame in order to read the data.

Is endTransmission(false) doing the Start condition again? Isn’t requestFrom(Address, Bytes, STOP) sending a start condition as well?

Hopefully someone can explain, thanks in advance.

There is no "bolded part"....

Regards,
Ray L.

I was trying to fix my post but there's a 5 minute delay in order to edit or post.

The Wire.endTransmission() part is what actually sends the data to the device. It is NOT optional.

The argument to the function defines whether or not to release the I2C channel when the function ends. In general, it is a good idea to do so.

PaulS:
The Wire.endTransmission() part is what actually sends the data to the device. It is NOT optional.

The argument to the function defines whether or not to release the I2C channel when the function ends. In general, it is a good idea to do so.

I am talking specifically about the Wire.endTransmission(false), why is this one needed in order to receive the data? What does it do? If I remove the false and allow it to send a stop command instead no data will be received.

why is this one needed in order to receive the data?

It isn't. But, it IS needed to complete the transaction where you tell the device what kind of data it is to send.

What does it do?

The beginTransmission() method allocates a buffer, and makes sure that it is empty. The write() method call(s) put data in the buffer. The endTransmission() method sends the data in the buffer to the device at the specified address. This is all documented on the Wire library page.

If I remove the false and allow it to send a stop command instead no data will be received.

Whether the value in the endTransmission() call needs to be true or false depends on what you are talking to. Some chips need to have the I2C bus released before they can send data on the bus. Others don't.

Sometimes, you want to send data to multiple devices without the other devices on the bus trying to send replies. Sometimes, you don't.

The endTransmission() argument lets you have complete control of the bus.

I see, I understand now. Thanks for the information.

Try this instead:

Wire.beginTransmission(0x10);
Wire.write(5);
Wire.endTransmission();

Wire.requestFrom(0x10, 2);


  while (Wire.available()) 
  {
  data = Wire.read();
  data |= Wire.read() << 8;
  }

What you’ll end-up doing is:

  • Tell the slave that you want it to point to its register #5

  • then tell the slave that you want to receive 2 bytes, starting from the current position of its pointer

  • when the data are going to be available, you will read them !

I never do a “Wire.endTransmission()” after a request: maybe I’m wrong, but it has never been an issue so far …

I noticed that you were reading the value from the slave right after requesting them: might be too fast ! That’s why I use the Wire.available.

Also, keep in mind that (for example) when you write, even if you do beginTransmission + write + endTransmission, all the commands get packaged ONLY when the endTransmission is executed.

hope it help …