TwoWire Issue to use 2 differents I2C objects with two LCDs

Hi I'm using ESP32 with Arduino IDE. Does anyone know how you can use the TwoWire class of wire.h
There is an example of how to initialize here: ESP32 and multiple I2C buses | QuadMeUp

I need to use 2 LCD at two differents I2C ports...
//Set pins for I2C1
#define I2C1_SDA_PIN 21
#define I2C1_SCL_PIN 22

//Set pins for I2C2
#define I2C2_SDA_PIN 18
#define I2C2_SCL_PIN 219

TwoWire I2C1 = TwoWire(0); //I2C1 bus
TwoWire I2C2 = TwoWire(1); //I2C2 bus

But I don´t know how can I handle two LCD displays

LiquidCrystal_I2C lcd1(0x3F, 16, 2);
LiquidCrystal_I2C lcd2(0x27, 16, 2);

Please tell me what lines of code need to relate Wire with lcd1 and Wire1 with lcd2
Thanks in advance.

Is one LCD at 0x3F and the other at 0x27 ? Then you don't need two I2C buses. Put them on the same I2C bus.

The "TwoWire" is a lower level, which you don't have to worry about.
That example with two I2C buses is from March 2021. That is very recent, so I suppose it works. Most libraries use the Arduino default of "Wire" in the source code, and some can select the I2C bus via a pointer to a TwoWire. If you need two I2C buses (you don't), then you can pass on such a pointer or you have to change the source code of the library.

Thanks to answer. Yes, I already know that with only two lines I can connect many devices I2C. My question is How to use the two I2C that are in the ESP32, no how to connect 2 LCDs using the default two lines. Thanks

Why do you want two I2C buses ?

Since the displays have different I2C addresses, they should be connected to a single I2C bus.
I think I have already answered your question, use a TwoWire pointer or change the source code of the library.

Explanation: You have to actually tell why you want two I2C buses. If someone asks a question that seems strange, then it might be a XY-problem.

I agree with Koepel

however, what the OP is asking is how to use two LCD in two different I2C busses, we can assume that both LCDs have the same address making it to need two different I2C busses

juanpdl: the problem is that the "LiquidCrystal_I2C" library is defaulted to the main I2C bus, to change that you need to modify the "LiquidCrystal_I2C" library

LiquidCrystal_I2C::LiquidCrystal_I2C(uint8_t lcd_Addr,uint8_t lcd_cols,uint8_t lcd_rows)
  _Addr = lcd_Addr;
  _cols = lcd_cols;
  _rows = lcd_rows;
  _backlightval = LCD_NOBACKLIGHT;

and here

void LiquidCrystal_I2C::expanderWrite(uint8_t _data){                                        
	printIIC((int)(_data) | _backlightval);

and if that wasn't enough you need to modify the "wire" library to be able to create two different objects (this may need to rewrite the whole library) starting here

TwoWire Wire = TwoWire();

and becasue as you noticed none of this changes actually tells what pins to use for the busses, you also need to modify the "twi" library at least here

void twi_init(void)
  // initialize state
  twi_state = TWI_READY;
  twi_sendStop = true;		// default value
  twi_inRepStart = false;
  // activate internal pullups for twi.
  digitalWrite(SDA, 1);
  digitalWrite(SCL, 1);

  // initialize twi prescaler and bit rate
  cbi(TWSR, TWPS0);
  cbi(TWSR, TWPS1);
  TWBR = ((F_CPU / TWI_FREQ) - 16) / 2;

  /* twi bit rate formula from atmega128 manual pg 204
  SCL Frequency = CPU Clock Frequency / (16 + (2 * TWBR))
  note: TWBR should be 10 or higher for master mode
  It is 72 for a 16mhz Wiring board with 100kHz TWI */

  // enable twi module, acks, and twi interrupt

and here

void twi_disable(void)
  // disable twi module, acks, and twi interrupt
  TWCR &= ~(_BV(TWEN) | _BV(TWIE) | _BV(TWEA));

  // deactivate internal pullups for twi.
  digitalWrite(SDA, 0);
  digitalWrite(SCL, 0);

but as you can see SDA and SCL are not defined anywhere here, so you need to make sure they match the naming from the esp variant "pins_arduino.h"

#define PIN_WIRE_SDA        (2)
#define PIN_WIRE_SCL        (3)

static const uint8_t SDA = PIN_WIRE_SDA;
static const uint8_t SCL = PIN_WIRE_SCL;

the question here is: is it really worth it?

1 Like

as told by others, you could clone the LCD library to be used with

TwoWire I2C2 = TwoWire(1); //I2C2 bus

there are 6 (?) Wire. in the LiquidCrystal_I2C.cpp which need to be modified from Wire. to I2C2.

IMHO a nicer variant is, if you adopt the library so the constructor accepts not only the I2C address but also a reference to your I2C interface.

But the remaining question is
WHY do you think you need two separate I2C buses for your displays with differing I2C addresses?

Pin 219?

We haven't received @juanpdl answer to why he/she wants to use 2 x I2C when they know only one bus is needed.

I agree X-Y problem

@juanpdl can you please tell us what the application is?
What is your project trying to do?

Thanks... Tom... :smiley: :+1: :coffee: :australia:

The general development integrates many devices, so to summarize I only gave as an example having to use an LCD for each I2C bus.
In the default bus I am already using 8 I2C sensors that I cannot modify their addresses to expand them and I had the second bus available.
I did not know how much trouble I was making here if he asked a seemingly simple question.
Thanks anyway to the whole community, I put the same question in another group and several Asians could help me without asking so much because I wanted it.
I close the issue.

Thanks for the reply.
The problem we have found here is if too little information is given, solutions can go off at a tangent.
The full project story comes to light, usually two or three days or 20 or 30 replies have been sacrificed.

Have you run the I2C Scanner code to identify your I2C addresses?

Tom... :smiley: :+1: :coffee: :australia:

The ESP32 API Reference (and associated examples) describe how to use both I2C busses. But, it's a completely different paradigm than the Arduino Wire class.

Opps, forgot you are using ESP32.

Tom.. :smiley: :+1: :coffee: :australia:

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.