Friday, August 14, 2015

When does the Arduino Wire library actually transmit on the I2C bus ?

I wanted to better understand the inner workings of the Wire library (the I2C library that comes with Arduino IDE).  The detailed reference and source code were helpful.  To check my understanding, I made a simple oscilloscope experiment, which I would like to report in this post.

Setup

Straightforward test code, which creates a write transaction on the I2C bus.  To know when the calls to the Wire library methods happen, each one is preceded by a strobe on pin 13.  These strobes will be seen with an oscilloscope.   To know when the I2C activity actually occurs, SDA and SCL (the I2C data and clock lines) are too observed with the oscilloscope.

  void strobe() {
    digitalWrite(13, HIGH);           // Strobe for oscilloscope
    digitalWrite(13, LOW);
  }
 
  void loop() {
    strobe();
    Wire.beginTransmission(0x4C);     // Set the address of the target device  
                                      // which we want to write to
    strobe();
    Wire.write(0x07);                 // Payload: set the address of the register inside
                                      // of the external device, which we want to write to
    strobe();
    Wire.write(0x01);                 // Payload: value to write to the register

    strobe();
    Wire.endTransmission();           // Actually do the transmission.

    delay(1000);
  }

This code ran on Arduino LilyPad USB (my clone thereof).  It should work the same on any Arduino that's based on AVR and has got hardware I2C.

(The addressee of this I2C transaction is an MMA7660 accelerometer.  It could have been just about any I2C slave device.)

Results and discussion

Debug strobes and the I2C activity.  All I2C activity takes place after the strobes.

As you can see, all of the I2C activity happens after all the calls to the Wire library methods have been made.
Wire.beginTransmission(...) doesn't actually begin the transmission, it only sets the I2C slave address for the forthcoming transmission.
Wire.write(...) doesn't actually transmit, it writes to a buffer in the Arduino's RAM.
Wire.endTransmission() actually causes the whole I2C transaction to happen from beginning to end.

Perhaps, the Wire Library functions could have names that better reflects inner workings.

References

[1]  Wire Library superficial reference
[2]  Wire Library detailed reference
[3]  Source code for Wire Library on GitHub

No comments:

Post a Comment