Can't drive NodeMCU ESP8266-12F built-in OLED display

Hello my friends,

I struggle to get the built in OLED display working. Most examples are based on different ESP8266 board with a separate 0.96" display, mine is integrated on the board, like this one:
image of NodeMCU ESP8266 F12

I use this source to drive the OLED display:

But it doesn't work. Flashing a simple webserver works fine, but I want to get the display working. I have no debugging tools to look for problems.
For the I2C I tried D1, D2, D3, D5, ... with no success.

I hope you can help me :slightly_smiling_face:

I found the solution!!! and oh boy, a lot of nerds tinkerers will be happy with this :grin:

The solution is:
use pin D5 and D6 for the I2C connection!

This is the pin layout for regarding my board:

I hope you'll benefit from it :wink:

2 Likes

Hi I'm facing a similar problem as you, I'll leave a link to my discussion, to put you in context

Well to make the long story short, my OLED worked(by work I mean it could turn on) , I flashed it with a deauther bin, didn't behave as expected (but still on), I unplugged it from my computer then the screen won't turn on with any code I'll put it

The board however responds to the built in led code perfectly, it's the screen the one not cooperating

Tryed the same (and others) library you tried even for differents esp8266 boards, with the same result, built in OLED screen off

Ran an I2c scan as well (one code worked and other didn't) to find out the address for sda and scl

So can you please update how you modified the OLED code to see if I'm doing something wrong? , because I also modified the ssd1306 wire function with the numbers (6,5) that correspond to sda and scl pins (even with D5 and D6 letter, in the right order)

Did you have to make modifications to the board? Add pull ups? Did the board worked but with the screen turned off?, did you have to connect scl and sda to ground? Tried other codes when it turned off?

Thank you regards

1 Like

I'm opening an old post but I have been struggling with a similar board and whenever I search for a solution I eventually end up back here. I thought it might help somebody solve their own problem with this board. I assume anyone playing with ESP8266 boards will have loaded the correct libraries in IDE

I'm using a cheap board from Aliexpress. As ever it comes with no documentation so its all a mystery.
Its advertised as 0.96" OLED ESP8266 NodeMCU Development Board Wifi Module CH340C Driver Module. It does come loaded with a message on screen saying Hello World and D5=GPIO12=SCL
D6=GPIO14=SDA which is at least a clue.
The first problem I had was no matter which board and port I selected in tools in the IDE the board would connect for a second and then disconnect and continue doing this until it often would crash my windows 10 PC. I tried it with a second windows 10 PC and also a mac with similar results.
I tried every USB lead I had to hand including several that are proven to work with a couple of Wemos d1 mini (clones) because I read that some leads have too much resistance. Sometimes I could get the Blink sketch to load and run but when I tried to load a sketch with WIFI involved it would crash.
I eventually tried powering the board with 5v via Vin and Grd pins and that worked.
I found that in tools I had to select NodeMCU 0.9(ESP-12 Module) as the board.
To get the OLED to work I downloaded ESP8266 and ESP32 OLED driver for SSD1306 displays by Thingpulse using the library manager.
In the examples sketch SSD1306SimpleDemo.ino edit line 54
instead of SSD1306Wire display(0x3c, SDA, SCL);
insert SSD1306Wire display(0x3c, 14, 12);
The 14 and 12 are the GPIO pins for the OLED. I t does not work if you use D6 and D5 instead.

Hope this useful for some other people trying to use this board.

1 Like

Sweet, finally a working solution. Thanks !

But according to documentation, GPIO14 is SCL, while GPIO12 is SDA, so definition Wire display(14, 12); means Wire display(SCL, SDA); does the SDA, SCL order matters?
P.S. Also, it works with SSD1306Wire display(0x3c, 14, 12); definition.

1 Like

Part of the confusion may be with the sketch that comes loaded on the ALI Express boards. When the board boots up, the display message shows D5=GPIO12=SCL, D6=GPIO14=SDA. In fact, D5 is GPIO14 and D6 is GPIO12. The onboard display is wired with SCA connected to GPIO14 and SCL connected to GPIO12.

1 Like

The diagram also seems to be wrong.

1 Like

I came to the same conclusion, don't see any other explanations. Btw, the board is from Ali express, of course.

Hello, I have been struggling with the module for about a day, I purchased from aliexpress, installed the necessary libraries, tested the diode flashing, it works, so I tested that the module works, but when I tried to get the display to work, it was a beam. After many attempts and searching for information from here as well. Finally it worked the right way. Toba is the correct order and manner of recording
u8g2(U8G2_R0, /* clock=/ 12, / data=/ 14, / reset=*/ U8X8_PIN_NONE);
if they are reversed, the pins do not work. I hope I have been helpful

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

U8G2_SSD1306_128X64_NONAME_F_SW_I2C
u8g2(U8G2_R0, /* clock=*/ 12, /* data=*/ 14, /* reset=*/ U8X8_PIN_NONE);   // All Boards without Reset of the Display


void setup() {
  // put your setup code here, to run once:

  u8g2.begin();

}

void loop() {
  // put your main code here, to run repeatedly:

  u8g2.clearBuffer();
  u8g2.setFont(u8g2_font_7x14B_tr);
  u8g2.drawStr(0,10,"Hello,ideaspark");
  u8g2.sendBuffer();
  delay(1000);

}

2 Likes

Thank you this worked for me. Very helpful.

For info, this did work from me:

SSD1306Wire display(0x3c, SDA, SCL)

as did

SSD1306Wire display(0x3c, D5, D6);

If you are starting from scratch do the device scan with printing to serial.
Anyway - is there a 5V output directly from usb? I thought vin is, but i have 0.2 on two devices.

VIN means Voltage Input, there is no output. USB voltage output pin has been added in NodeMCU v3

A post was split to a new topic: Error from ESP8266 in Serial Monitor: "ets Jan 8 2013,rst cause:2, boot mode:(3,6)"

HI! I finally did it! After a lot of time and a lot of headaches, I finally managed to get this library working with my NodeMCU ESP8266 with an integrated 0.96" OLED display. The solution was the following: Being a Chinese board, I didn't have much documentation about it and I discovered that the one that did exist was wrong, apparently according to the manufacturer, the SDA and SCL pins of the display were connected to pins 12 and 14 respectively. This is totally wrong, these pins are connected backwards, the SDA pin of the display is connected to pin 14 of the ESP and the SCL pin to 12. This configuration is special, so it has to be declared when programming the code. I did it by adding a single line in the setup() : Wire.begin(14, 12); With this alone it should work, in case it doesn't, you can always make sure that the I2C address of your display is correct, here is a simple code (in spanish, srry) to be able to know your I2C address:

#include <Wire.h>
void setup() {
  Wire.begin();
  Serial.begin(115200);
  Serial.println("\nStarting I2C scan...");
  byte count = 0;
  for (byte i = 1; i < 127; i++) {
    Wire.beginTransmission(i);
    if (Wire.endTransmission() == 0) {
      Serial.print("Device found at address 0x");
      Serial.println(i, HEX);
      count++;
    }
  }
  if (count == 0) {
    Serial.println("No I2C devices found.");
  } else {
    Serial.println("Scanning completed.");
  }
}
void loop() {}

If you are sure which are the pins of your screen, you can change the Wire.begin() line and add the pins of your screen, just like I did in the following way: Wire.begin(14, 12); I hope this helps you and saves you headaches lol. With this solution you can use every library that works with the SSD1306, like, for example the adafruit library! P.S. Srry for my english, i hope you can understand everything!

the best video I found for this board:

many examples

...// a mi me funciona cambiando el SDA por SCL ,, SCL = 14 , SDA 12.

// LOLIN WEMOS D1 ESP WROOM 2
//
#include <Arduino.h>
#include <U8g2lib.h>
#include <SPI.h>

U8G2_SSD1306_128X64_NONAME_F_SW_I2C u8g2(U8G2_R0, /* clock=/ 14, / data=/ 12, / reset=*/ U8X8_PIN_NONE); // All Boards without Reset of the Display

//U8G2_SSD1306_128X64_NONAME_F_SW_I2C u8g2(U8G2_R0, /* clock=/ 14, / data=/ 12, / reset=*/ U8X8_PIN_NONE);

// End of constructor list
uint8_t draw_state = 0;

void setup(void) {
u8g2.begin();
}

void loop(void) {
// picture loop
u8g2.clearBuffer();
draw();
u8g2.sendBuffer();

// increase the state
draw_state++;
if ( draw_state >= 12*8 )
draw_state = 0;

// delay between each page
delay(100);

}

void u8g2_prepare(void) {
u8g2.setFont(u8g2_font_6x10_tf);
u8g2.setFontRefHeightExtendedText();
u8g2.setDrawColor(1);
u8g2.setFontPosTop();
u8g2.setFontDirection(0);
}

void u8g2_box_frame(uint8_t a) {
u8g2.drawStr( 0, 0, "drawBox");
u8g2.drawBox(5,10,20,10);
u8g2.drawBox(10+a,15,30,7);
u8g2.drawStr( 0, 30, "drawFrame");
u8g2.drawFrame(5,10+30,20,10);
u8g2.drawFrame(10+a,15+30,30,7);
}

void u8g2_disc_circle(uint8_t a) {
u8g2.drawStr( 0, 0, "drawDisc");
u8g2.drawDisc(10,18,9);
u8g2.drawDisc(24+a,16,7);
u8g2.drawStr( 0, 30, "drawCircle");
u8g2.drawCircle(10,18+30,9);
u8g2.drawCircle(24+a,16+30,7);
}

void u8g2_r_frame(uint8_t a) {
u8g2.drawStr( 0, 0, "drawRFrame/Box");
u8g2.drawRFrame(5, 10,40,30, a+1);
u8g2.drawRBox(50, 10,25,40, a+1);
}

void u8g2_string(uint8_t a) {
u8g2.setFontDirection(0);
u8g2.drawStr(30+a,31, " 0");
u8g2.setFontDirection(1);
u8g2.drawStr(30,31+a, " 90");
u8g2.setFontDirection(2);
u8g2.drawStr(30-a,31, " 180");
u8g2.setFontDirection(3);
u8g2.drawStr(30,31-a, " 270");
}

void u8g2_line(uint8_t a) {
u8g2.drawStr( 0, 0, "drawLine");
u8g2.drawLine(7+a, 10, 40, 55);
u8g2.drawLine(7+a2, 10, 60, 55);
u8g2.drawLine(7+a
3, 10, 80, 55);
u8g2.drawLine(7+a*4, 10, 100, 55);
}

void u8g2_triangle(uint8_t a) {
uint16_t offset = a;
u8g2.drawStr( 0, 0, "drawTriangle");
u8g2.drawTriangle(14,7, 45,30, 10,40);
u8g2.drawTriangle(14+offset,7-offset, 45+offset,30-offset, 57+offset,10-offset);
u8g2.drawTriangle(57+offset2,10, 45+offset2,30, 86+offset*2,53);
u8g2.drawTriangle(10+offset,40+offset, 45+offset,30+offset, 86+offset,53+offset);
}

void u8g2_ascii_1() {
char s[2] = " ";
uint8_t x, y;
u8g2.drawStr( 0, 0, "ASCII page 1");
for( y = 0; y < 6; y++ ) {
for( x = 0; x < 16; x++ ) {
s[0] = y16 + x + 32;
u8g2.drawStr(x
7, y*10+10, s);
}
}
}

void u8g2_ascii_2() {
char s[2] = " ";
uint8_t x, y;
u8g2.drawStr( 0, 0, "ASCII page 2");
for( y = 0; y < 6; y++ ) {
for( x = 0; x < 16; x++ ) {
s[0] = y16 + x + 160;
u8g2.drawStr(x
7, y*10+10, s);
}
}
}

void u8g2_extra_page(uint8_t a)
{
u8g2.drawStr( 0, 0, "Unicode");
u8g2.setFont(u8g2_font_unifont_t_symbols);
u8g2.setFontPosTop();
u8g2.drawUTF8(0, 24, ":sun: :cloud:");
switch(a) {
case 0:
case 1:
case 2:
case 3:
u8g2.drawUTF8(a3, 36, ":umbrella:");
break;
case 4:
case 5:
case 6:
case 7:
u8g2.drawUTF8(a
3, 36, ":umbrella_with_rain_drops:");
break;
}
}

#define cross_width 24
#define cross_height 24
static const unsigned char cross_bits[] U8X8_PROGMEM = {
0x00, 0x18, 0x00, 0x00, 0x24, 0x00, 0x00, 0x24, 0x00, 0x00, 0x42, 0x00,
0x00, 0x42, 0x00, 0x00, 0x42, 0x00, 0x00, 0x81, 0x00, 0x00, 0x81, 0x00,
0xC0, 0x00, 0x03, 0x38, 0x3C, 0x1C, 0x06, 0x42, 0x60, 0x01, 0x42, 0x80,
0x01, 0x42, 0x80, 0x06, 0x42, 0x60, 0x38, 0x3C, 0x1C, 0xC0, 0x00, 0x03,
0x00, 0x81, 0x00, 0x00, 0x81, 0x00, 0x00, 0x42, 0x00, 0x00, 0x42, 0x00,
0x00, 0x42, 0x00, 0x00, 0x24, 0x00, 0x00, 0x24, 0x00, 0x00, 0x18, 0x00, };

#define cross_fill_width 24
#define cross_fill_height 24
static const unsigned char cross_fill_bits[] U8X8_PROGMEM = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x18, 0x64, 0x00, 0x26,
0x84, 0x00, 0x21, 0x08, 0x81, 0x10, 0x08, 0x42, 0x10, 0x10, 0x3C, 0x08,
0x20, 0x00, 0x04, 0x40, 0x00, 0x02, 0x80, 0x00, 0x01, 0x80, 0x18, 0x01,
0x80, 0x18, 0x01, 0x80, 0x00, 0x01, 0x40, 0x00, 0x02, 0x20, 0x00, 0x04,
0x10, 0x3C, 0x08, 0x08, 0x42, 0x10, 0x08, 0x81, 0x10, 0x84, 0x00, 0x21,
0x64, 0x00, 0x26, 0x18, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, };

