Exploring i2c

The summary of the “Exploring I2C” meetup? Good times!

As a start, Patrick provided some slides about I2C basics with Arduino. Most examples came from the hackaday blog that has tags for I2C. To get started with I2C, it turns out that temperature sensors are the simplest components to learn about the multi-master multiple-slave bus protocol. Displays, real-time clocks and EEProms are other popular examples.

We started by exploring the Eduction shield from Rheingoldheavy. On that board, you’ll find and AT30TS750A temperature sensor and a MCP7940N real time clock among other components.

So, the first step to get going was finding the right I2C library for Arduino. Arduino comes with its own Wire library for I2C. But that API is not very nice, and the code can even result into freezing the controller. This is why we directly looked into the I2C library as was suggested in this blog post by Rheingoldheavy.com.

The I2C library has a nice “scan” command that returns the slaves on the bus. A simple sketch to get started looked as follows:

void setup() {

  I2c.begin();
  I2c.setSpeed(0);

  Serial.begin(9600);
  Serial.println("init");
  I2c.scan();

}

void loop() {}

On the Learning shield it returned 0x48 and 0x60 for the temp sensor and RTC respectively. Running the code on an Wii Nunchuck gave:

So, you see that the Wii Nunchuck has quite a number of I2C slaves on its board. Once that basic code was running, we delved more into interactions with slave devices. First, you’ll program the configuration of a device. In the case of the temp sensor, you can set the resolution. This requires you the read the datasheet a bit. The resolution we liked was:

   I2c.write(0x48, 0x01, 0x60);

Last comes the readout of the actual data. In the API docs, we found several ways to readout registers. Well, here comes a bit C an C++ syntax into play as you need to deal with a pointer to a buffer. At the end, we came up with this code to readout the registers:o

uint8_t status1, status2;
void loop() {

    I2c.read(0x48, 0x00, 2);
    status1 = I2c.receive();
    status2 = I2c.receive();
    Serial.print(status1);
    Serial.print(" ");
    Serial.println(status2);
}

But you could also look at the code from Rheingoldheavy that is much cleaner to read. See the I2C Display+Temp sensor code or the Display+RTC code. With that code it is not too difficult to arrive at a working example as shown below:

Extra: We tried to compare the value from the Atmel temp sensor with the TC74 that communicates with I2C as well. Not too much luck this time. Our TC74 sensor seemed to be broken, but it might also be a problem with the wires and breadboard setup. Too much bus capacitance or too low pull resistances can quickly give problems.