Cheap I2C 128x64 OLED Module quick Review


When I was playing with the SeekThermal XR, I set my mind on building a temperature calibrator and for it to be of any use, it needed a display. Because the control circuitry was on a fairly small board, I wanted to use a small LCD, but having none available I ended up using a classic 16x2 HD44780 LCD. That's when I realized I need to broaden my options when it comes to cheap displays for quick projects.

It didn't took me long and I found these gems on Aliexpress for about $3.50/pcs. They're graphic, so no support for direct alpha numeric mode and they come in different colors, but usually monochrome.

The information on Aliexpress is almost always sketchy, so I went for the model that could display both blue and yellow. What I didn't know at the time is that it displays blue in the top segment (48 vertical pixels) and yellow in the bottom segment (16 vertical pixels). It actually doesn't look bad and I rather like it.

I did my best to make the pictures look as close to reality as I could, but it just didn't work, so what you're seeing in these images are very washed out colors compared to what they look like in reality. It really stands out, it's crisp and vivid.

Its footprint is almost square, measuring about 27x27mm, which compared to a classic 16x2 LCD is absolutely tiny, but can still fit a lot more information on the screen, if you're willing to deal with a small font. The actual display area measures 22x11 mm.

128x64 OLED vs 16x2 LCD

Back of the board


What can it do?

Well, as I mentioned earlier, it's a graphical display, so you can obviously display images and if you want to draw text, you have to prepare some fonts, because it won't do it natively. There seem to be quite a few libraries available for these modules, but the few I looked at, appear to be derived from the adafruit library, which unfortunately isn't sending the commands in the most efficient way and because of that a few clock cycles are wasted with almost every command. That said, I'm sure most libraries out there will do the job, just not as efficient as they could.

My suggestion is to pick up the datasheet for the SSD1306 driver and implement your own library or at least give it a good read. It's a simple interface and you'll get a much better feeling regarding what this chip can do and how to do it to squeeze the maximum performance out of it.

Now, this is not a tutorial, but there are a few things that are worth mentioning, regarding how it operates:

1) The memory is split into 8 pages of 128 bytes each and each byte represents 8 pixels. The kicker here, is that each of those 8 pixels are not following each other horizontally, but vertically, however, each group of 8 pixels is next to each other horizontally, so what you end up with are horizontal strips of 128x8 pixels each, for each of the 8 pages.

To make it a bit more clear, if you look at the image on the right, which is generated by putting the module in test mode (command 0xA5), the yellow strip at the bottom is made up of 2 pages, so 2 strips of 128x8 pixels each, while the blue part of the screen is made out of 6 pages.

2) Because of point nr. 1, you can only update a minimum of 8 pixels at a time, at an arbitrary horizontal position, with the vertical position being dictated by the page you're writing to. This means that if you want to update a single pixel, you have to either keep a local buffer, update it in the buffer and then send the updated buffer to the module, or you have to read the existing 8 pixels from the module, update them and send them back. This is obviously not necessary if you're writing new data and don't care about destroying existing one.

3) It has various addressing modes, which basically dictate how the internal pointer gets incremented when you're writing data to its memory. One of the addressing modes and my personal favorite, called the horizontal addressing mode, allows you to define subsections of the screen to write to, allowing you to easily paint small sprites, just like we used to do with games, back in the day. These subsections can span any arbitrary number of pixels horizontally and any number of pages vertically (within the limits of the display). This is useful for drawing both text and graphics.

4) The maximum I2C baudrate is 400 kbps, defined in the datasheet by a minimum cycle time of 2.5 us. Given that there are 8,192 pixels and for each byte transferred over I2C, there's an additional ACK being received, for a full display update 9,216 bits have to be clocked over I2C, which translates to a maximum refresh rate of ~43 Hz, with I2C running at 400 kbps. That's pretty good.


The only issues I faced with these modules is the fact that not all the needed I/Os are exposed. For example, in my case there is no Reset pin, which could come in handy to get the module in a known state. Lacking that, you have to write all the registers to their default values (documented in the datasheet). Another I/O that could be exposed and it's not, is the FR pin, which outputs a synchronization signal that can be used to avoid flickering.


Cheap, small footprint and a very good datasheet - hard to say anything against it. I'll buy more to use them in future projects, but next time I'll go for full monochrome ones, because I already have 5 blue/yellow units and I'll be more careful at the pins they have exposed, different vendors have different pinouts.

comments powered by Disqus