I2C - 8-bits Slave address

Hi everyone,

I have a device which can be interfaced with I2C. The address of the device has 8-bits (7 of proper address 0x59 and 1 bit R/W). I've been reading on the topic and I understood that the Wire.beginTransmission works only with 7-bits. My question is, how do I set the read/write bit condition if I have to drop it in the address?

Thank you for the help
Vince

Don't worry about the R/W bit, the real address is the other 7 bits and those bits only.

Power_Broker:
Don't worry about the R/W bit, the real address is the other 7 bits and those bits only.

Let me be more specific. I'm trying to program the TI DVR2667 (haptic driver piezos). To check that the connection is working properly I'm trying to read the byte in the first register 0x00. Now the datasheet explains how to do it:

  • send the 7-bit address of the device with the R/W bit set to write;
  • ACK;
  • send the address of the register you want to read;
  • ACK;
  • repeat the start condition;
  • send the 7-bit address of the device with the R/W bit set to read;
  • read the bus;
  • ACK;
  • send the stop condition

what I've naively done is:

  • Wire.beginTransmission(7-bit address), because I think arduino handles the R/W bit;
  • Wire.write(register_address);
  • Wire.requestFrom(7-bit addres, 1byte);
  • Wire.read();
  • Wire.endTransmission;

surprisingly it works :smiley: The point is I would like to know how the Wire.requestFrom and Wire.read handle the hardware signals

Vinnie_90:
Let me be more specific. I'm trying to program the TI DVR2667 (haptic driver piezos). To check that the connection is working properly I'm trying to read the byte in the first register 0x00. Now the datasheet explains how to do it:

  • send the 7-bit address of the device with the R/W bit set to write;
  • ACK;
  • send the address of the register you want to read;
  • ACK;
  • repeat the start condition;
  • send the 7-bit address of the device with the R/W bit set to read;
  • read the bus;
  • ACK;
  • send the stop condition

I'm already familiar with the I2C standard.

Vinnie_90:
what I've naively done is:

  • Wire.beginTransmission(7-bit address), because I think arduino handles the R/W bit;
  • Wire.write(register_address);
  • Wire.requestFrom(7-bit addres, 1byte);
  • Wire.read();
  • Wire.endTransmission;

No, no, no. That's not how the library works. What you should've done was this:

Wire.beginTransmission(7-bit address);
Wire.requestFrom(7-bit addres, 1byte);
Wire.read();
Wire.endTransmission;

This is because wire.write() sends and entire I2C transmission frame, not just the value you want to send. Also, you already "told" the library what slave you are talking to. Wire.write() takes care of all the calls/acks that you describe in the above standard; you just give it the values you want it to use. You are making this more complicated than it is.

Vinnie_90:
surprisingly it works :smiley: The point is I would like to know how the Wire.requestFrom and Wire.read handle the hardware signals

Why do you care? If you're really that interested, find the Wire.cpp and Wire.h files on your machine and you can find out for yourself.

Power_Broker:
No, no, no. That's not how the library works. What you should've done was this:

Wire.beginTransmission(7-bit address);

Wire.requestFrom(7-bit addres, 1byte);
Wire.read();
Wire.endTransmission;




This is because wire.write() sends and entire I2C transmission frame, not just the value you want to send. Also, you already "told" the library what slave you are talking to. Wire.write() takes care of all the calls/acks that you describe in the above standard; you just give it the values you want it to use. You are making this more complicated than it is.

Mh, I see. But then let's say I want to read the data in a specific register (0x05 for example). How do I tell the slave device that, if I don't include it anywhere in the code?

Thanks a lot for the help. I'm not that good in c++ to read the whole library and understand it.

Vinnie_90:
Mh, I see. But then let's say I want to read the data in a specific register (0x05 for example). How do I tell the slave device that, if I don't include it anywhere in the code?

Thanks a lot for the help. I'm not that good in c++ to read the whole library and understand it.

No problem. This is how you read from a specific register:

  Wire.beginTransmission(address);
  Wire.write(0x5);  // register 0x5
  Wire.endTransmission(false);
  Wire.requestFrom(address,1,true);
  value = Wire.read();

Here's how you can read from multiple registers that are in sequence:

  Wire.beginTransmission(address);
  Wire.write(0x5);  // starting with register 0x5
  Wire.endTransmission(false);
  Wire.requestFrom(address,3,true);  // request a total of 3 registers
  value1 = Wire.read(); //register 0x5
  value2 = Wire.read(); //register 0x6
  value3 = Wire.read(); //register 0x7