OLED display with 4-wire SPI mode, but without CS

I bought the cheapest 1.3" OLED 128x64 display on Ebay. It has a 4-wire SPI mode, but the CS is fixed to ground.
Most libraries have a bad result, but the u8glib is almost working, only the characters are shifted some to the left.

Is this easy to fix in the library, or is there another library for it ?

Details for this display:
128x64 pixels
manufacturer: heltec http://heltec.taobao.com
The BS0,BS1,BS2 are connected to ground, so it is a 4-wire SPI interface.
On Ebay it is sometimes said that the driver IC is a SH1106, but the 128x64 display of this manufacturer has always the SSD1306 driver chip.
The labels on the board are wrong, the ‘sda’ is the data_in and the ‘scl’ is the clock. It is not possible to set it in I2C mode, since the BS0,BS1,BS2 are connected to ground and can not be changed.

What happens if you remove the 0 ohm jumper? Does CS/ work then?

I think your display really has a SH1106 controller. It is similar, but not identical to the SSD1306.

  1. Locate file u8g_dev_ssd1306_128x64.c
  2. Find line 183:
  0x000,		/* set lower 4 bit of the col adr to 4  */
  1. Change this to
  0x004,		/* set lower 4 bit of the col adr to 4  */


CrossRoads, If I remove the 0 ohm, I should be able to solder a wire to CS. But it is working without CS now.

olikraus, Thank you so much! Value 0x002 worked. So now my cheap display is fully working.

I'm testing now to see what it can do. It doesn't seem to have contrast.

Good to read that your display is working. I am also glad that U8glib supports this controller with minor modifications. The 0x004 was a wild guess, based on your picture. Excellent, that you figured out the correct value.


With hardware SPI, sometimes a mismatch could occur. But using the RST with the third parameter fixed it.

Software SPI : okay
Hardware SPI : okay with RST connected and used as third parameter.

FPS sketch with Arduino Uno and Hardware SPI with RST to pin 2:
U8GLIB_SSD1306_128X64 u8g(10, 9, 2); // HW SPI Com
draw clip test : 038.4
clear screen : 005.3
draw @ : 007.8
draw pixel : 002.5

When I use 50ns instead of 300ns for the SPI clock cycle, the values are about 4% higher.

Using Software SPI
U8GLIB_SSD1306_128X64 u8g(13, 11, 10, 9, 2); // SW SPI Com
draw clip test : 026.3
clear screen : 005.0
draw @ : 007.2
draw pixel : 002.4

The ‘2X’ has higher fps
U8GLIB_SSD1306_128X64_2X u8g(10, 9, 2); // HW SPI Com
draw clip test : 047.9
clear screen : 007.9
draw @ : 011.8
draw pixel : 004.7

Thanks for providing the values. Hope speed is sufficient for you.


Hi Oliver, Any chance you could officially add this device to the library?

  • Lars

LarsSorensen, if you look at the source development, you can see that Oliver is already working on the SH1106. XD For now, you only have to change that value in the library to 0x002, as you can read in the posts above.

I have added this as issue 240 to u8glib: http://code.google.com/p/u8glib/issues/detail?id=240. Not sure when i will be able to release a new version.


Sounds great. I would like to not have to alter the SSD1306 device in the library, as I have many SSD1306 devices laying around.

It will still take some time to the next release. Until then, i suggest to alter that one number on the source code as described above.


Hi guys, I've got the same display but I don't know how to wire it, somebody can help me? I would like to use it with an arduino mega.

With the U8glib you can use the hardware SPI signals, but also any pin using software toggling.
I suggest to use the software toggle.

I did this:
U8GLIB_SSD1306_128X64 u8g(13, 11, 10, 9, 2); // SW SPI Com

Find 5 unused pins.
You have to use an Arduino pin for chip-select (I used pin 10), but that is not connected to the display.

Connect it like this:
U8GLIB_SSD1306_128X64 u8g( SCL, SDA, , D/C, RST);
The display label ‘SCL’ is the clock, ‘SDA’ is the data.

Let me know if it works.

I uncommented that line U8GLIB_SSD1306_128X64 u8g(13, 11, 10, 9); in the Hello word example and connect th wires like these:

Mega OLED 13 SCL 11 SDA 10 - 9 D/C 2 RST

I also tried like that

Mega OLED 21 SCL 20 SDA 9 D/C 2 RST

but they doesn't work. What could be the problem? Why need to use an Arduino pin for chip-select, if it isn't connected to the display?

You have to add the extra parameter for the RST wire. That is an extra fifth parameter to the line that you have uncommented.

Connect also GND to GND and VCC to 5V. Do you see something ? If you don't see anything, please attach a photo of your display on both sides and a photo of your wiring.

The library uses that chip-select. Even if it is not used.

I forgot to add the fifth parameter to the line. Thank you very much it's working.

I changed that line to this: U8GLIB_SSD1306_128X64 u8g(21, 20, 10, 9, 2); because the mega SCL is on the 21 pin and the SDA is on the 20 pin.

Well done. I'm glad it is working.

But please don't use pin 20 and 21, use those for the I2C bus. http://arduino.cc/en/reference/wire

Yours and my OLED display have the wrong labels. 'SCL' is actually the clock of a SPI interface. 'SDA' is actually the data of a SPI interface. The labels are wrong, that is one of the reasons why it is so cheap :grin: The 'D/C' and 'RST' labels are correct.

If you would use the hardware SPI bus of the Mega, you can increase the speed a little. But using software SPI on any pin is a lot easier and that is what you are using at the moment. http://arduino.cc/en/Main/arduinoBoardMega

This thread came at the perfect time for me. I just purchased ten 128X32 displays from a distributer on aliexpress for about $2.50 a piece. They were advertised as SSD1306 but when I tried them out with the adafruit oled library they didn't work. The screen was all garbled but I could see the graphics in the example sketch running at the bottom of the screen. I thought perhaps the reason the displays were so cheap were that they were defective. Thankfully I came across this thread and tried out the u8glib. I changed the line:

0x000,              /* set lower 4 bit of the col adr. to 4  */


0x004,              /* set lower 4 bit of the col adr. to 4  */

(0x002 didn't quite shift the text over enough to get it on the screen)

and then ran the "Hello World!" example. It is running like a top now! Still doesn't work with the adafruit library but I'm sure I could dig in to it and find the line that needs to be changed. For now I am comfortable just using the u8glib :-)

I'm curious where in the library the internal charge pump is enabled. I found this line:

 0x08d, 0x010,          /* [2] charge pump setting (p62): 0x014 enable, 0x010 disable */

but I notice that it doesn't make a difference whether I use 0x010 or 0x014. It works either way. What if I wanted to use an external supply to drive the display (not that I want to….just curious)?