LCD I2C CustomCharacters freezing screen

Hello everyone

I’ve been trying to develop some custom characters on my LCD screen with an I2C backpack. I have spent a fair amount of time trying to isolate the issue and resolve it but have drawn a blank an help will be much appreciated.

When I simply use the “LIQUIDCRYSTAL_I2C_SPARK” library which is public available for all users to display text it works fine. When I attempt to use the command createChar it freezes my screen. For example if I place it in the setup function it stops writing text to LCD screen after the createChar function. It will write “Hi here is my custom character” then nothing more. The ordering of the createChar function does not solve the freezing problem it simply dictates where it will freeze.

When I tried to make the board LED turn on after using the createChar command the light would not light up.

The public library I am trying to use is located here: https://github.com/BulldogLowell/LiquidCrystal_I2C_Spark

void setup(void)
    {
      Serial.begin(9600);
      lcd = new LiquidCrystal_I2C(0x27, 20, 4);
      //lcd->begin(20,4); 
      lcd->init();
      lcd->backlight();
      lcd->clear();
      byte customChar[8]  = { 0b00000,0b10101,0b01010,0b00100,0b11111,0b00100,0b01010,0b10101 };
      lcd->print("Hi here is my custom");
      lcd->print("character: ");
      delay(10000);
      lcd->createChar(0, customChar);
      lcd->print("Any more text?");
      digitalWrite(13, HIGH);
    //lcd->write(uint8_t(0));
    }

Thanks in advance

Inserting the delay (as in your pull request) didn’t work?

No it didn’t. I looked at the library I was using on my Arduino Uno and that had the 2 delays I inserted I then tried removing the delays from this offline library used with my Arduino Uno and it the same issue occurred. When the delays are present the Arduino worked fine with the createChar() function. That is why I thought the delay was necessary.

Still no success though it does not work with the 2 delays included.

Has anyone been able to get custom characters working on their device? Any of those working with an LCD screen that has a I2C backpack?

yes, I am using custom chars with the I2C backpack and the LiquidCrystal_I2C_Spark library.

Are you certain you are creating the character with correct scope?

also, try to create your custom char like this:

uint8_t  downLoadArrow[8] =
{
  0b00100,
  0b00100,
  0b00100,
  0b00100,
  0b10101,
  0b01110,
  0b00100,
  0b00000
};

and create thusly:


lcd->createChar(0, downLoadArrow);

and NOT cast it later:

lcd->write(0);

i seem to recall having similar problems with data types when I first tweaked that I2C library, now some time ago…

Here the the code I am using in the entirety of it. I did also try assigning the custom character to memory 0 but that gave the same result.

    // This #include statement was automatically added by the Particle IDE.
#include "LiquidCrystal_I2C_Spark/LiquidCrystal_I2C_Spark.h"

//error occurs when createChar() function is uncommented and allowd to run.
LiquidCrystal_I2C *lcd;

int lastSecond = 0;

void setup(void)
{
  Serial.begin(9600);
  lcd = new LiquidCrystal_I2C(0x27, 20, 4);
  lcd->begin(20,4); 
  lcd->init();
  lcd->backlight();
  lcd->clear();
  uint8_t  downLoadArrow[8] =
{
  0b00100,
  0b00100,
  0b00100,
  0b00100,
  0b10101,
  0b01110,
  0b00100,
  0b00000
};
  lcd->print("Hi here is my custom");
  lcd->print("character: ");
  lcd->createChar(1, downLoadArrow);
  lcd->print("Any more text?");
  digitalWrite(13, HIGH);
  lcd->write(1);
}

void loop(void){ 
    //lcd->print("Hi there?");
    }

I have attached a picture of the LCD screen and board so you can see the result of the above code. You can also note on the Spark Core in the back drop that there is no board LED on. Suggesting that it does not merely “skip” that function or and continue on with the code but the code appears to stop running there as my board LED works in other situations.

Thank you I appreciate you getting back to me.

I noticed the lack of Pullup Resistors on the I2C lines

try:
1: making the char a global var
2: creating the custom char before calling init()

Thank you Bulldog that has definitely improved the result.

The code now runs to completetion no problem and the custom character is created. It just isn’t rendered or created “correctly”. You can see this in the photo I have included.

