functions
begin()
Initiate the Wire library and join the I2C bus as a master or slave. This should normally be called only once.
Parameters
Arduino
address: the 7-bit slave address (optional); if not specified, join the bus as a master.
ESP32
there are no address only you can select scl gpio , sda gpio and frequency
requestFrom()
Used by the master to request bytes from a slave device.
Syntax
Wire.requestFrom(address, quantity)
Wire.requestFrom(address, quantity, stop)
Parameters
address: the 7-bit address of the device to request bytes from
quantity: the number of bytes to request
stop : boolean. true will send a stop message after the request, releasing the bus. false will continually send a restart after the request, keeping the connection active.
Returns
byte : the number of bytes returned from the slave device
beginTransmission()
Begin a transmission to the I2C slave device with the given address.
Parameters :
the 7-bit address of the device to transmit to
endTransmission()
Ends a transmission to a slave device
Syntax
Wire.endTransmission()
Wire.endTransmission(stop)
Parameters
stop : boolean. true will send a stop message, releasing the bus after transmission. false will send a restart, keeping the connection active.
Returns
byte, which indicates the status of the transmission:
- 0:success
- 1:data too long to fit in transmit buffer
- 2:received NACK on transmit of address
- 3:received NACK on transmit of data
- 4:other error
write()
Writes data from a slave device in response to a request from a master, or queues bytes for transmission from a master to slave device (in-between calls to beginTransmission() and endTransmission()).
Syntax
Wire.write(value)
Wire.write(string)
Wire.write(data, length)
Parameters
value: a value to send as a single byte
string: a string to send as a series of bytes
data: an array of data to send as bytes
length: the number of bytes to transmit
Returns
byte: write() will return the number of bytes written, though reading that number is optional
available()
Returns the number of bytes available for retrieval with read(). This should be called on a master device after a call to requestFrom() or on a slave inside the onReceive() handler.
Returns
The number of bytes available for reading.
read()
Reads a byte that was transmitted from a slave device to a master after a call to requestFrom() or was transmitted from a master to a slave.
Returns
The next byte received
SetClock()
This function modifies the clock frequency for I2C communication. I2C slave devices have no minimum working clock frequency, however 100KHz is usually the baseline.
Syntax
Wire.setClock(clockFrequency)
Parameters
clockFrequency: the value (in Hertz) of desired communication clock. Accepted values are 100000 (standard mode) and 400000 (fast mode). Some processors also support 10000 (low speed mode), 1000000 (fast mode plus) and 3400000 (high speed mode). Please refer to the specific processor documentation to make sure the desired mode is supported.
onReceive()
Registers a function to be called when a slave device receives a transmission from a master.
Parameters
handler: the function to be called when the slave receives data; this should take a single int parameter (the number of bytes read from the master) and return nothing, e.g.: void myHandler(int numBytes)
onRequest()
Register a function to be called when a master requests data from this slave device.
Parameters
handler: the function to be called, takes no parameters and returns nothing
ESP32
in esp32 you can create more than one i2c bus by Create Object from TwoWire instead of using public general object Wire
The ESP32 supports I2C communication through its two I2C bus interfaces that can serve as I2C master or slave, depending on the user’s configuration. Accordingly to the ESP32 datasheet, the I2C interfaces of the ESP32 supports:
- Standard mode (100 Kbit/s)
- Fast mode (400 Kbit/s)
- Up to 5 MHz, yet constrained by SDA pull-up strength
- 7-bit/10-bit addressing mode
- Dual addressing mode. Users can program command registers to control I²C interfaces, so that they have more flexibility
The SDA and SCL lines are active low, so they should be pulled up with resistors. Typical values are 4.7k Ohm for 5V devices and 2.4k Ohm for 3.3V devices.
Most sensors we use in our projects are breakout boards that already have the resistors built-in. So, usually, when you’re dealing with this type of electronics components you don’t need to worry about this.
Connecting an I2C device to an ESP32 is normally as simple as connecting GND to GND, SDA to SDA, SCL to SCL and a positive power supply to a peripheral, usually 3.3V (but it depends on the module you’re using).
Examples
master esp32
#include <Arduino.h>
#include <Wire.h>
TwoWire i2c(0);//you can use general Wire object or create one by TwoWire
void setup(){
Serial.begin(9600);
i2c.begin(33,32,8000000);
}
void loop(){
i2c.beginTransmission(4);
i2c.write("hello there");
Serial.println("send data");
i2c.endTransmission();
delay(1000);
i2c.requestFrom(4,10,true);// true for stop connection for can use beginTransmission next time
while(i2c.available()) // slave may send less than requested
{
char c = i2c.read(); // receive a byte as character
Serial.print(c); // print the character
}
delay(5000);
}
slave arduino
#include<Wire.h>
void receiveEvent(int coutn){
while(0 < Wire.available())
{
char c = Wire.read();
Serial.print(c);
}
Serial.println("");
}
void requestEvent(int count){
Wire.write("hi how are");
Serial.println(String("master request ")+String(count));
}
void setup() {
Serial.begin(9600);
Wire.begin(4);
Wire.onReceive(receiveEvent);
Wire.onRequest(requestEvent);
}
void loop() {
delay(100);
}
Scan available addresses
#include <Wire.h>
void setup() {
Wire.begin();
Serial.begin(115200);
Serial.println("\nI2C Scanner");
}
void loop() {
byte error, address;
int nDevices;
Serial.println("Scanning...");
nDevices = 0;
for(address = 1; address < 127; address++ ) {
Wire.beginTransmission(address);
error = Wire.endTransmission();
if (error == 0) {
Serial.print("I2C device found at address 0x");
if (address<16) {
Serial.print("0");
}
Serial.println(address,HEX);
nDevices++;
}
else if (error==4) {
Serial.print("Unknow error at address 0x");
if (address<16) {
Serial.print("0");
}
Serial.println(address,HEX);
}
}
if (nDevices == 0) {
Serial.println("No I2C devices found\n");
}
else {
Serial.println("done\n");
}
delay(5000);
}