Sep 252010

Ever wanted to use any pair of pins for I2C on Arduino, not just the dedicated pins on Analog 4 & 5? Me too, so I made a quick little Arduino library called “SoftI2CMaster”, available in the “blinkm-projects” Googlecode repository.

Get it here: SoftI2CMaster.h, SoftI2CMaster.cpp.

It’s still a work in progress, but it can write data pretty successfully and do it over longer cables than normal.

For the VIMBY/Scion Hackerspace Challenge, I created an array of BlinkM MaxM-powered accent lights for the device we made. Because the I2C cable was longer than a few feet, the normal Wire library that BlinkM_funcs.h uses to communicate with BlinkMs couldn’t be used. This is because the Wire library assumes a perfect bus. If there is any noise or other bus problems, the Wire library will currently lock up. For the SoftI2CMaster library, I wanted it to be very tolerant, even lazy, about bus problems and also have more tunable timing to let you slow the bus down. Of course, you still need pull-up resistors on the two lines. I’ve found using 2.2k resistors to be good.

The SoftI2CMaster API follows Wire’s API pretty closely:

  • SoftI2CMaster(sdaPin,sclPin) — create an new SoftI2CMaster for the two pins specified
  • beginTransmission(address) — begin sending data
  • send(data) — send some data (byte or byte arrays)
  • endTransmission() — stop sending data

In use it looks something like this:

#include "SoftI2CMaster.h"
const byte sdaPin = 7;
const byte sclPin = 6;
SoftI2CMaster i2c = SoftI2CMaster( sdaPin,sclPin );

i2c.beginTransmission( 9 );  // send to address 9

There is a simple demo for BlinkMs that this library currently lives in. It’s called “BlinkMSoftI2CDemo” and shows off a simplified BlinkM_funcs called “BlinkM_funcs_soft.h“. The entirely of BlinkMSoftI2CDemo is shown below.

const byte sdaPin = 7;  // digital pin 7 wired to 'd' on BlinkM
const byte sclPin = 6;  // digital pin 6 wired to 'c' on BlinkM

#include "SoftI2CMaster.h"
SoftI2CMaster i2c = SoftI2CMaster( sdaPin,sclPin );

// must define "i2c" before including BlinkM_funcs_soft.h
#include "BlinkM_funcs_soft.h"

byte blinkm_addr = 9;

void setup()
  Serial.begin( 19200 );


  for( int i=0; i< 100; i++ ) {  // flash the blinkms
    BlinkM_setRGB( blinkm_addr, 255,255,255 );
    BlinkM_setRGB( blinkm_addr, 0,0,0 );

void loop()
  byte r = random(255);
  byte g = random(255);
  byte b = random(255);
  BlinkM_setRGB( blinkm_addr, r,g,b );
  BlinkM_fadeToRGB( blinkm_addr, 0,0,0 );

void BlinkM_off(byte addr)
  BlinkM_stopScript( addr );
  BlinkM_setRGB(addr, 0,0,0 );
 Posted by at 12:14 am

  25 Responses to “SoftI2CMaster: Add I2C to any Arduino pins”

  1. Great, you have resold the problem of white noise controlling tea5767 module both lcd i2c module on LCD refresh data, thanks!

  2. Does anyone have a simple example of this library working. e.g. See slave device and display text from slave device in serial monitor.


    - John

  3. I am using your library to run a IMU digital combo board (6 degrees) with an adxl345 accel and ITG3200 gyro, on an Arduino LilyPad Simple board. The gyro works fine with your code but I am not able to read values from the accelerometer. I tested it on an Arduino Mega board with the Wire library and it worked fine. Can you please suggest what might be the problem? I really need help urgently…
    IMU board link –

  4. Can I use SoftI2CMaster to creat two I2C to control two devices which have a same device address ? For example :
    #include “SoftI2CMaster.h”
    const byte sdaPin1 = 7;
    const byte sclPin1 = 6;
    const byte sdaPin2 =3;
    const byte sclPin2 =2;
    SoftI2CMaster i2c1 = SoftI2CMaster( sdaPin1,sclPin1 );
    SoftI2CMaster i2c2 = SoftI2CMaster( sdaPin2,sclPin2 );

  5. Hi YangSong,
    Yes, that should work.

 Leave a Reply



You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>