Arduino-esp32: 2 I2C ports

Created on 25 May 2018  路  12Comments  路  Source: espressif/arduino-esp32

Please fill the info fields, it helps to get you faster support ;)

If you have a Guru Meditation Error, please decode it:
https://github.com/me-no-dev/EspExceptionDecoder

----------------------------- Remove above -----------------------------

Hardware:

Board: ESP32 Pico D4 Kit
Core Installation/update date: ?11/jul/2017?
IDE name: Arduino IDE
Flash Frequency: 40Mhz
Upload Speed: 115200

Description:

I have been searching for an example of 2 concurrent I2C ports in Arduino. I have found an example 2 port scanner , but the second port does not drive any outputs to the lines.

I have tried each individually and they work fine. I have tried manually attaching and detaching a single port to see if I could simply switch with one driver, no luck.

The actual configuration will require one port to be a master and one port to be a slave.

And thoughts or insights?

Sketch:

include

include

include //for esp32

define SDA1 21

define SCL1 22

//#define SDA1 19
//#define SCL1 23

define SDA2 19

define SCL2 23

TwoWire1 I2Cone = TwoWire1(0);
TwoWire2 I2Ctwo = TwoWire2(1);

void scan1(){
Serial.println("Scanning I2C Addresses Channel 1");
uint8_t cnt=0;
for(uint8_t i=0;i<128;i++){
I2Cone.beginTransmission(i);
uint8_t ec=I2Cone.endTransmission(true);
if(ec==0){
if(i<16)Serial.print('0');
Serial.print(i,HEX);
cnt++;
}
else Serial.print("..");
Serial.print(' ');
if ((i&0x0f)==0x0f)Serial.println();
}
Serial.print("Scan Completed, ");
Serial.print(cnt);
Serial.println(" I2C Devices found.");
}

void scan2(){
Serial.println("Scanning I2C Addresses Channel 2");
uint8_t cnt=0;
for(uint8_t i=0;i<128;i++){
I2Ctwo.beginTransmission(i);
uint8_t ec=I2Ctwo.endTransmission(true);
if(ec==0){
if(i<16)Serial.print('0');
Serial.print(i,HEX);
cnt++;
}
else Serial.print("..");
Serial.print(' ');
if ((i&0x0f)==0x0f)Serial.println();
}
Serial.print("Scan Completed, ");
Serial.print(cnt);
Serial.println(" I2C Devices found.");
}

void setup(){
Serial.begin(115200);

I2Cone.begin(SDA1,SCL1,400000); // SDA pin 21, SCL pin 22 TTGO TQ
I2Ctwo.begin(SDA2,SCL2,400000); // SDA pin 5, SCL pin 4 builtin OLED

}
void loop(){

delay(500);
scan1();
Serial.println();
delay(500);

delay(500);
scan2();
Serial.println();

delay(2000);

}

Most helpful comment

@mrlight
Use the current github espressif main branch. Wire() and Wire1() are now predefined.

void setup(){
Wire.begin(SCL,SDA);
Wire1.begin(SCL1,SDA1);
}

Chuck

All 12 comments

@MajicCat When you #include <Wire.h> it assigns the first i2c hardware peripheral to Wire(). If you don't want to use Wire() you should manually call the destructor ~Wire(); That will release all of the hardware and GPIO pins, interrupt..

If you are using one of my i2c variants (stickbreaker/arduino-esp32,espressif/arduino-esp32/stickbreaker-i2c) this code will work.

TwoWire I2cOne, I2cTwo; // create variables
void setup(){
Serial.begin(115200);
~Wire(); // release hardware assignments, but Wire is still taking up RAM, because it was assign as Global

I2cOne = TwoWire(0); //initialize using the first i2c peripheral
I2cTwo = TwoWire(1); // initialize using the second i2c peripheral

I2cOne.begin(SCL1,SDA1,SPEED1); // you have to select which pins and speed
I2cTwo.begin(SCL2,SDA2,SPEED2);

}

If you just want to use both i2c peripherals, I would just use Wire() and assign the second peripheral to another TwoWire Object.

#include <Wire.h>
#define SDA2 19
#define SCL2 23

TwoWire Wire1=TwoWire(1);

void setup(){
Serial.begin(115200);
Wire.begin(); // defaults to SCL,SDA,100000hz, SCL and SDA are defined in your Board Variants pins_arduino.h file.
Wire1.begin(SCL2,SDA2,100000); // there are no defined pins for the second peripheral.
}

Chuck.

@MajicCat Also, we don't yet have an I2C slave mode that works with the Arduino code model.

Chuck.

Hi Stickbreaker,

i tried to get the second example from above running, but I don't get any data from the second i2c. Even the clock signal is not send on the specific port. I cloned your i2c branch. Can you please shortly ack that the branch is actually working and that the failure is in my setup. (the first example is not compiling for me, it fails during the variable creation)

Thanks!

@mrlight
Use the current github espressif main branch. Wire() and Wire1() are now predefined.

void setup(){
Wire.begin(SCL,SDA);
Wire1.begin(SCL1,SDA1);
}

Chuck

thanks a lot for the quick answer. I just found my failure.
It is not
Wire1.begin(SCL,SDA);
but
Wire1.begin(SDA,SCL);

From Wire.cpp:
void TwoWire::begin(int sdaPin, int sclPin, uint32_t frequency)

Thanks a lot!
Sebastian

your're correct, Sorry.

Chuck.

Closed as fixed =)

Hi to everyone,

it's been days that i'm trying to generate a secondary i2c bus to drive my DRV2605 with non hardware default i2c bus on ESP32. What i need to do is :
1- to keep going with a first i2c bus driving a MPU9250 (so using pins 21 SDA1 and 22 SCL1, let's name it Wire
2- having a second i2c bus on pins 4 SDA2 and 17 SCL2. let's name this Wire1

it looks like impossible using the library to have this
what i'm able to do is to move the original hardware i2c from 21-22 to 4-17 but this means that the original one it disappears and can't be used

this does not work for a normal single core loop, nor using two different tasks using Core1 and Core2 (and this is what i'm going to do to run two instances of Wire and use simultaneously Wire and Wire1

and keep using MPU and DRV at the same time).

i'm stuck... :roll:

i must add that i have tried to interrogate the busses ad they replied with the addresses, so it's woring, but no luck to let it work in this way simultaneously.

any ideas :?:

thanks

Richie

Here is the code --- > https://pastebin.com/mtGrWjsk

Please don't hijack issues. This one is closed.

hi @lbernstone

i'm new in here, may i open a new topic then ?
thanks

richie

super helpful, many thanks

Was this page helpful?
0 / 5 - 0 ratings