U8g2: Two/multiple OLEDs with u8g2 - small problem

Created on 26 Nov 2017  路  8Comments  路  Source: olikraus/u8g2

Dear Friends,
Sorry for bothering you with this simple issue. I have two OLED SH1106 displays connected via I2C. I have changed physical address resoldering apropiate pins on the bottom side of displays. Now I have two devices on I2C bus - 0X3C and 0X3D. The problem is that I can not use two displays the same time. It is not working. What can I do?

oleds

`#include "U8g2lib.h"

include //Library for I2C interface

U8G2_SH1106_128X64_NONAME_F_HW_I2C OLED_1(U8G2_R0, U8X8_PIN_NONE);
U8G2_SH1106_128X64_NONAME_F_HW_I2C OLED_2(U8G2_R0, U8X8_PIN_NONE);

void setup() {
u8g2_SetI2CAddress(&OLED_1, 0x3C);
u8g2_SetI2CAddress(&OLED_2, 0x3D);
OLED_1.begin();
OLED_2.begin();
OLED_1.setFont(u8g_font_6x10);
OLED_2.setFont(u8g_font_6x10);
}

void loop() {
static unsigned long oledTimer = millis(); //every 1000ms update the oled display
if (millis() - oledTimer >= 1000) {
oledTimer = millis();
drawOLED_1();
//drawOLED_2();
}
}

void drawOLED_1(void) {
char buffer[10];
OLED_1.clearBuffer(); // clear the internal memory
OLED_1.setFont(u8g_font_6x10);
OLED_1.drawStr(0, 10, "Sensor 1 -> ");
dtostrf(10, 5, 0, buffer); //print value 10
OLED_1.drawStr(80, 10, buffer);
OLED_1.sendBuffer(); // transfer internal memory to the display
}

void drawOLED_2(void) {
char buffer[10];
OLED_2.clearBuffer(); // clear the internal memory
OLED_2.setFont(u8g_font_6x10);
OLED_2.drawStr(0, 10, "Sensor 2 -> ");
dtostrf(20, 5, 0, buffer); //print value 20
OLED_2.drawStr(80, 10, buffer);
OLED_2.sendBuffer(); // transfer internal memory to the display
}`

Most helpful comment

Problem SOLVED!

Thank you olikraus:)

Below you can see working code.

#include "U8g2lib.h"
#include <Wire.h> //Library for I2C interface

U8G2_SH1106_128X64_NONAME_F_HW_I2C OLED_1(U8G2_R0, U8X8_PIN_NONE);
U8G2_SH1106_128X64_NONAME_F_HW_I2C OLED_2(U8G2_R0, U8X8_PIN_NONE);

void setup() {
  OLED_1.setI2CAddress(0x3C * 2);        //<- SOLVED it works
  OLED_2.setI2CAddress(0x3D * 2);        //<- SOLVED it works
  //u8g2_SetI2CAddress(&OLED_1, 0x3C * 2); This did not work for me
  //u8g2_SetI2CAddress(&OLED_2, 0x3D * 2); This did not work for me
  OLED_1.begin();
  OLED_2.begin();
  OLED_1.setFont(u8g_font_6x10);
  OLED_2.setFont(u8g_font_6x10);
}

void loop() {
  static unsigned long oledTimer = millis(); //every 1000ms update the oled display
  if (millis() - oledTimer >= 1000) {
    oledTimer = millis();
    drawOLED_1();
    drawOLED_2();
  }
}

void drawOLED_1(void) {
  char buffer[10];
  OLED_1.clearBuffer(); // clear the internal memory
  OLED_1.setFont(u8g_font_6x10);
  OLED_1.drawStr(0, 10, "Sensor 1 -> ");
  dtostrf(10, 5, 0, buffer); //print value 10
  OLED_1.drawStr(80, 10, buffer);
  OLED_1.sendBuffer(); // transfer internal memory to the display
}

void drawOLED_2(void) {
  char buffer[10];
  OLED_2.clearBuffer(); // clear the internal memory
  OLED_2.setFont(u8g_font_6x10);
  OLED_2.drawStr(0, 10, "Sensor 2 -> ");
  dtostrf(20, 5, 0, buffer); //print value 20
  OLED_2.drawStr(80, 10, buffer);
  OLED_2.sendBuffer(); // transfer internal memory to the display
}

All 8 comments

Try

u8g2_SetI2CAddress(&OLED_1, 0x3C2);
u8g2_SetI2CAddress(&OLED_2, 0x3D
2);

