Skip to content

2 I2C ports #1438

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
MajicCat opened this issue May 25, 2018 · 12 comments
Closed

2 I2C ports #1438

MajicCat opened this issue May 25, 2018 · 12 comments

Comments

@MajicCat
Copy link

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 <Arduino.h>

#include <Wire.h>

#include <dummy.h> //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);

}

@stickbreaker
Copy link
Contributor

@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.

@stickbreaker
Copy link
Contributor

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

Chuck.

@MrLight
Copy link

MrLight commented Aug 27, 2018

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!

@stickbreaker
Copy link
Contributor

@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

@MrLight
Copy link

MrLight commented Aug 27, 2018

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

@stickbreaker
Copy link
Contributor

your're correct, Sorry.

Chuck.

@copercini
Copy link
Contributor

Closed as fixed =)

@richiehard
Copy link

richiehard commented Mar 19, 2020

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

@lbernstone
Copy link
Contributor

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

@richiehard
Copy link

hi @lbernstone

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

richie

@lbernstone
Copy link
Contributor

@richiehard
Copy link

super helpful, many thanks

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants