The current (v1.6.7) Arduino Wirelibrary doesn’t seem to have a convinent API to read/write from/to I2C devices. All the pieces are available but what’s lacking is a wrapper around Wire that makes it straight forward to talk to I2C slaves. I wrote one similar to the PIC code I’ve used in the past, and it’s posted here.
Initialization
The Wire interface can be initialized by calling begin(). The default speed is 100kbps, which can be increased by calling SetClock().
12
Wire.begin();Wire.setClock(400000L);// Set clock to 400kbps
Read
Reading from a slave typically consists of first sending the register ID you want to read out from followed by a repeated start condition [using endTransmission(false)]. Then you set the read bit and clock out the data [via requestFrom()].
123456789101112
voidi2c_read(byteseven_bit_address,bytereg,byte*pData,bytelen){bytei=0;Wire.beginTransmission(seven_bit_address);Wire.write(reg);Wire.endTransmission(false);// send a repreated startWire.requestFrom(seven_bit_address,len,true);// read N bytes and send a stop bitwhile(Wire.available()&&(i<len))// Copy the already read out data into our buffer{*pData++=Wire.read();i++;}}
Write
Write is self explanatory.
1234567891011121314151617
voidi2c_write(byteseven_bit_address,bytereg,byte*pData,bytelen){Wire.beginTransmission(seven_bit_address);Wire.write(reg);for(inti=0;i<len;i++){Wire.write(*pData++);}Wire.endTransmission();// send a stop}// An even simpler interface to write a bytevoidi2c_write(byteseven_bit_address,bytereg,bytevalue){Wire.beginTransmission(seven_bit_address);Wire.write(reg);Wire.write(value);Wire.endTransmission();// send a stop}
Example Usage
The code below shows how to read/write some data from/to the MAX30100 Pulse Oximetry sensor [I2C address = 0x57].
1234567891011121314151617181920212223
Serial.begin(230400);// InitializeWire.begin();Wire.setClock(400000L);// Do stuff..// Readbyteid;i2c_read(0x57,0xFF,&id,1);// Part ID register = 0xFFSerial.println("Part ID:");Serial.print(id,HEX);// expected value is 0x11// Writebytedata;data=(byte)0xA<<4|(byte)0xB;// Set the LED config register to 0xABi2c_write(0x57,0x09,&data,1);// LED config register = 0x09 // OR i2c_write(0x57, 0x09, data);// Read back and checki2c_read(0x57,0x09,&data,1);Serial.println("LED Config = ");Serial.print(data,HEX);