See: https://github.com/olikraus/u8g2/wiki/u8g2reference#seti2caddress

Olikraus thank you for the quick reply and help in solving the problem.

Nothing has changed. Moreover when I apply:
u8g2_SetI2CAddress(&OLED_1, 0x00);
u8g2_SetI2CAddress(&OLED_2, 0x00);
result is not observable. No reaction on I2C address changing.

After uncommenting the OLED_2
void loop() {
static unsigned long oledTimer = millis(); //every 1000ms update the oled display
if (millis() - oledTimer >= 1000) {
oledTimer = millis();
drawOLED_1();
drawOLED_2();
}
The screen is blinking every 1 second. It looks like time is shared into two subsequent processes. The info on the screen is displaying in a sequence:
Sensor 1 -> wait about 10 ms -> Sensor 2 -> wait about 990 ms->

There was a formating problem in my previous post. You must multiply the address with 2:

u8g2_SetI2CAddress(&OLED_1, 0x3C*2);
u8g2_SetI2CAddress(&OLED_2, 0x3D*2);

See: https://github.com/olikraus/u8g2/wiki/u8g2reference#seti2caddress

I did it already. The program is not responding on i2C address change. That is the problem.
In general nobody is thinking about changing the IIC address in common OLED application. People just take a display and use it without thinking about i2C. In my case it is important. Maybe there is a bug in my u8g2 lib

Ah, another issue, you should use

u8g2.setI2CAddress( 0x3C*2);
u8g2.setI2CAddress(0x3D*2);

Problem SOLVED!

Thank you olikraus:)

Below you can see working code.

#include "U8g2lib.h"
#include <Wire.h> //Library for I2C interface

U8G2_SH1106_128X64_NONAME_F_HW_I2C OLED_1(U8G2_R0, U8X8_PIN_NONE);
U8G2_SH1106_128X64_NONAME_F_HW_I2C OLED_2(U8G2_R0, U8X8_PIN_NONE);

void setup() {
  OLED_1.setI2CAddress(0x3C * 2);        //<- SOLVED it works
  OLED_2.setI2CAddress(0x3D * 2);        //<- SOLVED it works
  //u8g2_SetI2CAddress(&OLED_1, 0x3C * 2); This did not work for me
  //u8g2_SetI2CAddress(&OLED_2, 0x3D * 2); This did not work for me
  OLED_1.begin();
  OLED_2.begin();
  OLED_1.setFont(u8g_font_6x10);
  OLED_2.setFont(u8g_font_6x10);
}

void loop() {
  static unsigned long oledTimer = millis(); //every 1000ms update the oled display
  if (millis() - oledTimer >= 1000) {
    oledTimer = millis();
    drawOLED_1();
    drawOLED_2();
  }
}

void drawOLED_1(void) {
  char buffer[10];
  OLED_1.clearBuffer(); // clear the internal memory
  OLED_1.setFont(u8g_font_6x10);
  OLED_1.drawStr(0, 10, "Sensor 1 -> ");
  dtostrf(10, 5, 0, buffer); //print value 10
  OLED_1.drawStr(80, 10, buffer);
  OLED_1.sendBuffer(); // transfer internal memory to the display
}

void drawOLED_2(void) {
  char buffer[10];
  OLED_2.clearBuffer(); // clear the internal memory
  OLED_2.setFont(u8g_font_6x10);
  OLED_2.drawStr(0, 10, "Sensor 2 -> ");
  dtostrf(20, 5, 0, buffer); //print value 20
  OLED_2.drawStr(80, 10, buffer);
  OLED_2.sendBuffer(); // transfer internal memory to the display
}

:+1:

Just to complete this:

//u8g2_SetI2CAddress(&OLED_1, 0x3C * 2); 

This statement is wrong, because u8g2_SetI2CAddress expects something of type pointer to u8g2 struct, however you pass the address of a C++ class. This is illegal and breaks the code. It is required to use u8g2.GetU8g2() to get the address of the u8g2 structure first. The correct statement would look like this:

u8g2_SetI2CAddress(OLED_1.GetU8g2(), 0x3C * 2); 

As a conclusion: Do not use the address operator &, unless you exactly know what you do.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

BrickBee picture BrickBee  路  3Comments

idreamsi picture idreamsi  路  5Comments

idreamsi picture idreamsi  路  7Comments

hilsonp picture hilsonp  路  3Comments

sarwarislammoon picture sarwarislammoon  路  4Comments