WiFi LoRa 32 (V3) I2C SDA/SCL

yes, although they are there for testing. You can solder to them but the 18 pad on my board lifted after some handling.

I’ve also noticed that works, but only the SOFTWARE I2C works, and is super slow :frowning:
If you try the _F_HW_I2C constructor (with the slightly different param order, btw!) it doesn’t work.
Any ideas why hardware I2C not usable?

I don’t know why i2c isn’t broken out better. However, esp32 boards allow for multiple buses, as mentioned by UniquePete. I found success like so:

Wire1.begin(SDA_2, SCL_2,400000);

with Wire1 being my additional bus, sda-2 and scl-2 being my desired pins, and youri2cdevice being the hardare I’m connecting.

Yes, this is exactly where my problem lies. The included oled display works with the u8g2 library and HW constructor. If I take the 2nd display on the same I2C bus, I can only use it with SW constructor. that’s too slow. hence my idea with the 2nd I2C bus. no idea if that solves my problem. If someone has already successfully implemented this (both displays run with u8g2 with HW Constructor) I would be very interested in the sketch.:pray:

If you’re able to solder to the pogos for the second display can you also manually change the address of said display?

As far as having second display on second bus: this thread seems relevant to your issue. I’m not too familiar with the U8g2 library, I quickly jumped to the Adafruit_ss1306 library which has Wire as a parameter in its constructor.

Wire.begin(SDA_OLED, SCL_OLED);

I imagine that a second display object could have a dereferenced Wire1 as an argument?

Wire1.begin(SDA, SCL);


Can either of you share working code for the V3 that would demonstrate using both the onboard and a secondary OLED display with the adafruit library?

I don’t understand how to specify the &Wire address for the onboard display (17, 18).

Bonus points for helping with my second question, if you have any ideas. :slight_smile:

[Connect WiFi LoRa 32 (v3) to TFT display via SPI?](http://How link external TFT via SPI to V3?)

I can’t give you an example using the Adafruit library, and that may simply be because the Adafruit library does not include support for the ESP32-S3 processor (I don’t know if that’s the case, but I tried to load the example provided in the IDE and couldn’t quickly get it to display anything on the onboard display—but I didn’t try very hard, it just didn’t work first time around, so I just went back to the Eichhorn SSD1306 library that I always use), but the following will write to two displays on the two I2C buses.

This is just the setup part of an I2C bus scanner that would normally use a single display, but with the few extra lines of code to define and write something to a second display:

#include <SSD1306.h>            // OLED display
#include <Wire.h>

#define SDA 19
#define SCL 20

SSD1306 display(0x3c, SDA_OLED, SCL_OLED);
SSD1306 display2(0x3c, SDA, SCL, GEOMETRY_128_64, I2C_TWO);

void setup()
  Serial.println("\nI2C Scanner");
  Serial.print("SDA : ");
  Serial.print(", SCL: ");

// Initialise the OLED displays
  Serial.println("[setup] Initialise display...");
  pinMode(RST_OLED,OUTPUT);     // GPIO16
  digitalWrite(RST_OLED,LOW);  // set GPIO16 low to reset OLED

  display.drawString(5,15,"I2C Display 1");

  display2.drawString(5,15,"I2C Display 2");


SDA_OLED, SCL_OLED and RST_OLED are all defined in the relevant pins-arduino.h file that is automatically loaded with the board definition. I2C_TWO is defined within the SSD1306 library, which automatically handles the initialisation of both buses (which involves little more than invoking the relevant begin() method on each).

Also, I don’t know whether or not there’s a way to do a hardware reset the second display—I didn’t try—all I was trying to do was to get a simple sketch that wrote to two displays on different I2C buses.

I don’t know if this helps in your situation, but it at least demonstrates the use of two OLED displays on two separate I2C buses.


Hello, thank you for the helpful post - I’m trying to do the same thing. However, with your code only the onboard ssd1306 is activating. I tried two approaches for having two i2c busses. On the second, the usb also got unnaturally hot and sometimes it would go into a cycle of restarting…
#include <Arduino.h>
#include <U8g2lib.h>
#include <Wire.h>

#define sc1_oled_scl 18
#define sc1_oled_sda 17
#define sc1_oled_rst 21

#define sc2_oled_scl 20
#define sc2_oled_sda 19

U8G2_SSD1306_128X64_NONAME_1_SW_I2C screen1(U8G2_R0, /* clock=*/sc1_oled_scl, /* data=*/sc1_oled_sda, /* reset=*/sc1_oled_rst);

U8G2_SSD1306_128X64_NONAME_1_SW_I2C screen2(U8G2_R0, /* clock=*/sc2_oled_scl, /* data=*/sc2_oled_sda, /* reset=*/U8X8_PIN_NONE);

// U8G2_SSD1306_128X64_NONAME_1_SW_I2C u8g2(U8G2_R0, /* clock=*/ SCL, /* data=*/ SDA, /* reset=*/ U8X8_PIN_NONE);   // All Boards without Reset of the Display
// U8G2_SSD1306_128X64_NONAME_1_SW_I2C u8g2(U8G2_R0, /* clock=*/ 16, /* data=*/ 17, /* reset=*/ U8X8_PIN_NONE);   // ESP32 Thing, pure SW emulated I2C

void setup()
  while (!Serial)
  Serial.println("OLED Test");

void loop()
    screen1.drawStr(0, 24, "Hello World screen 1");

    screen2.drawStr(0, 24, "Hello World screen 2");
  } while (screen1.nextPage());