#define cross_block_width 14
#define cross_block_height 14
static const unsigned char cross_block_bits[] U8X8_PROGMEM = {
0xFF, 0x3F, 0x01, 0x20, 0x01, 0x20, 0x01, 0x20, 0x01, 0x20, 0x01, 0x20,
0xC1, 0x20, 0xC1, 0x20, 0x01, 0x20, 0x01, 0x20, 0x01, 0x20, 0x01, 0x20,
0x01, 0x20, 0xFF, 0x3F, };

void u8g2_bitmap_overlay(uint8_t a) {
uint8_t frame_size = 28;

u8g2.drawStr(0, 0, "Bitmap overlay");

u8g2.drawStr(0, frame_size + 12, "Solid / transparent");
u8g2.setBitmapMode(false /* solid */);
u8g2.drawFrame(0, 10, frame_size, frame_size);
u8g2.drawXBMP(2, 12, cross_width, cross_height, cross_bits);
if(a & 4)
u8g2.drawXBMP(7, 17, cross_block_width, cross_block_height, cross_block_bits);

u8g2.setBitmapMode(true /* transparent*/);
u8g2.drawFrame(frame_size + 5, 10, frame_size, frame_size);
u8g2.drawXBMP(frame_size + 7, 12, cross_width, cross_height, cross_bits);
if(a & 4)
u8g2.drawXBMP(frame_size + 12, 17, cross_block_width, cross_block_height, cross_block_bits);
}

