How to: I2C running at 10kHz

Hi All,

I thought I would share how I configured the I2C interface to work at 10kHz rather than the default 100kHz. While I'm sure it is pretty elementary to many of you, it had me stymied for longer than it should have and, as I couldn't find anyone on the internet who had documented this minor task, I thought someone should write something. Modifying Wire to parametrize bus speed is left as an exercise that may not be worth while.

The task at hand was to interface my Arduino to a PicAxe AXE033 LCD display which works at 10kHz.

This applies to Arduino-0014 running from OS X.

Modify hardware/libraries/Wire/utility/twi.h:

#ifndef TWI_FREQ
#define TWI_FREQ 100000L

#ifndef TWI_FREQ
#define TWI_FREQ 10000L  /* 10kHz */
#define PRESCALER_10KHZ 4

Modify hardware/libraries/Wire/utility/twi.c

cbi(TWSR, TWPS0);
cbi(TWSR, TWPS1);

TWBR = ((CPU_FREQ / TWI_FREQ) - 16) / 2;

/* Select 4 as the prescaler value - see page 239 of the data sheet */
cbi(TWSR, TWPS1);
sbi(TWSR, TWPS0);

  The documentation in twi.c is assuming a prescaler value of 1.  
  The actual equation (data sheet page 218) is 
      SCL Frequency = CPU Clock Frequency / (16 + (2 * TWBR * prescaler))
  For a rate of 10kHz with a clock speed of 16MHz, TWBR is 198.

For completeness, don't forget that the AXE033's documented address of 0xC6, when used with an Arduino, should be 0x63 (only use 7 bits).

The other gotcha is remembering the importance of using a common ground between the device and the Arduino. Not that I would ever make that mistake. Again.

I hope this is helpful to somebody.

Cheers, Clayton