Chinese 0.91" OLED display address [SOLVED] - Page 1
Forum section: electronics / general

author: mushroom
author_rank: Regular Contributor
timestamp: September 21, 2019, 05:56:08 pm
content: 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

author: Nusa
author_rank: Super Contributor
timestamp: September 21, 2019, 07:08:32 pm
content: If it's an i2c addressing problem, you can usehttps://github.com/olikraus/u8g2/wiki/u8g2reference#seti2caddressbefore 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?

author: oPossum
author_rank: Super Contributor
timestamp: September 21, 2019, 10:17:16 pm
content: The usual address of OLED using the SSD1306 controller is 0x3C (0x78 on the bus).

author: I wanted a rude username
author_rank: Frequent Contributor
timestamp: September 21, 2019, 11:43:40 pm
content: 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).

author: mushroom
author_rank: Regular Contributor
timestamp: September 22, 2019, 02:20:46 am
content: 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 -> 0x78But 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 LCDsSame 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://#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);#endifvoid 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 LCDlcd.init();lcd.backlight();lcd.setCursor(0, 0);lcd.clear();lcd.print("hello world");#endif}void loop(void){static uint8_t addr = 0x00;char buf1 = { 0 };char buf2 = { 0 };itoa(addr, buf1, 16);if(addr<=0x0F)sprintf(buf2, "0x0%s", buf1);elsesprintf(buf2, "0x%s", buf1);#ifdef LCDlcd.setCursor(0, 1);lcd.print(buf2);#endif#ifdef OLED// only the right address can be displayedoled.setI2CAddress(addr);oled.begin();// draw address on OLEDoled.setFont(u8g2_font_ncenB10_tr);oled.setDrawColor(0xFF);oled.drawStr(10, 30, buf2);oled.sendBuffer();#endifaddr = ++addr > 0x7F ? 0 : addr; // max = 127 dec.Serial.println(buf2);}

author: Ian.M
author_rank: Super Contributor
timestamp: September 22, 2019, 02:39:08 am
content: 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_41851or consider a wide range of similar products from other manufacturers.

author: Nusa
author_rank: Super Contributor
timestamp: September 22, 2019, 02:51:05 am
content: 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.

author: mushroom
author_rank: Regular Contributor
timestamp: September 22, 2019, 11:42:49 am
content: 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 :

author: mushroom
author_rank: Regular Contributor
timestamp: September 22, 2019, 12:10:02 pm
content: 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:/*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 4Adafruit_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() functionvoid loop(){static int i = 0;// text display testsdisplay.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++;}

author: Kilrah
author_rank: Unknown
timestamp: September 22, 2019, 12:29:14 pm
content: First item in the FAQ for u8g2:QuoteUse u8g2 with hardware i2c, not bit-banging like you're doing now.

author: mushroom
author_rank: Regular Contributor
timestamp: September 22, 2019, 01:02:41 pm
content: 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:/*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 LCDvoid 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 LCDlcd.init();lcd.backlight();lcd.clear();lcd.setCursor(0, 0);lcd.print("hello !");#endifdelay(3000);oled.clearDisplay();}void loop(void){static int i = 0;char buf1 = { 0 };itoa(i, buf1, 16);oled.clearDisplay();oled.setCursor(0, 20);oled.print(i);oled.sendBuffer();#ifdef LCDlcd.clear();lcd.setCursor(0, 1);lcd.print(i);#endifi++;}

author: mushroom
author_rank: Regular Contributor
timestamp: September 22, 2019, 05:45:25 pm
content: 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 !

author: ledtester
author_rank: Super Contributor
timestamp: September 22, 2019, 05:46:01 pm
content: What kind of I2C was the LCD using, hardware or software?

author: mushroom
author_rank: Regular Contributor
timestamp: September 22, 2019, 05:48:44 pm
content: I was using software, without noticing it ! Discovered this while Kilrah was posting. SW vs HW in the constructor name.

author: ledtester
author_rank: Super Contributor
timestamp: September 22, 2019, 06:19:53 pm
content: 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.

author: mushroom
author_rank: Regular Contributor
timestamp: September 22, 2019, 10:13:31 pm
content: 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 !)

author: ledtester
author_rank: Super Contributor
timestamp: September 22, 2019, 10:33:45 pm
content: Was the LCD module library using HW I2C or SW I2C?

author: mushroom
author_rank: Regular Contributor
timestamp: September 22, 2019, 11:25:05 pm
content: 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)No ! I uncommented the wrong line, it wasn't a copy/paste

author: mikerj
author_rank: Super Contributor
timestamp: September 23, 2019, 08:07:16 pm
content: Quote from: ledtester on September 22, 2019, 10:33:45 pmThree time's the charm!

author: mushroom
author_rank: Regular Contributor
timestamp: September 23, 2019, 08:51:31 pm
content: 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.