Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Two/multiple OLEDs with u8g2 - small problem #434

Closed
walenw opened this issue Nov 26, 2017 · 9 comments
Closed

Two/multiple OLEDs with u8g2 - small problem #434

walenw opened this issue Nov 26, 2017 · 9 comments

Comments

@walenw
Copy link

walenw commented Nov 26, 2017

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 <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() {
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
}`

@olikraus
Copy link
Owner

olikraus commented Nov 28, 2017

Try

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

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

@walenw
Copy link
Author

walenw commented Nov 28, 2017

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->

@olikraus
Copy link
Owner

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

@walenw
Copy link
Author

walenw commented Nov 29, 2017

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

@olikraus
Copy link
Owner

Ah, another issue, you should use

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

@walenw
Copy link
Author

walenw commented Nov 29, 2017

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
}

@olikraus
Copy link
Owner

olikraus commented Dec 2, 2017

👍

@olikraus olikraus closed this as completed Dec 2, 2017
@olikraus olikraus reopened this Dec 2, 2017
@olikraus olikraus closed this as completed Dec 2, 2017
@olikraus
Copy link
Owner

olikraus commented Dec 2, 2017

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.

@Denis-Alpi
Copy link

It's working well with u8x8lib for changing I2C adress (0x78 --->0x7A) on a SSD1306
u8x8_SetI2CAddress(u8x8.getU8x8(), 0x3D * 2);
Thanks to Oliver for its work
mfg / Denis

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants