Author Topic: Chinese 0.91" OLED display address [SOLVED]  (Read 8796 times)

0 Members and 1 Guest are viewing this topic.

Offline mushroomTopic starter

  • Regular Contributor
  • *
  • Posts: 123
  • Country: fr
Chinese 0.91" OLED display address [SOLVED]
« on: September 21, 2019, 05:56:08 pm »
Hello !

ususally, I don't ask for help, I find everything on the web... But today I'm stuck. I got one of these chinese 0.91" 128x64 OLEDs, and I can't figure how to address it. If it is alone on the I²C bus, no problem. (I use u8glib).

But I need it to be in "parallel" with a 2004 LCD. As long as the OLED is alone, everything's fine. As long as the LCD is alone, no problem. But when the 2 displays are connected, only the LCD works.

I can't find the address for the OLED : scanners hang ! I found somewhere 0x3C, but it does not make any difference. It is a project based on a Blue Pill (STM32, and the "Roger" STM32Duino lib). A finite state machine (poor man's PLC). 2 displays are needed : one on the door of a large enclosure, one on the DIN rail module I'm buiding (v2.0, the 1st one used 2 LCD)...

I didn't find the answer in u8glib2. Bazilions lines, and I found nothing interesting.

Could this thingy ingnore the address, and "react" or "answer" to everything ?

Until now, I had a workaround : 2 different i²C buses. But I'm out of pins, and need a 3rd serial port... Therefore, the 2nd I²C ports have to be used for a 2nd serial (for a 2nd MAX485). I've no alternative (except maybe a 2nd MC).

Before any question :

- the I²C lines are pulled up to 3.3V (open drain outputs)
- the LCD2004 communicates through MOSFET shifters
- individually, the LCD works fine on the I²C bus
- individually, the OLED works fine on the I²C bus
- only the LCD works when all 2 displays are connected
« Last Edit: September 22, 2019, 12:49:28 pm by mushroom »
 

Offline Nusa

  • Super Contributor
  • ***
  • Posts: 2416
  • Country: us
Re: Chinese 0.91" OLED display address
« Reply #1 on: September 21, 2019, 07:08:32 pm »
If it's an i2c addressing problem, you can use https://github.com/olikraus/u8g2/wiki/u8g2reference#seti2caddress before begin for each display. Of course, that does require some knowledge of what address the display is using.

Note that the OLED will have a solder jumper on the back to change to an alternate i2c address.

The i2c module on the 2004 lcd MAY have solder jumpers...they come in many flavors, but should be easy to spot by eye if they are there.

How long is your i2c bus? There is a length limit.

What are the pull-up resistor values?
 

Offline oPossum

  • Super Contributor
  • ***
  • Posts: 1417
  • Country: us
  • Very dangerous - may attack at any time
Re: Chinese 0.91" OLED display address
« Reply #2 on: September 21, 2019, 10:17:16 pm »
The usual address of OLED using the SSD1306 controller is 0x3C (0x78 on the bus).
 

Offline I wanted a rude username

  • Frequent Contributor
  • **
  • Posts: 627
  • Country: au
  • ... but this username is also acceptable.
Re: Chinese 0.91" OLED display address
« Reply #3 on: September 21, 2019, 11:43:40 pm »
With those symptoms, I also suspect signal effects. The I²C bus is slow, so topology (star, daisy-chain, etc.) doesn't matter much, but capacitance does. Length and number of devices increase capacitance. If you find that the devices work when you switch to a slower speed (e.g. 100 kHz), then this is probably your issue, and you need to minimise bus length and maybe decrease the resistance of the pull-ups to 2 kΩ or less (there is a formula to calculate this based on bus capacitance).
 

Offline mushroomTopic starter

  • Regular Contributor
  • *
  • Posts: 123
  • Country: fr
Re: Chinese 0.91" OLED display address
« Reply #4 on: September 22, 2019, 02:20:46 am »
Yes, 0x3C (this is what I thought, and it is what I wrote).

I wrote this short program ; it sets addresses from 0x00 to 0x7F, and attempt to display the current address. Therefore, after some iterations, the address is displayed -> 0x78

But if the LCD is added, the OLED displays nothing. I'm missing something ; never had such a problem.

I can't really see what happens : just a scope ; the logic analyzer is on the way. (ordered a week ago, will take 3 or 4 more)

Wires are very short (breadboard). I already connected 2x LCD (1602 + 2004, star) with long cables (1 meter) without a problem.

The pullups were 10k, but I removed them : the OLED module already has 2x 4.7k pullups. (I found the schematics ; the address cannot be changed ; no pads nor jumpers not 0R resistors)

For some reason this OLED hates the LCDs  :-//

Same problem with Arduino Nano and Blue Pill. I ordered some other displays, they should be there within a few days :  128x32 0.91" (another one...), 128x64 0.96", and 128x64 1.3". The final project will use 128x64. I don't know if it will work with the other ones.

Code: [Select]
//#define LCD
#define OLED

#ifdef LCD
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x3F, 20, 4);
#endif

#ifdef OLED
#include <U8g2lib.h>
U8G2_SSD1306_128X32_UNIVISION_F_SW_I2C oled(U8G2_R0, A5, A4, U8X8_PIN_NONE);
#endif

void setup(void)
{
Serial.begin(115200);

#ifdef OLED
//oled.setI2CAddress(0x78);
oled.begin();
//oled.setFont(u8g2_font_ncenB10_tr);
//oled.setDrawColor(0xFF);
//oled.drawStr(10, 30, "hello world");
//oled.sendBuffer();
//delay(1000);
#endif

#ifdef LCD
lcd.init();
lcd.backlight();
lcd.setCursor(0, 0);
lcd.clear();
lcd.print("hello world");
#endif
}

void loop(void)
{
static uint8_t addr = 0x00;
char buf1[16] = { 0 };
char buf2[16] = { 0 };
itoa(addr, buf1, 16);
if(addr<=0x0F)
sprintf(buf2, "0x0%s", buf1);
else
sprintf(buf2, "0x%s", buf1);

#ifdef LCD
lcd.setCursor(0, 1);
lcd.print(buf2);
#endif

#ifdef OLED
// only the right address can be displayed
oled.setI2CAddress(addr);
oled.begin();

// draw address on OLED
oled.setFont(u8g2_font_ncenB10_tr);
oled.setDrawColor(0xFF);
oled.drawStr(10, 30, buf2);
oled.sendBuffer();
#endif

addr = ++addr > 0x7F ? 0 : addr; // max = 127 dec.

Serial.println(buf2);
}
« Last Edit: September 22, 2019, 02:49:01 am by mushroom »
 

Offline Ian.M

  • Super Contributor
  • ***
  • Posts: 12860
Re: Chinese 0.91" OLED display address
« Reply #5 on: September 22, 2019, 02:39:08 am »
An I2C multiplexer can be used to solve I2C bus address contention issues, as long as its own control address is available.   It does so by partitioning the bus and allowing your code to select which set of downstream devices are connected to the master.  This can also help with capacitive loading issues.

See: https://www.nxp.com/products/interfaces/ic-spi-serial-interface-devices/ic-multiplexers-switches:MC_41851
or consider a wide range of similar products from other manufacturers.
 
The following users thanked this post: I wanted a rude username

Offline Nusa

  • Super Contributor
  • ***
  • Posts: 2416
  • Country: us
Re: Chinese 0.91" OLED display address
« Reply #6 on: September 22, 2019, 02:51:05 am »
Confirm its a hardware problem. Write some code that only uses the OLED display, explicitly setting the address. Confirm that works. Add the LCD to the bus without trying to use it. If it still works, then it was likely a software conflict between the two packages using the same i2c.
 

Offline mushroomTopic starter

  • Regular Contributor
  • *
  • Posts: 123
  • Country: fr
Re: Chinese 0.91" OLED display address
« Reply #7 on: September 22, 2019, 11:42:49 am »
It isn't definetly not a hardware issue. I could get the 2 displays working together using the Adafruit library.

I tested every situation (precompiler soup in the source...). After the LCD is initialized, the scope shows that nothing is no ore sent to the OLED. I can see bytes only (for the LCD), not the huge graphics traffic.

The problem is u8g2lib related. Using the Adafruit SSD1306 library, the OLED can be drawn and the LCD can be written "simultaneously". At first, I was thinking of an hardware issue, or wiring issues. Reading about these cheap chinese OLED, I found that they don't aknowledge (this could explain why I²C scanners hang). Or maybe I could be using the wrong constructor...

I open an issue on Git.

Here's the display :
« Last Edit: September 22, 2019, 11:52:59 am by mushroom »
 

Offline mushroomTopic starter

  • Regular Contributor
  • *
  • Posts: 123
  • Country: fr
Re: Chinese 0.91" OLED display address
« Reply #8 on: September 22, 2019, 12:10:02 pm »
This code works fine, and is much more faster ; it uses Adafruit gfx library.
But Adafruit does not offer so much fonts and usefull functions.

Code: [Select]
/*
LcdOledAda
*/

#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <LiquidCrystal_I2C.h>

LiquidCrystal_I2C lcd(0x3F, 20, 4);

#define OLED_RESET 4
Adafruit_SSD1306 display(OLED_RESET);

void setup()
{
Serial.begin(9600);
lcd.init();
lcd.backlight();
lcd.setCursor(0, 0);
lcd.clear();
lcd.print("hello world");

// by default, we'll generate the high voltage from the 3.3v line internally! (neat!)
display.begin(SSD1306_SWITCHCAPVCC, 0x3C);  // initialize with the I2C addr 0x3C (for the 128x32)
// init done

// Show image buffer on the display hardware.
// Since the buffer is intialized with an Adafruit splashscreen
// internally, this will display the splashscreen.
display.display();
delay(2000);

// Clear the buffer.
display.clearDisplay();
}

// Add the main program code into the continuous loop() function
void loop()
{
static int i = 0;

// text display tests
display.clearDisplay();
display.setCursor(0, 0);
display.setTextSize(2);
display.setTextColor(WHITE);
display.println(i);
display.display();

lcd.setCursor(0, 0);
lcd.clear();
lcd.print(i);

delay(100);
i++;
}
 

Offline Kilrah

  • Supporter
  • ****
  • Posts: 1852
  • Country: ch
Re: Chinese 0.91" OLED display address
« Reply #9 on: September 22, 2019, 12:29:14 pm »
First item in the FAQ for u8g2:

Quote
Q: Why does my xxx_SW_I2C() device not work with my other I2C devices?
A: SW_I2C emulates I2C with digitalWrite(), which will have a conflict with other
I2C devices at the same pins. There are two options: (A) use xxx_HW_I2C() or
(B) use different pins with xxx_SW_I2C()

Use u8g2 with hardware i2c, not bit-banging like you're doing now.
 
The following users thanked this post: thm_w

Offline mushroomTopic starter

  • Regular Contributor
  • *
  • Posts: 123
  • Country: fr
Re: Chinese 0.91" OLED display address [SOLVED]
« Reply #10 on: September 22, 2019, 01:02:41 pm »
PROBLEM SOLVED !!!

It was a constructor issue !

We cross posted !

I was using U8G2_SSD1306_128X32_UNIVISION_F_SW_I2C ; found this information on the web....

I replaced with U8G2_SSD1306_128X32_UNIVISION_F_HW_I2C ; also found on the web. But now, it works, and much faster than Adafruit.

