I have written a working LCD driver for a NHD‐0212WH‐ATGH‐JT and I would like to add the possibility to create your own custom characters.

Through some research I understood that I need to write a byte for each row in the CGRAM in specific positions and then point to that position when trying to write a character.

I did the following but it doesn't seem to be working:

The array of char for the bytes to write to CGRAM were obtained with online tools such as HD44780 LCD User-Defined Graphics. The functions and commands don't seem to be the problem as I write every other ASCII characters just fine.

char myCustomCharacter[8] = {0x0,0x1,0x3,0x16,0x1c,0x8,0x0};

void createCharacter(unsigned char location, unsigned char[] bytes){

Then in some test main:

int main(void){
    createCharacter(1, myCustomCharacter);
    setCursor(0, 0);
    writeCharacter('A'); //This work just fine, the A is displayed as expected
    writeCharacter(0x08); //Doesn't work, I don't see the character I stored in the CGRAM at the 1st position. Any standard ASCII character still works just fine.

How do I access the custom character as if it was just another ASCII character and how do I know I have correctly written the byte into the CGRAM?

  • 1
    \$\begingroup\$ I found the mistake but I can't answer my own question. I was trying to write the wrong CGRAM location: writeCharacter(0x01); works just fine. An explanation still would be appreciated. \$\endgroup\$
    – Asics
    Aug 8, 2014 at 16:28
  • \$\begingroup\$ As an aside, if you code your custom character like: char myCustomCharacter[] = { 0b00000000, 0b00000001, 0b00000011, 0b00010110, 0b00011100, 0b00001000, 0b00000000, 0b00000000, }; ...then, using a fixed font, it becomes self-documenting. Even I can see that it is a "tick" symbol :) ...looks better when not a SE comment! \$\endgroup\$
    – aja
    Aug 9, 2014 at 7:22

2 Answers 2


The following line adds a custom character to a CGRAM location 1.

createCharacter(1, myCustomCharacter);

The problem with your code was that you told the controller to write a custom character stored at location 8. The writing code should instead look like this.


How do I access the custom character as if it was just another ASCII character

Because the display uses a mostly accurate ascii table, you normally write that character with its regular ascii code. An "A" is ascii character 0x41, and is treated by your compiler as 0x41. The printable characters begin at 0x20 " " (space). The display uses space 0x00-0x0f, normally unprintable control characters in a computer, to hold the reference to the custom characters. As a side note, the 1st custom character is at 0x00, not 0x01.

and how do I know I have correctly written the byte into the CGRAM?

Aside from looking at the screen? You need to have the displayed wired for read AND write, which most people do not. Then you can read the character map just the opposite of the writing. You could also read what the display should be showing, and use the extra memory addresses in a display as extra ram/storage for your microcontroller.


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.