Second approach:
code done by
Rui Santos

  Complete project details at https://RandomNerdTutorials.com/esp32-i2c-communication-arduino-ide/


  Permission is hereby granted, free of charge, to any person obtaining a copy

  of this software and associated documentation files.


  The above copyright notice and this permission notice shall be included in all

  copies or substantial portions of the Software.


#include <Wire.h>

#include <Adafruit_Sensor.h>

#include <Adafruit_BME280.h>

#define SDA_1 27

#define SCL_1 26

#define SDA_2 33

#define SCL_2 32

TwoWire I2Cone = TwoWire(0);

TwoWire I2Ctwo = TwoWire(1);

Adafruit_BME280 bme1;

Adafruit_BME280 bme2;

void setup() {


  Serial.println(F("BME280 test"));

  I2Cone.begin(SDA_1, SCL_1, 100000);

  I2Ctwo.begin(SDA_2, SCL_2, 100000);

  bool status1 = bme1.begin(0x76, &I2Cone);  

  if (!status1) {

    Serial.println("Could not find a valid BME280_1 sensor, check wiring!");

    while (1);



  bool status2 = bme2.begin(0x76, &I2Ctwo);  

  if (!status2) {

    Serial.println("Could not find a valid BME280_2 sensor, check wiring!");

    while (1);





void loop() {

  // Read from bme1

  Serial.print("Temperature from BME1= ");


  Serial.println(" *C");

  Serial.print("Humidity from BME1 = ");


  Serial.println(" %");

  Serial.print("Pressure from BME1 = ");

  Serial.print(bme1.readPressure() / 100.0F);

  Serial.println(" hPa");


  // Read from bme2

  Serial.print("Temperature from BME2 = ");


  Serial.println(" *C");

  Serial.print("Humidity from BME2 = ");


  Serial.println(" %");

  Serial.print("Pressure from BME2 = ");

  Serial.print(bme2.readPressure() / 100.0F);

  Serial.println(" hPa");





I’ve a similar issue, but with the DS3231 RTC. This module must be connected to the SDA and SCL pins.
The problem is that I can’t pass as arguments the new SDA and SCL pins, because the method to create the rtc is:
If I call the u8g2.begin() before, the RTC will never start (because SDA and SCL ports are been used for the u8g2 OLED display).
There are any solution to solve this? I’m stucked.

I found a solution…
SDA is the GPIO 21 and SCL the 22, and it worked, but after initialize the OLED display with “u8g2.begin()” this GPIO ports change to 15 (SCL) and 4 (SDA).
If after initialize the OLED display connect the I2C modules to 15 and 4, it works.
Other possibility is initialize the Wire library to use 15, 4 GPIO ports (with SoftWire library).
Issue explainig this GPIO port change: https://github.com/Heltec-Aaron-Lee/WiFi_Kit_series/issues/62

Hello Guys,
I am a bit confused about the conversation. So the SDA Pin is 22 and SCL is 21 or 17,18 ?? Can somebody pls explain the final pins for the I2C (I2C for external Sensors eg)

GPIO17 (SDA) & GPIO18 (SCL) are used for the I2C bus that is connected to the on-board OLED display. These GPIOs are not broken out to pins on the board, although there are pads on the bottom of the board that appear to be connected to these GPIOs.

A second I2C bus can be defined and associated with any other two available pins, restrictions on the use of individual GPIOs specified in the ESP32-S3 datasheet notwithstanding. I have used GPIO19 (SDA) & GPIO20 (SCL) in the test sketch that I previously posted. @sorin-jay suggests that using GPIO19 & GPIO20, as I have done using the SSD1306 library to drive a second OLED display, does not work when using the U82g library, but @clemenlg notes that GPIO4 (SDA) & GPIO15 (SCL) can be used with the U8g2 library. I have no doubt that there will be other pin combinations that will also work, it will just be a matter of defining the ‘second’ I2C bus appropriately.

Ok thank you for the summary :smiley:

Hello, i have the same kind of problem. I tried this :

This is a library for the BMP280 humidity, temperature & pressure sensor

Designed specifically to work with the Adafruit BMP280 Breakout

----> http://www.adafruit.com/products/2651

These sensors use I2C or SPI to communicate, 2 or 4 pins are required

to interface.

Adafruit invests time and resources providing this open source code,

please support Adafruit andopen-source hardware by purchasing products

from Adafruit!

Written by Limor Fried & Kevin Townsend for Adafruit Industries.

BSD license, all text above must be included in any redistribution


#include <Wire.h>

#include <SPI.h>

#include <Adafruit_BMP280.h>

#include “SSD1306Wire.h”

#define BMP_SCK (13)

#define BMP_MISO (12)

#define BMP_MOSI (11)

#define BMP_CS (10)

SSD1306Wire display(0x3c, SDA_OLED, SCL_OLED);

TwoWire I2Ctwo = TwoWire(1);

Adafruit_BMP280 bmp(&I2Ctwo); // I2C

//Adafruit_BMP280 bmp(BMP_CS); // hardware SPI

//Adafruit_BMP280 bmp(BMP_CS, BMP_MOSI, BMP_MISO, BMP_SCK);

void setup() {



I2Ctwo.begin(SDA, SCL);

while ( !Serial ) delay(100); // wait for native usb

Serial.println(F(“BMP280 test”));

unsigned status;

status = bmp.begin(BMP280_ADDRESS_ALT, BMP280_CHIPID);

//status = bmp.begin();

if (!status) {

Serial.println(F("Could not find a valid BMP280 sensor, check wiring or "

                  "try a different address!"));

Serial.print("SensorID was: 0x"); Serial.println(bmp.sensorID(),16);

Serial.print("        ID of 0xFF probably means a bad address, a BMP 180 or BMP 085\n");

Serial.print("   ID of 0x56-0x58 represents a BMP 280,\n");

Serial.print("        ID of 0x60 represents a BME 280.\n");

Serial.print("        ID of 0x61 represents a BME 680.\n");

while (1) delay(10);


/* Default settings from datasheet. */

bmp.setSampling(Adafruit_BMP280::MODE_NORMAL, /* Operating Mode. */

              Adafruit_BMP280::SAMPLING_X2,     /* Temp. oversampling */

              Adafruit_BMP280::SAMPLING_X16,    /* Pressure oversampling */

              Adafruit_BMP280::FILTER_X16,      /* Filtering. */

              Adafruit_BMP280::STANDBY_MS_500); /* Standby time. */


void loop() {


display.drawString(0, 10, "Left aligned (0,10)");

Serial.print(F("Temperature = "));


Serial.println(" *C");

Serial.print(F("Pressure = "));


Serial.println(" hPa");

Serial.print(F("Approx altitude = "));

Serial.print(bmp.readAltitude(1013.25)); /* Adjusted to local forecast! */

Serial.println(" m");




It compiles but when i try to upload it i have a kernel panic.
Any idea ?

You should be able to strategically comment out a few of those lines of code to identify the offending line. But having said that, I uploaded your code and all that showed in the Serial Monitor was your message “Could not find a valid BMP280 sensor…etc.” (which was no surprise because there was nothing connected to my Dev-Board). So maybe you’ve misconfigured your hardware in some way.

Kernel panic… bootloop… old version esptool? See earlier topics from past few days, it’s mentioned somewhere. May be the solution.

It’s not an old esptool version. With the same sketch without any mention of SSD1306Wire (i comment all lines related) it works fine…

hi, could u share the code about ur solution
I’m very frustrating now on this…
I had tried the solution u said, but still not working
I just want to display the time on the screen using ds3231, the arduino serial monitor can display the time but my oled on wifi lora 32 V3 cant display

Anyone have the code for DS3231 with Heltec wifi lora 32 V3
I had tried many solution but it still no working

It sounds like you are able to configure the DS3231 and display the time in the IDE Serial Monitor. So, have you tried the Examples > Heltec-Example > OLED > Simple Demo to test the OLED display? If you can do both of those, it’s not clear why you shouldn’t be able to simply combine the code from those two exercises, taking into consideration earlier posts in this thread in relation to operating the second I2C bus.

If you can successfully read the DS3231 and run the OLED Demo(s) independently, and you are still having trouble, if you post your code, someone who has not actually coded this particular configuration may still be able to help pinpoint your problem.