I2c: More details of the Wire library?

Hi guys -

I’m familiar with I2C protocol and have used it on the tiva launchpad microcontroller before. I’m trying to figure out whether the Arduino Wire library has the capability to talk to my I2C device (QT2120 capacitive touch sensor). I was hoping a document existed that broke down exactly what each of the Wire functions was doing, in terms of I2C protocol. For instance, “BeginTransmission: sends a start bit, followed by the slave address followed by a write bit…” etc.

The problem I’m having is that to read from my device I have to do a long sequence of I2C conditions. I’ve included a picture from the datasheet. I’m not sure whether, using the Wire library, I can do two things:

  • Send the slave address and then a write bit, then later on send the slave address and a read bit. I can’t find control over the read or write bit anywhere in the documentation of the Wire library.
  • Send a start condition, then the Slave address + Read bit, receive an Ack from my sensor, then start reading data.

This is why I’m trying to figure out exactly what the Wire library does. When I was using the Tiva library, there’s a separate document that explains what each of the flexible I2C functions does and I could piece them together for this device’s required protocol. Haven’t found this for Arduino. All advice welcome, thanks.

This should get you started.

Thanks Eddie. I'd read the detailed reference, but it still wasn't answering what they did in terms of I2C. Also, I think it is outdated, because it's referring to Send and Receive functions that were tweaked to read and write in the latest version of the Wire library.

I might just have to use my logic analyzer to see what each of the functions is actually doing. For instance, when you use EndTransmission(false). It's not sending a Stop bit, right? But the Wire library page says it "sends a restart" - I'm guessing that means it sends another start bit, but I wish there were a document describing each function in terms of I2C protocol. Tiva/ARM has this and it's incredibly useful.

I'm sure there are more detailed documents with timing charts. I just don't know of any in particular. You might try the Nick Gammon site as he is well versed on I2C.

PS
This will help you.

I wrote this explanation : http://forum.arduino.cc/index.php?topic=390814.msg2695029#msg2695029

If you want to set the R/W bit to write, use the beginTransmission --- write --- endTransmission sequence.
If you want to set the R/W bit to read, use the requestFrom.

The endTransmission returns an error, that can be checked to see if the device did acknowledge.
The requestFrom returns the number of received bytes, if something is wrong the number is most likely zero.

The endTransmission and requestFrom can have a repeated start. It is often called 'Sr' to distinguish it from Start and Stop.
http://www.arduino.cc/en/Reference/WireEndTransmission
https://www.arduino.cc/en/Reference/WireRequestFrom

When writing, the Master should NAK the last byte, followed by a STOP. That is done by the endTransmission function. It does a ACK for every sent byte, but the last byte is followed by a NAK.

Does this help a little ? Ask what you want to know.

Thank you, Koepel, for the advice. The one thing that had me worried was sending a NACK. You're saying that if I write:

Wire.requestFrom(0x1c, 1, false)

That one line should make the Arduino send a Start Condition, the slave address + Read Bit, wait for an ack, get one data byte, send a NACK, then a Stop Condition?

Yes, that function does all that.
After that, the data is in a 32 byte receive buffer in the Wire library.
The parameter ‘false’ for the Stop parameter means that a repeated start will be used. It must be ‘true’ for a Stop. The default is ‘true’.

I think I made a mistake in my explanation. When the Master is writing databytes, the Slave does the ACK/NAK. When the Master is reading databytes the Master does ACK and a NAK after the last byte. That is correct, right ?

This sketch gets a byte (the register-address is not set, so the byte is useless).

#include <Wire.h>

const int HMC5883L_address = 0x1E;

void setup() 
{
  Wire.begin();
  Wire.requestFrom( HMC5883L_address, 1);
}

void loop() 
{
}

And this is the result with a logic analyzer:

Hi guys,
Can i use SoftI2CMaster.h header file for arduino M0 pro?
Board has ATMEL SAM D 21 G proccessor.
Suggest header files required .....please