LCD i2c (Lib+Info+CustomCharacters)

Hitchhikers Guide to run a i2c 16x2 LiquidCrystalDisplay


First, for all, and forever: All starships “Heart of Gold” goes to @sej7278:
He helped me out and without him I were totally lost.


  • Wiring Challenge (to left the Vogon Flagship throught the air-lock)

You need 4 Wires to connect the display to your :spark: Core and one to connect the resistors with the i2c bus.

I´ll try to explain:
Important, these are not the correct 4,7K ohm resistors, only 1K Ohm!!! Do not try this. Pls, this is only a demonstration. I set up mine as a serial circuit 3,8K and 1K and it works. But it´s up to you, it´s your hardware and I´am absolutely not responsible for any damage on your core! But I think this is crystal clear. Get the right resistors to protect you from vogon poetry!

Yellow wire goes from D0 to SDA(lcd)
Purple wire goes from D1 to SCL(lcd)
White wire goes from GND to GND(lcd)
Red wire goes from VIM to VCC(LCD)
Second red wire for the red line of the breadboard.
2 4,7K ohm resistors set up to the red line of the breadboard

Here is an image from the backside of my LCD.
When things come to an end and you have to escape the well known Ravenous Bugblatter Beast of Traal, then try to rotate the poti on the i2c backpack. Contrast goes down and you can barely manage to save your poor life.


  • I2C address Challenge (to get on board of the Heart of Gold)
    I wrote another tutorial exactly about this, if you need to scan where your i2c bus is attached to, then use THIS thread.


  • Library and Example Code Challenge (to finally get Trinity)
    You now almost there. You can fly to the restaurant at the end of the universe with your girl. Think about without @sej7278 this trip would not have been possible. Again thank you and now go to:


Copy and Paste it to the :spark: Cloud IDE and finally don´t forget to edit the line of your identified i2c adress from the last step:

lcd = new LiquidCrystal_I2C(0x27, 16, 2);


  • Custom Characters Challenge (Secret Mission: Keep calm facing nuclear warheads from Magrathea)

So your LCD is running, then prepare to jump through the planets portal to meet your destiny. The 16x2 lcd have limited space. If you wrote "Temperature: " you have lost 13 chars in one line. Not pretty much space, eh? Yes that´s right but there is way to solve that. Custom Characters!
Meet the Custom Character Generator from omerk and design how you like it. New Firefox on OSx seems to have problems with this. Simple use a different browser. If you have your character designed copy the code. We need only the

byte customChar[8] = {0b…,} part

For a running example we need something like this:

// Custom Character
byte SparkChar[8]  = { 0b00000,0b10101,0b01010,0b00100,0b11111,0b00100,0b01010,0b10101 };