void u8g2_bitmap_modes(uint8_t transparent) {
const uint8_t frame_size = 24;

u8g2.drawBox(0, frame_size * 0.5, frame_size * 5, frame_size);
u8g2.drawStr(frame_size * 0.5, 50, "Black");
u8g2.drawStr(frame_size * 2, 50, "White");
u8g2.drawStr(frame_size * 3.5, 50, "XOR");

if(!transparent) {
u8g2.setBitmapMode(false /* solid /);
u8g2.drawStr(0, 0, "Solid bitmap");
} else {
u8g2.setBitmapMode(true /
transparent*/);
u8g2.drawStr(0, 0, "Transparent bitmap");
}
u8g2.setDrawColor(0);// Black
u8g2.drawXBMP(frame_size * 0.5, 24, cross_width, cross_height, cross_bits);
u8g2.setDrawColor(1); // White
u8g2.drawXBMP(frame_size * 2, 24, cross_width, cross_height, cross_bits);
u8g2.setDrawColor(2); // XOR
u8g2.drawXBMP(frame_size * 3.5, 24, cross_width, cross_height, cross_bits);
}

void draw(void) {
u8g2_prepare();
switch(draw_state >> 3) {
case 0: u8g2_box_frame(draw_state&7); break;
case 1: u8g2_disc_circle(draw_state&7); break;
case 2: u8g2_r_frame(draw_state&7); break;
case 3: u8g2_string(draw_state&7); break;
case 4: u8g2_line(draw_state&7); break;
case 5: u8g2_triangle(draw_state&7); break;
case 6: u8g2_ascii_1(); break;
case 7: u8g2_ascii_2(); break;
case 8: u8g2_extra_page(draw_state&7); break;
case 9: u8g2_bitmap_modes(0); break;
case 10: u8g2_bitmap_modes(1); break;
case 11: u8g2_bitmap_overlay(draw_state&7); break;
}
}

Translation