OLED interface with High Speed Serial, i2c and Mapped i2c

OLED interface with High Speed Serial, i2c and Mapped Screen using i2c

A few months ago, I purchased RevEd's AXE133Y Serial OLED package. While the OLED unit itself is fantastic, I was a little disappointed with the 18X2 serial daughterboard. I wanted a faster and more flexible interface.

My solution was to build on the capabilities of the 20X2: High Speed background serial and i2c (slave) interfaces. Also, I could utilise the extra speed of the 20X2.

In recent weeks there has been a flourish of different ideas relating to serial and i2c interfaces for parallel-connected OLED and LCD modules. Each has its merits and I hope my design offers its own alternatives.

The pinout of the 20X2 is not as ideal as that of the 18M2: Port B has 3 pins used for hardware serial (hSerial) and i2c (hi2c) interfaces. Port C has one pin which is input-only.

After some initial speed tests, I decided to use the 4-bit parallel interface mode between the 20X2 and the Winstar OLED module. With the 4-bit interface and the PICAXE whistling along at 64MHz, the entire 16x2 screen can be updated in just over 19 milliseconds. One row can be updated in 9.58 mS: that's 1669 characters per second! So the speed of 4-bit interface is faster than my eyes. There is a minor downside to using the 4-bit interface of the Winstar - you are restricted to just 2 of the 4 available font sets. Something our continental European members should take into account.

So, the features of my design:
  • High Speed Serial interface. Works well with async serial speeds up to 76800 baud. It also works at 115200 baud and may be a little more reliable with the newer C.3 firmware, which I do not have yet.
  • i2c command mode. Accepts OLED commands and character strings into the slave's scratchpad and executes them like async serial strings. This makes a good alternative to the cheap and nasty i2c interfaces available through EBay.
  • i2c memory-mapped mode. In addition to the i2c command mode, the master device can write text directly into an area of the 20X2's scratchpad that maps via software to the OLED's 16x2 screen. This memory mapping allows strings to automatically wrap from the top row to the bottom row. It could easily be modified to work with a 20x4 row LCD or OLED. Also, due to the direct relationship between the scratchpad buffer and the OLED screen, almost all available characters (0-249 & 251-255) of the chosen font set can be used. Refer to the code, below, for more details (definition of constant cEmpty).
The design also offers three output pins for control by command (C.1 to C.3), using an identical command and data structure to RevEd's 18X2 version.

Acknowledgement. You will see pieces of Clive Seager's (RevEd's) AXE133 18M2 code in some areas of my program, so I should acknowledge the origins of some of this code.

Serial i2c OLED-v0.4.png
Pullup resistors are required on the scl and sda lines. I have assumed that they will be provided on the i2c master end.

Code to follow...
Last edited:
Code files

The code for the Serial and i2c (to 4-bit parallel) daughter board.

Added: The test code for a 20X2 used as a serial as i2c master, driving data into the daughter board. It should also work in a 28X2 or 40X2
I have been recently working on a project which closely follows your excellent design for a rotary encoder based dimmer switch using a picaxe 08m2.

When I tried to add a display I encountered a problem that the encoder code works best at 32mhz but the oled driver using the axe133 firmware runs at 16mhz. Slowing the speed down from 32 to 16 and then back to 32 seems to make the encoder slightly less responsive.

This can be solved by modifying the oled firmware to run at 32mhz which then allows communication and seems stable. However modifying the firmware to run at a changeable 16 or 32 mhz (based on hacking the 253,x control sequence to display a suitable message and then effect the speed change with the serin commands also branched between 16 and 32mhz versions) seems to also affect the stability of the display driver.

Using a 20x2 seems a nice idea and is a project for a future date but is overkill for what is required for the dimmer.
Do you have an intermediate solution using the 18m2 at 32mhz in your back catalogue of code?

Or alternatively have you evolved your 20x2 i2c solution to work with 64x48 pixel micro-oled displays or similar as these would be an ideal sized display for the project?
I'm glad someone is getting some value out of this old project of mine. I tend to develop my projects on a needs basis. And, you guessed it, I've not had a need for a pixel/graphical display yet, so can't help much there. I've never been a fan of the 18-pin PICAXEs due to their old pin arrangement, their closeness in size and the superior capabilities of the 20X2. I've even made my own "14X2" with a 20X2 SMD on a tiny adapter board.
Last edited:
Thanks for the response.

In fact I found a basic working example in a post from edmunds and have developed this on to meet requirements and now have it running on a 20M2.

The bitmaps for the character fonts together with some standard messages and ssd1306 op codes all sit nicely in the 512 byte table.

There are a few tweaks still required such as formatting to centre or left justify messages and support some graphics beyond bitmapped splash screens but with around half the memory still available this looks eminently feasible.

Unfortunately the 20x2 memory configuration seems less suited to the project due to the smaller table size (unless you know otherwise) but would have been better with its inbuilt 64mhz speed.

However this demonstrates how great the picaxe chip and picaxe forum are as I never succeeded in getting this working on certain ssd1306 based oled displays / esp8266 / esp32 combinations even after tracking down and chatting with one of the original contributors to the arduino based libraries with their thousands of lines of horrible c / c++ code!

I have even found a use for a parallel processing fractal optimizer which never solved the astrodynamics problem it was originally created for but has successfully compressed the font table from around 400 bytes down to just 46 although 100 in total including the integer only expansion algorithms and a patch table so multiple fonts a la arduino version seem do-able. Of course a more sensible solution would be to hold them in an external eeprom.

Many thanks for the inspiration from your rotary encoder / picaxe based dimmer project without which I would never have discovered the humble but very capable picaxe.