void setup() {
lcd->createChar(0, SparkChar);

// Setup output, this could be also used in the loop() part
lcd->setCursor(6,0 );
lcd->print("DONT PANIC");

void loop() {
 // Oh no, not again

May the Galaxy be with you!
Now you can drink your Pan Galactic Gargle Blaster and hang out with Marvin

Hope it helps somebody.
Cheers clyde


Oh one more thing… let´s say you get caught by vastly hyperintelligent pandimensional beings (white mices) you have only one chance left. Dim the light and again escape this madness!

Start - time is ticking tick tock

Let´s imagine that with the i2c you can use only 0 and 1 to activate and deactivate the backlight.
No chance to use analogWrite. But there is a solution. You only need one more wire!

  1. Have a look at the second image from my first post.
    You see the I2C backpack. On the left side there is a blue jumper that bridges to pins.
    Remove it!
  2. Wire a cable from your :spark: Core to the upper PIN
    That one directly under the label “LED”

Add this to your code

const int backlight = A0;                                   // Backlight extra pin for dimming
int mornDim  = 100;                                         // LCD backlight daylight brightness
int mornHour = 6;                                           // LCD backlight beginn hour of daylight
int eveDim   = 20;                                          // LCD backlight nighttime brightness
int eveHour  = 18;                                          // LCD backlight beginn hour of nighttime

void setup() {
pinMode(backlight, OUTPUT);                                 // Set backlight pin as output
lcd->backlight();                                           // Activate backlight

void loop() {
    if ( Time.hour() >= eveHour ) {
        analogWrite(backlight, eveDim);
    } else if ( Time.hour() <= mornHour ) {
        analogWrite(backlight, mornDim);

Now you should be able to adjust the backlight by time.
Here is another one, more straight forward.

const int backlight = A0;                            // Backlight extra pin for dimming
void setup() {
    pinMode(backlight, OUTPUT);                // Set backlight pin as output
    lcd->backlight();                                    // Activate backlight
    analogWrite(backlight, 100);                   // Modify from 0 -255

Hi @Clyde. Thanks for uploading this. I copied all three files (.cpp, .h and .ino) into the Spark IDE but when I try to verify the code I get compile errors. Any thoughts?

its builds locally and in the cloud for me, what’s test4.cpp, and did you #include "application.h" ?

Hi @sej7278

Test4 is my program name in the Spark IDE. Not sure what Test4.cpp is, probably part of the build process. Yes I included the .h file. What I did was copy each of the following files from the repo into the Spark IDE and comment out only the #include “LiquidCrystal_I2C.h” lines.


that’ll be your problem then. don’t do that.

plus you should probably delete Test4.cpp or rename LiquidCrystal_I2C_example.ino to Test4.cpp

1 Like

just bought the 20x4 version of this, so will see how that goes when it arrives, got to get it working on my raspberry pi internet radio first so the 16x2 might get relegated to spark twitter display, but i’ll at least try the new one on the spark

@clyde Thank you very much for posting this. I was having trouble with trying to get my LCD screen to work.

I am running into a small error however and being new to the Spark Core cannot seem to find whats wrong.

Hopefully this helps!

Thank you,


@busterdavidson where did you get your LiquidCrystal_I2C.h from as there is no #include “Print.h” in it, you’re not using the arduino library are you?

try the files from here

I know there is not… That is why I am frustrated about it, haha.

I copy and pasted from the links in the previous description.

Same result when I copied and pasted from the files you provided…

I read through all of it and can’t figure out why it has this idea that it is trying to get to the print.h

@busterdavidson i don’t know what to say then, it builds fine for me locally and in the IDE.

i noticed there’s a similarly-named library within the ide, maybe you’ve forked that and its buggy and conflicting with clyde’s one? you need to ensure your app is totally empty and doesn’t have extra files.

@sej7278 I changed a contributed library that I had in previously from trying to get this darn LCD screen to work. That removed the one error, but introduced more…

`In file included from ../inc/spark_wiring.h:30:0,
from ../inc/application.h:29,
from LiquidCrystal_I2C.cpp:22:
../../core-common-lib/SPARK_Firmware_Driver/inc/config.h:12:2: warning: #warning "Defaulting to Release Build" [-Wcpp]
#warning "Defaulting to Release Build"
In file included from ../inc/spark_wiring.h:30:0,
from ../inc/application.h:29,
from sparkcorelcdi2c.cpp:1:
../../core-common-lib/SPARK_Firmware_Driver/inc/config.h:12:2: warning: #warning "Defaulting to Release Build" [-Wcpp]
#warning "Defaulting to Release Build"
sparkcorelcdi2c.cpp:2:35: fatal error: lcd/LiquidCrystal_I2C.h: No such file or directory

compilation terminated.
make: *** [sparkcorelcdi2c.o] Error 1

Error: Could not compile. Please review your code.

I have no idea what this means…

I figured it out… I had one of the libraries labeled incorrectly…

Embarrassing, but it works correctly now.

@sej7278 thank you for your help.


Thx for support @sej7278 and glad to here that it works now for you @busterdavidson

@clyde, it’s a long time, but have you got a clou where the library originated from that you uploded the gist of?
It would be nice to give credit to the original author :+1:

It appears to be this from here. Alternatively, github, though I’m not sure if that’s official.

1 Like

i think @clyde modified the library from the sainsmart website linked above, which is basically the one that @mumblepins has linked to on xs4all

1 Like

Hi @ScruffR & Rest:

I really feel sorry for that, but I have no clue where I have found this piece of code. Neither do I had removed any copyrights or the author nor did I changed the code. If anyone is the author or knows the author - feel free to give me the link. Then I can change the link from this post to the origin source. Last not least and afair I do not uploaded this to Gist, because if I have done it I think I definitely have used my Git Account for that.


Thanks @clyde, @sej7278 and @mumblepins for the feedback on this.

It’s no big deal. I just got the impression that the gist may have originated from this thread since the time this thread was opened corresponds to the date given on GitHub Gist: “Anonymous created this gist on 28 May 2014, 19:18 CEST

I think Daniel (mumblepins) and sej7278 have tracked the origin down quite well.
So I just try to add a ref to the gist