I have had some experience in bit banging I2C, mainly from a PC printer port. I think there are a few improvements that you could use. Firstly my initialisation routine always sends a couple of STOPs, just to try to clear the bus of any half completed communiactions. You are getting some kind of communications so this isn't your problem, but it is a good idea and can save a lot of grief. -- init I2C lines procedure i2c_init is pin_a3_direction = input -- clock high pin_a4_direction = input -- data high pin_a3 = low pin_a4 = low end procedure Secondly, your start and stop procedures always assume the state of SDA and SCL. A much better solution is to assume they will be in the wrong state. ie. Start SDA = HI SCL = HI SDA = LO SCL = LO Stop SCL = LO SDA = LO SCL = HI SDA = HI -- output a start condition procedure i2c_put_start is _i2c_wait pin_a4_direction = output -- data low _i2c_wait pin_a3_direction = output -- clock low end procedure -- output stop condition procedure i2c_put_stop is _i2c_wait pin_a4_direction = output -- data low _i2c_wait pin_a3_direction = input -- clock high _i2c_wait pin_a4_direction = input -- data high end procedure I had a lot of problems using your start method, especially if you are doing multi byte commands were a second start has to be issued. The only other thing you may want to look at is giving the slave an acknowledge. Your routine seems to do a 'i2c_put_ack' for both reading and writing. Surely you should be giving ACK's when you are receiving and waiting for ACK's when transmitting? -- write one byte to specified address procedure i2c_write_1( byte in address, byte in d1 ) is i2c_put_write_address( address ) i2c_put_data( d1 ) i2c_put_ack <-----should be getting an ACK from slave, not sending it. i2c_put_stop end procedure -- write two bytes to specified address procedure i2c_write_2( byte in address, byte in d1, byte in d2 ) is i2c_put_write_address( address ) i2c_put_data( d1 ) i2c_put_ack <----should be getting an ACK from slave, not sending it. i2c_put_data( d2 ) i2c_put_nack_stop end procedure