0

I've got two displays hooked up to a ESP32 via I2C and I'm using the AdaFruit library. All handling display output is packed in a own library. As I was testing I only had one display set up and everything looked fine. Now, in my actual setup with two displays, I only get the output of the first display on both screens. The displays are running on the same I2C-bus, different addresses are set. I also ran a address/portscanner that confirmed the different addresses (0x3C and 0x3D).

I have used separate displays with the AdaFruit library in such a setup before, but only on an Arduino uno and without having code moved to own libraries. So I can't tell if the ESP32 or having multiple files is messing things up or I'm missing something.

Here are parts of code in the cpp-file I used to initialize the displays and some functions I call:

#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <Wire.h>
#include <gfxfont.h>
#include <SPI.h>
#include "DisplayOut.h"
#include "Game.h"


    /* -------------esp32 Pin setup --------------------- */
    const byte displayData = 21;    // I2C SDA
    const byte displayClock = 23;   // I2C SCL
    /* --------------------------------------------------- */

// Define OLED
#define OLED_RESET displayData  
Adafruit_SSD1306 display1(OLED_RESET);
Adafruit_SSD1306 display2(OLED_RESET);



/* some variables */


void DisplayOutClass::init()
{
    // Initialize each display with i2c-address

    display1.begin(SSD1306_SWITCHCAPVCC, 0x3C);
    display2.begin(SSD1306_SWITCHCAPVCC, 0x3D);
    display1.setTextWrap(false);
    display2.setTextWrap(false);
}



void DisplayOutClass::scorePlayer1(int score1)
{
    display1.clearDisplay();

    if (gameMode == 2)
    {
        display1.clearDisplay();
        display1.setCursor(0, 0);
        display1.setTextSize(2);
        display1.setTextColor(WHITE);
        display1.print(playerName[player1]);
    }

    display1.setTextSize(4);
    display1.setTextColor(WHITE);
    display1.setCursor(getCenteredPosX(3, String(score1)), 24);
    display1.print(score1);
}

void DisplayOutClass::scorePlayer2(int score2)
{
    display2.clearDisplay();

    if (gameMode == 2)
    {
        display2.clearDisplay();
        display2.setCursor(0, 0);
        display2.setTextSize(2);
        display2.setTextColor(WHITE);
        display2.print(playerName[player2]);
    }

    display2.setTextSize(4);
    display2.setTextColor(WHITE);
    display2.setCursor(getCenteredPosX(3, String(score2)), 24);
    display2.print(score2);
}



/* some more Functions */


DisplayOutClass DisplayOut;

I didn't post the complete code or the header file, because it exceeds a few hundred lines. But this should show how the I2C-addresses are used. If necessary, I of course can post the rest of the code.

My next approach would be either trying the U8g2 library or trying start a second I2C bus. Since I already have a finished circuit board, so this would be my least preferred option.

5
  • Your reset pins are set to the number of the i2c address and you use the same reset pin for both displays? Did your read that you can make the reset pin -1 to not use it or share it with the arduino reset.
    – Jot
    Commented Feb 13, 2019 at 15:57
  • I agree with @Jot, reset pins must be separated: you are using the same pin (same define OLED_RESET), resulting reset the first display after initialized...
    – caligari
    Commented Feb 13, 2019 at 15:59
  • The displays each only have four pins: VCC, GND, SCL, SDA. So there is no reset pin. Setting OLED_RESET to -1 didn't work, neither did setting OLED_RESET to unused pins.
    – cfu479
    Commented Feb 13, 2019 at 16:16
  • Adding false to the begin-methods display1.begin(SSD1306_SWITCHCAPVCC, 0x3C, false) and display2.begin(SSD1306_SWITCHCAPVCC, 0x3D, false) to disable reset didn't bring any progress either.
    – cfu479
    Commented Feb 13, 2019 at 16:37
  • fwiw, i had to use a 2nd i2c line to get the esp32 to play nice. worked well and ended my frustration, but if there's a better way, I too am curious.
    – dandavis
    Commented Feb 13, 2019 at 19:24

1 Answer 1

0

Try the new constructors (old ones are deprecated):

Wire.begin(21, 23); // SDA, SCL

Adafruit_SSD1306 display1(SSD1306_LCDWIDTH, SSD1306_LCDHEIGHT);
Adafruit_SSD1306 display2(SSD1306_LCDWIDTH, SSD1306_LCDHEIGHT);

display1.begin(SSD1306_SWITCHCAPVCC, 0x3C);
display2.begin(SSD1306_SWITCHCAPVCC, 0x3D);


2
  • Using this with "#define SSD1306_LCDWIDTH 128" and "#define SSD1306_LCDHEIGHT 64" just gives me errors and doesn't compile, although I overwritten the library with the one from the link to be sure to have the correct version.
    – cfu479
    Commented Feb 14, 2019 at 21:10
  • Found the problem, was still using the constructor wrong. What dfid the trick was: #define OLED_RESET -1 #define SCREEN_WIDTH 128 // OLED display width, in pixels #define SCREEN_HEIGHT 64 // OLED display height, in pixels Adafruit_SSD1306 display1(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET); Adafruit_SSD1306 display2(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
    – cfu479
    Commented Feb 16, 2019 at 0:24

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.