Will hardware serial related library make any difference ? AFAIK, STM32duino (Roger's core), has software I²C only. The STM32Duino forum is down since the 1st week of august because of the load on the host server.

Try this :

Code: [Select]
/*
LcdOled
*/

#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <U8g2lib.h>

LiquidCrystal_I2C lcd(0x3F, 20, 4);
//U8G2_SSD1306_128X32_UNIVISION_F_SW_I2C oled(U8G2_R0, A5, A4, U8X8_PIN_NONE);
U8G2_SSD1306_128X32_UNIVISION_F_HW_I2C oled(U8G2_R0, A5, A4, U8X8_PIN_NONE);

#define LCD

void setup(void)
{
oled.setI2CAddress(0x78);// 0x3C);
oled.begin();
oled.setFont(u8g2_font_ncenB10_tr);
oled.clear();
oled.setDrawColor(0xFF);
oled.drawStr(10, 30, "hello !");
oled.sendBuffer();
#ifdef LCD
lcd.init();
lcd.backlight();
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("hello !");
#endif
delay(3000);

oled.clearDisplay();
}

void loop(void)
{
static int i = 0;
char buf1[16] = { 0 };
itoa(i, buf1, 16);

oled.clearDisplay();
oled.setCursor(0, 20);
oled.print(i);
oled.sendBuffer();
#ifdef LCD
lcd.clear();
lcd.setCursor(0, 1);
lcd.print(i);
#endif

i++;
}
« Last Edit: September 22, 2019, 01:12:54 pm by mushroom »
 
The following users thanked this post: I wanted a rude username

Offline mushroomTopic starter

  • Regular Contributor
  • *
  • Posts: 123
  • Country: fr
Re: Chinese 0.91" OLED display address [SOLVED]
« Reply #11 on: September 22, 2019, 05:45:25 pm »
Tested on the STM32 + Roger's STM32duino : good !

Thank you all for the effort.

One more evidence that problems are mostly between the seat and the keyboard !
 

Offline ledtester

  • Super Contributor
  • ***
  • Posts: 3036
  • Country: us
Re: Chinese 0.91" OLED display address [SOLVED]
« Reply #12 on: September 22, 2019, 05:46:01 pm »
What kind of I2C was the LCD using, hardware or software?
 

Offline mushroomTopic starter

  • Regular Contributor
  • *
  • Posts: 123
  • Country: fr
Re: Chinese 0.91" OLED display address [SOLVED]
« Reply #13 on: September 22, 2019, 05:48:44 pm »
I was using software, without noticing it ! Discovered this while Kilrah was posting. SW vs HW in the constructor name.
 

Offline ledtester

  • Super Contributor
  • ***
  • Posts: 3036
  • Country: us
Re: Chinese 0.91" OLED display address [SOLVED]
« Reply #14 on: September 22, 2019, 06:19:53 pm »
I was curious what kind of I2C the LCD display was using - the one that was incompatible with the OLED display driven via SW I2C.

 

Offline mushroomTopic starter

  • Regular Contributor
  • *
  • Posts: 123
  • Country: fr
Re: Chinese 0.91" OLED display address [SOLVED]
« Reply #15 on: September 22, 2019, 10:13:31 pm »
Just a cheap LCD2004, with a PCF8574 piggyback module : the LCD/I²C displays that can be purchased for < 2$ on eBay or Aliexpress.

I also tried many LiquidCrystal_I2C libraries ; forkers don't change the name : 50+ can be found with the same name. Most of them don't work with Roger's STM32duino, and many don't have the "library.properties" file. One works fine with AVR and STM : LiquidCrystal_I2C_STM32 : https://github.com/lightcalamar/LiquidCrystal_I2C_STM32, the one I normally use for STM32 and AVR ; I obviously didn't use it for this thread. Tests (Nano) were done with the DFRobot library that comes with Arduino IDE. Code was compiled with Arduino IDE (but I'm a Visual Studio + Visual Micro user ; both are powered by gcc).

But the problem is probably on the OLED side : I read that cheap ones don't aknowledge transactions, and cause problems. Not being a "low level guy", I don't really know.

Are these informations what you need ? (not always easy to ask, describe or answer, english not being my native language !)
« Last Edit: September 22, 2019, 10:18:11 pm by mushroom »
 

Offline ledtester

  • Super Contributor
  • ***
  • Posts: 3036
  • Country: us
Re: Chinese 0.91" OLED display address [SOLVED]
« Reply #16 on: September 22, 2019, 10:33:45 pm »
Was the LCD module library using HW I2C or SW I2C?
 

Offline mushroomTopic starter

  • Regular Contributor
  • *
  • Posts: 123
  • Country: fr
Re: Chinese 0.91" OLED display address [SOLVED]
« Reply #17 on: September 22, 2019, 11:25:05 pm »
Hardware.

And by mistake I was using hardware LCD driver + the software OLED driver on the same IO pins... (some tutorial + class ctor copy/paste without noticing it was the software one :palm: )

No ! I uncommented the wrong line, it wasn't a copy/paste
« Last Edit: September 22, 2019, 11:27:30 pm by mushroom »
 
The following users thanked this post: ledtester

Offline mikerj

  • Super Contributor
  • ***
  • Posts: 3240
  • Country: gb
Re: Chinese 0.91" OLED display address [SOLVED]
« Reply #18 on: September 23, 2019, 08:07:16 pm »
Was the LCD module library using HW I2C or SW I2C?

Three time's the charm!   :clap:
 

Offline mushroomTopic starter

  • Regular Contributor
  • *
  • Posts: 123
  • Country: fr
Re: Chinese 0.91" OLED display address [SOLVED]
« Reply #19 on: September 23, 2019, 08:51:31 pm »
 :--

The question was really difficult to understand. If the LCD library was dealing with software I2C, I would have been using either SoftI2CMaster or SoftWire in the sources. It was Wire (therefore : hardware). These 2 soft wire libraries are for AVR, not STM32, the MC I had problems at first. Therefore, I thought that the question was about the LCD module hardware : PCF8574, MAX7329 or whatever. Please, be indulgent. Keep in mind that english is not my native language.
 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf