[Solved] I2C OLED Only Displays if Reset is Pressed??
[Solved] I2C OLED Only Displays if Reset is Pressed??
My setup:
• STM32F103C8T6
• ST Arduino core
• 0.96 SSD1306 I2C OLED
• Program: Adafruit "ssd1306_128x64_i2c" example program
The program compiles fine and uploads without issue using ST-Link and serial.
After upload, the program starts and the display works.
BUT if I disconnect the power (provided by the ST-Link or the FTDI USB to TTL adapter) then apply power, the program starts (confirmed by blinking the LED on PC13 I added to troubleshoot) and the display stays dark/off.
It doesn't show anything UNTIL I press reset, then the programs runs as expected and the display is functioning as expected.
I tried another STM32 and it did the exact same thing.
I have also used the same OLEDs on Nano, and the they functioned as expected.
I am going to dig out a logic analyzer and verify the I2C clock & data lines.
Any idea what is happening or how to resolve this?
• STM32F103C8T6
• ST Arduino core
• 0.96 SSD1306 I2C OLED
• Program: Adafruit "ssd1306_128x64_i2c" example program
The program compiles fine and uploads without issue using ST-Link and serial.
After upload, the program starts and the display works.
BUT if I disconnect the power (provided by the ST-Link or the FTDI USB to TTL adapter) then apply power, the program starts (confirmed by blinking the LED on PC13 I added to troubleshoot) and the display stays dark/off.
It doesn't show anything UNTIL I press reset, then the programs runs as expected and the display is functioning as expected.
I tried another STM32 and it did the exact same thing.
I have also used the same OLEDs on Nano, and the they functioned as expected.
I am going to dig out a logic analyzer and verify the I2C clock & data lines.
Any idea what is happening or how to resolve this?
Last edited by Franke39 on Sat Jan 16, 2021 2:01 am, edited 2 times in total.
Re: I2C OLED Only Displays if Reset is Pressed??
UPDATE from logic analyzer:
• Upon start up the OLED address (0x3C) is sent and the OLED responds with a negative acknowledgement / NAK
• After I press reset, the OLED address is sent, and the OLED responds with a positive acknowledgement / ACK
Next steps... get out the DSO and look at the raw signals.
• Upon start up the OLED address (0x3C) is sent and the OLED responds with a negative acknowledgement / NAK
• After I press reset, the OLED address is sent, and the OLED responds with a positive acknowledgement / ACK
Next steps... get out the DSO and look at the raw signals.
Re: I2C OLED Only Displays if Reset is Pressed??
Do you used a bootloader ?
Do you used PU on I2C line ?
Do you used PU on I2C line ?
Re: I2C OLED Only Displays if Reset is Pressed??
(Thanks for the quick reply!!)
Answers

(1) Before this project, I did load the "STM32duino-bootloader". I didn't want to load a ST USB driver on my Mac, so I erased it (using the STMCubeProgrammer) and reprogrammed from the Arduino IDE using the ST-Link. I believe this erases or overwrites the bootloader.
I also tried a new STM32 that has never had a boot loader flashed to it and had the same result.
(2) Yes, the OLED board uses two 4.7K pull up resistors and did function as expected on a Nano clone.
I have have powered the OLED with 5 and 3.3 volts and get the same result.
ALSO....
I have also learned that a NAK is the same as the I2C device not responding.
In the Adafruit SSD1306 example program, I put in a 1 second delay after this line:
Code: Select all
Display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
I should have it on the scope in the next hour and will update then.
Re: I2C OLED Only Displays if Reset is Pressed??
It looks like OLED controller might need more time to start then STM. Try adding delay before initializing display.
I also recommend u8g2 library. It's faster than adafruit and much more fonts. You can also create own font quite easily.
I also recommend u8g2 library. It's faster than adafruit and much more fonts. You can also create own font quite easily.
Re: I2C OLED Only Displays if Reset is Pressed??
Thanks, for the reply.GonzoG wrote: Fri Jan 15, 2021 9:14 pm It looks like OLED controller might need more time to start then STM. Try adding delay before initializing display.
I also recommend u8g2 library. It's faster than adafruit and much more fonts. You can also create own font quite easily.
Tonight I will:
• Check the I2C clock (SCK) frequency with logic analyzer. It should be 400Khz
• Scope the start up of the 3.3 rail, SCK and SDA and compare to the startup of the Nano
• Add 1 second delay at the very beginning of the program
• Try the u8g2 library
For the product I am developing, I really want to use the I2C OLEDs as I can easily display information on two 128x64 with only 4 wires.
PLUS with the I2C multiplexer, I can add up to 8 more displays.
I hope to update this thread in a few hours.

Re: I2C OLED Only Displays if Reset is Pressed??
Adding a 25ms delay right after StartUp() resolved the issue.
20ms was not enough, so I will add a buffer just in case temperature is an issue and use 100ms.
That is a long time to a uC, but the end user won't notice a slower boot up.
20ms was not enough, so I will add a buffer just in case temperature is an issue and use 100ms.
That is a long time to a uC, but the end user won't notice a slower boot up.
Re: [Solved] I2C OLED Only Displays if Reset is Pressed??
Look at this program it has ;
In instruction is says that 3 wire connection is needed but I using only 2, SDA and SCL
Code: Select all
#define OLED_RESET 4
Adafruit_SSD1306 display(OLED_RESET);
Code: Select all
#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#define OLED_RESET 4
Adafruit_SSD1306 display(OLED_RESET);
//#if (SSD1306_LCDHEIGHT != 64)
#if (SSD1306_LCDHEIGHT != 32)
///#error("Height incorrect, please fix Adafruit_SSD1306.h!");
#endif
int sensorValue = 0;
int voltage = 0;
const int analogInPin = PA7;
//display.invertDisplay(true); // invert the colours of led display
//display.invertDisplay(false);
//display.drawPixel(10, 10, WHITE);//to highlight a particular pixel
void setup()
{
display.begin(SSD1306_SWITCHCAPVCC, 0x3C); // initialize I2C addr to 0x3C ( for 128x64 Display )
display.clearDisplay(); // clear the display before starting the program to avoid adafruit splashscreen ( *we can also skip it by modifing header file )
// display.drawBitmap(x-axis position, y-axis position, bitmap data, bitmap width, bitmap height, color)
display.drawPixel(100, 15, WHITE);//to highlight a particular pixel
}
void loop()
{
display.clearDisplay();
display.setTextSize(4);
display.setTextColor(WHITE);
sensorValue = analogRead(analogInPin);
voltage = map(sensorValue, 0, 4096, 0, 3300);
display.setCursor(0, 0);
display.print(voltage);
display.display();
}
Re: [Solved] I2C OLED Only Displays if Reset is Pressed??
Can you connect OLED to PB10 and PB11 and tell me the scanner results ?
Re: [Solved] I2C OLED Only Displays if Reset is Pressed??
The number of connections/wires needed is determined by the OLED display. The Adafruit ones have a dedicated connection for reset, (and may also have optional SPI) BUT the cheaper ones don't. I am using one of the cheaper ones and it has 4 connections: ground, Vcc, SCL and SDA.
When you asked for a "scan" I assume you are asking for the results of a I2C scanner. Most I2C scanners I see, are for the Uno/Nano type boards and only look for one I2C bus. If you use that type of I2C scanner, it doesn't know to look on the second I2C bus (SCL2 @ PB10, SDA2 @ PB11)... It will only show the first I2C bus (SCL1 @ PB6, SDA1 @ PB7)
If you want to use the second I2C bus you need to add these lines before setup()
Then after setup():
I hope this helps 
When you asked for a "scan" I assume you are asking for the results of a I2C scanner. Most I2C scanners I see, are for the Uno/Nano type boards and only look for one I2C bus. If you use that type of I2C scanner, it doesn't know to look on the second I2C bus (SCL2 @ PB10, SDA2 @ PB11)... It will only show the first I2C bus (SCL1 @ PB6, SDA1 @ PB7)
If you want to use the second I2C bus you need to add these lines before setup()
Code: Select all
#define OLED_RESET -1 // use -1 if no reset pin on OLED board
// use second I2C bus on STM32F103
// TwoWire Wire2(SDA2, SCL2);
TwoWire Wire2(PB11, PB10);
Adafruit_SSD1306 Display
// below is for a 128x64 OLED. Other option is 128x32 for smaller OLED
(128, 64, &Wire2, OLED_RESET);
Code: Select all
Display1.begin(SSD1306_SWITCHCAPVCC, 0x3C); // if nothing is displayed using 0x3C, try 0x3D
// Display1
Display1.clearDisplay();
Display1.setTextSize(2);
Display1.setTextColor(WHITE, BLACK);
Display1.setCursor(0, 0 );
Display1.println("Display");
Display1.println("I2C #2 @ 3C");
Display1.display();