I had a similar issue on my Arduino Uno and the way I resolved it on the Arduino Uno is to run lcd.begin(20,4); or whatever your screen size is. If lcd.begin(20,4); runs BEFORE you create the custom character [createChar()] the custom character works. If lcd.begin(20,4); does not run before [createChar()] then all you you see on the LCD screen is 4 rows of bars in every second row of the character cell. I can attach a picture if you desire but it looked similar to the photo attached. After reading up on this issue I discovered that lcd.begin(20,4); needed to run first. When I did that on the Arduino Uno it worked fine. I have tried using the lcd.begin(20,4); as well as init() to no avail on the Spark Core.

From the code you can see I tried to create 2 different characters both looking different but they both appeared the same on the LCD screen suggesting that it is not in the array.

Here is the code I was using for reference:

   // This #include statement was automatically added by the Particle IDE.
#include "LiquidCrystal_I2C_Spark/LiquidCrystal_I2C_Spark.h"
LiquidCrystal_I2C *lcd;
uint8_t customChar[8] = {
	0b00000,
	0b01010,
	0b01010,
	0b00000,
	0b10001,
	0b11111,
	0b01110,
	0b00000
};

uint8_t  downLoadArrow[8] =
{
  0b00100,
  0b00100,
  0b00100,
  0b00100,
  0b10101,
  0b01110,
  0b00100,
  0b00000
};

void setup(void)
{
  lcd = new LiquidCrystal_I2C(0x27, 20, 4);
  lcd->createChar(0, customChar);
  lcd->createChar(1, downLoadArrow);
  lcd->init();
  lcd->backlight();
  lcd->clear();
  lcd->print("Hi here is my custom");
  lcd->setCursor(0,1);
  lcd->print("character: ");
  lcd->write((uint8_t)0);
  lcd->setCursor(0,2);
  lcd->print("Second: ");
  lcd->write((uint8_t)1);
}

void loop(void){ 
    //lcd->print("Hi there?");
    }

Curiously though the very first time I ran the code with a global variable and creating the character before init() it worked the second time it ran (no different code) the top half did not work and the bottom did. After that though I have consistently been getting the above results.

Thank you for you suggestion it has definitely improved.

Edit: I have also included pull up resistors in the above tests as well they did not resolve the issue and there was no difference when they were used and not used.

Well, I just realized that you re using the Core… I am using Photon!

is adding this cast the only way you could get it to compile?

lcd->write((uint8_t)0);

did you try just:

lcd->write(0);

Yes I have tried that as well and it doesn’t work we just have the same issue and same result on the LCD screen. I was simply including that to try something different to see if it worked and reading around I found some people needed to include (uint8_t) in front of character 0 for it t work for them.

O so you are using a spark Photon and it works without a hitch? That’s curious because I am simply prototyping for my final product on a Spark Core and my final product will be a on a Photon. I need to do it on the Core though as the Photon I own has no header as I am going to solder the parts together.

This is a very interesting discovery.

I purchased a new LCD display one without an I2C backpack to test the other library and see if that works. I wired it all up correctly and had it displaying text without and issue. I then tried to make to make it display a custom character.

It came up with the same result as when using the I2C library and did not display correctly. As you can see in the picture.

Would that suggest it is an issue with the core rather than the library or function order?

FYI I have a photon on its way and I will test both screens with the photon to see if that resolves the issue.

I have managed to get it working. It seems that it does not work with Particle Cores rather you need a Photon instead. Moreover the order of the functions is important. You need to call lcd->init() before you call createChar(). Then simply use lcd->write() including the character number in the brackets.

Here is the code I used that works on my Photon:

    // This #include statement was automatically added by the Particle IDE.
#include "LiquidCrystal_I2C_Spark/LiquidCrystal_I2C_Spark.h"
LiquidCrystal_I2C *lcd;
uint8_t customChar[8] = {
	0b00000,
	0b01010,
	0b01010,
	0b00000,
	0b10001,
	0b11111,
	0b01110,
	0b00000
};
void setup(void)
{
  lcd = new LiquidCrystal_I2C(0x27, 20, 4);
  lcd->init();
  lcd->createChar(0, customChar);
  lcd->backlight();
  lcd->clear();
  lcd->print("Hi here is my custom");
  lcd->setCursor(0,1);
  lcd->print("character: ");
  lcd->write(0);
}

void loop(void){ }

Thank you for your help @BulldogLowell

1 Like