WiFi LoRa 32 (V3) I2C SDA/SCL

I note that, in the pins_arduino.h file for the V3 board, entries for the I2C pins are listed as:

static const uint8_t SDA = 8;
static const uint8_t SCL = 9;

but there are no pins marked either SDA/SCL or GPIO8/GPIO9 in the V3 Pin Map, nor can I see any such pins no the board itself.

Does anyone know how one would access these pins? If it’s not possible to physically access pins 8 and 9, why do these definitions exist? How would they otherwise be used?

I realise that I don’t need to use any specific pins for the I2C bus, but I would generally try to use the default assignments provided by a manufacturer. In the present case, this doesn’t seem possible so I’m wondering why the definitions have been included.

EDITED: And now having looked at the schematic, where GPIO8 & GPIO9 are assigned to LoRa functions, I’m even more puzzled…

GPIO8-9

This may be the definition of the test version, which has not been changed later. I will submit a bug for modification later. As you think, I2C pin can be mapped to any IO.

I am also confused by this and more specifically what I2C pins I can call to use the OLED (it is I2c, no?). I’m finding the HT_ssd1306.h library a bit opaque and would like to use a more documented library (u8g2, or adafruit ssd1306), but I can’t make any headway. I’m finding many examples of people doing this with the V2 but the pinouts for V3 are completely different and don’t have any OLED/SDA or OLED/SCL pins labeled. ???

I’m using the MIT (Daniel Eichhorn) SSD1306 library with the WiFi LoRa 32 V3 board, initialising the display with:

SSD1306 myDisplay(0x3c, SDA_OLED, SCL_OLED);

The I2C pins used for the display are pins 17 (SDA_OLED) and 18 (SCL_OLED), but they are not broken out so there does not appear to be any way to use this [first] I2C bus for anything other than the on-board display. To connect any other I2C device I’ve had to declare a second bus, as something like either:

Wire1.being(SDA,SCL);

or

TwoWire I2CBus2 = TwoWire(1);
 .
 .
I2CBus2.begin(SDA,SCL,400000);

given that the first bus is identified as Wire or TwoWire(0) by default.

This is very helpful, thank you.

Since my post I’ve found success with the U8g2 library by initializing:

U8G2_SSD1306_128X64_NONAME_F_SW_I2C u8g2(U8G2_R0, /* clock=*/ 18, /* data=*/ 17, /* reset=*/ 21);

I also noticed that the 17 and 18 pins do appear to be broken out, they are pads on the bottom of the board.

Ah! Well spotted! Nicely set up for pogo-pin connectors it would seem…

17 and 18 are the i2c sda/scl pins? These pads on the bottom?

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);
youri2cdevice.begin(&Wire1);

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);
Adafruit_SSD1306 oled(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);

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

Wire1.begin(SDA, SCL);
Adafruit_SSD1306 oled2(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire1, OLED_RESET);

maybe?

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.begin(115200);
  delay(500);
  Serial.println("\nI2C Scanner");
  Serial.print("SDA : ");
  Serial.print(SDA);
  Serial.print(", SCL: ");
  Serial.println(SCL);
  Serial.println();

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

  display.init();
  display.clear();
  display.setFont(ArialMT_Plain_16);
  display.setTextAlignment(TEXT_ALIGN_LEFT);
  display.drawString(5,15,"I2C Display 1");
  display.display();

  display2.init();
  display2.clear();
  display2.setFont(ArialMT_Plain_16);
  display2.setTextAlignment(TEXT_ALIGN_LEFT);
  display2.drawString(5,15,"I2C Display 2");
  display2.display();

}

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.

1 Like