SH1106 i2c Library

Since I need all my analog inputs and i2c is on the digital pins I need a way to get a cheap oled working.
There aren’t any yet for this combo, so I guess it is on me to try and figure out.
I forked this Library as it seemed fairly simple and I understood the flow of it, so it seemed like a good place to start. (rather than u8glib)

But I am running into a problem with a class that is giving an error for “undefined reference to” class::something()
It compiled fine for arduino so it probably has something to do with the compile optimiser and the way the class is laid out. Anyone have a tip or hint on how to restructure this so that it might work?

/spark/compile_service/shared/workspace/2_compile-server2/core-firmware/build/sh1106.cpp:60: undefined reference to `sh1106_lcd::Show()'
/spark/compile_service/shared/workspace/2_compile-server2/core-firmware/build/sh1106.cpp:66: undefined reference to `sh1106_lcd::ClearScreen()'

code snip from sh1106.h

class sh1106_lcd {
    static sh1106_lcd *getInstance();

    void ClearScreen();
//   ... deleted a few out for ease of review
    void Show();
    void Initialize();
    byte SendByte(byte data, SendState state);
    byte SendCommand(byte command, SendState state = Complete);
    byte SendData(byte data, SendState state = Complete);
    void PrintData(char *data, bool incrementLine);
    static sh1106_lcd *m_pInstance;
    byte m_currentLine;
    byte m_cursor;
    byte m_screen[MAX_PAGE_COUNT][SCREEN_WIDTH]; // 1024 bytes 8 pages of 128 bits

What dev env are you using?
What is the exact problem you’ve got with I2C being on D0/D1?
Have you considered any softSPI/softI2C solutions?

If you want to prevent the optimizer to interfere, you can add this to the top of your .INO file


In this case you have to care for #include "application.h" and function prototypes yourself.

BTW: Have you seen this?

1 Like

I am using I have no problems with I2C being on D0/1 it works out great for me.

I did see that library, but since it was for SPI, i was trying to take a shortcut. I have a very poor understanding of how to approach device communications.

@officeboy, is your display SPI or I2C? If it is SPI then it would need to use some of your precious analog pins. If you want a simple to use I2C or Serial display, you may want to consider Digole smart displays. You can use one with just the Serial1 Tx line on the Core!

1 Like

I’ve not looked deeply into your library, yet. But I don’t see a big problem in porting this, but I’d rather go with Spark Dev to start with.
One of the main advantages is, the quick flashing to test your dev evolutions and you actually see what’s going on, where and how files are stored.
Web IDE seems a bit more obscure about the file handling, sometimes - especially when adding libraries :wink:

And as an additional avenue to go for, would be softSPI on any of your digital pins.
In my port of Adafruit_HX8357 (available on Web IDE), I’ve used @BDub 's softSPI code, which would quite nicely fit into the linked library too - and it’s not too difficult to understand either.
I guess there are other implementations of softSPI around too.

And of course, as I’ve just seen @peekay123 has answered as well, his advice is always worth its weight in gold

but what’s the weight of a forum post : :stuck_out_tongue_winking_eye:

Just compiled your library in Spark DEV and there were no errors - can’t test ofcourse without display :wink:

I have some i2c sh1106 displays, they say heltec on the back with a little flame logo.
Look like this or this.

I should have done more research on displays before I bought cheapies… but they are 1/2 the price.

Thanks, I have spark dev, but gave up in it as it seemed to have been stuck on compiling in cloud yesterday. (But that was with what turned out to be a not ported u8glib) :smile:

And yes, after deleting all the git stuff from my folder it did compile nicely, very strange. I wonder how it will work if added as a lib on the web ide.

If you want to put it up on the Web IDE, you have to put the library files into the firmware folder and the .INO file into the examples folder.
You also need to add a spark.json file.
Best to download one of the existing Web IDE libs from GitHub and copy the structure of it.

As for the includes in your examples, you need to write them like this

#include "library_name/library_name.h"

For convenience I usually do this


#if defined(SPARK_WEB_IDE)
#include "library_name/library_name.h"
#include "library_name/other.h"

#include "other_lib/other_lib.h"
#include "library_name.h"
#include "other.h"

#include "other_lib.h"

Then I only need to comment the #define line, when I’m in Spark Dev and uncomment for Web IDE.

1 Like

Just published it. It has seemed to be working well enough at home.

Published Library

SH1106 0.0.2
A library for the SH1106 chipset via I2C

1 Like

Where can I get a copy of the published library?


What do you mean with a copy?

If you use the Web IDE (Particle Build) you just go to the Libraries drawer and search for SH1106.
There you’ll find the library for direct use in Build, and once selected you’ll find next to the library name a GitHub icon which will lead you to the source repository.

1 Like

I am using the SH1106 library for a project with a Particle Photon and a 1.3" OLED display. I would very much like to be able to set the text cursor to a desired line (essentially having a public means of setting mCurrentLine). This would seem a generally useful feature.

Have read this bit of my post?
This would have lead you to this repository where you can find the original which you could fork or even better file an issue for the original contributor to add this feature.

If you want a quick fix, add two new file tabs with the (+) icon in top right corner of Web IDE and copy/paste the source code of the lib into these.
Then you can alter as you like.

1 Like

Thanks - that was quite helpful and the quick fix was perfect for right now. I now have a version that provides line and position control. The only thing missing for me is variable text size.