U8glib: Graphics Lib for LCDs and OLEDs

Below is the code used in the Adafruit and u8glib sketches. The Arduino is connected the same in both cases. The Adafruit one works, but the other does not.


// pin 9 - Serial data out (SID)
// pin 8 - Serial clock out (SCLK)
// pin 7 - Data/Command select (RS or A0)
// pin 6 - LCD reset (RST)
// pin 5 - LCD chip select (CS)
ST7565 glcd(9, 8, 7, 6, 5);


U8GLIB_LM6059 u8g(8, 9, 5, 7, 6);

The Adafruit library leaves the left most column of pixels garbled. There are a few activated pixels, the rest are inactive. This makes pixel (0,0) actually located at (1,0). The rest of the screen is fine. I don't know if this is relevant information

Seems ok. Can you use the following construcor call: U8GLIB_LM6059 u8g(8, 9, 5, 7, U8G_PIN_NONE); and connect the reset signal to 3.3V.

Will this work?


Awesome! Thanks a ton.

It looks like the paging is off. To get the Adafruit library pages in the right order I had to change the following line in ST7565.cpp from

const uint8_t pagemap[] = { 3, 2, 1, 0, 7, 6, 5, 4 }; // Adafruit original


const uint8_t pagemap[] = { 7, 6, 5, 4, 3, 2, 1, 0 }; // Adafruit changed

I poked around and I haven't found where I would define the page mapping.

Great. Now we need to correct the display and the Bias. I have seen that the Adafruit code and the NHD display do differ in that. I also guess that I need to implement another variant for this display. So, here is another request from me. Can you apply the U8GLIB_DOGM128 constructor?

Maybe you can also send a picture of the result with the DOGM128 constructor. Main questions are: Is the contrast as good as before? Is it better? I also expect that the wrong line will disapear but the display might be flipped (not a problem, because u8glib can rotate the screen by 180 degree) and probably the row mapping is still wrong.

If the row mapping is still wrong, i would like to use the DOGM128 as a template for further changes.

Thanks, Oliver

I’m making an Arduino shield for this LCD, so I’d be thrilled to see these changes make it upstream. It would be nice to point folks to u8glib. I really appreciate the work you’re doing to unify the graphics libraries. I’ll match the pin mapping with the u8glib default pins.

To see graphics I had to change the contrast in ug8_dev_st7576_lm6059.c, line 70 from

 0x018 /* contrast value*/


 0x005, /* contrast value*/

I have tried the U8GLIB_DOGM128 constructor. The default contrast was also poor, so I changed the contrast in u8g_dev_st7565_dogm128.c, line 59 from

 0x018,	/* contrast value, EA default: 0x016 */


 0x005, /* contrast value, EA default: 0x016 */

A contrast of 0x005 in the DOGM128 constructor seems a little more washed out than the LM6059 constructor.

I’ve cloned your google code repo and I’m able to run …arduino/create_release.sh. Do you want to make the changes in there and I’ll test it? I can also rewire my setup to be consistent with your library.

Thank a lot for the pictures. So, this is what i understand: - page mapping is ok now - col offset wrong by 4 pixel - contrast wrong - dogm128 a little bit washed out

I have created a new device in the repo: NHD_C12864. So you need to update the repo.

I have added this to the U8gLogo.pde example only (at the moment) line 75: http://code.google.com/p/u8glib/source/browse/sys/arduino/U8gLogo/U8gLogo.pde

The code for the display is here: http://code.google.com/p/u8glib/source/browse/csrc/u8g_dev_st7565_nhd_c12864.c At the moment, this is an exact copy of the DOGM128 code.

  • col offset wrong by 4 pixel --> change line 79 to "0x004"

  • contrast wrong --> probably change contrast in line 68 to 0x005 (or maybe other values like 0x006 or 0x007) --> you might also try to change the value in line 55 from 0x0a2 to 0x0a3

Once you find the best values, i would be really glad to add these values to the new device. Also, let me know if there is something else wrong with the new NHD_C12864 device.

Thanks for testing, Oliver

Changing line 79 to 0x004 worked. The pixels are aligned.

Changing line 61 (not 68) to 0x008 looked good for contrast. I played with several values. 0x009 also worked. 0x010 is where the background started getting funky.

Keep line 55 at 0x0a2. To get a reasonable screen using 0x0a3 I had to bring the contrast down to 0x003.

Some people might consider the display to be upside down, but this is the orientation in which I would like to use it. It allows buttons beneath the screen to be as close as possible. Are you cool with leaving it like this in the library? It would mean one fewer steps in my instructions.

Good work. I changed line 79 to 0x004, line 61 to 0x008 and added the constructor U8GLIB_NHD_C12864 to all examples. The orientation can be changed later by the group of rotation commands: http://code.google.com/p/u8glib/wiki/userreference#setRot90

I'm making an Arduino shield for this LCD

Looking forward to read about your shield. :)

I want to include issues 75, 79 and 81 into the next u8glib release. So i am not sure about the next release date at the moment, but everything is in the repository.

Thanks for all the testing and the pictures, Oliver

Edit: I have also updated the reset functionality. So maybe this will also work now. Connecting the reset line to 3.3 is a little bit critical. It may work, but usually reset control by the controller or a RC circuit is better: http://code.google.com/p/dogm128/wiki/dogs102_arduino_hardware For a shield i would suggest to add the RC circuit to have one more pin for the user.

Thanks so much for your help, Oliver. I wouldn't expect my shield to be available until after December 2012, so no rush on a release.

I used the constructor as "U8GLIB_NHD_C12864 u8g(13, 11, 10, 9, 8);" and connected the LCD reset pin to Arduino pin 8. Works just fine, but I will use the circuit you mention.

rdeweerd: I'm using the library for the DFRobot ST7920 128 X 64 LCD and it works without a problem, both in serial as in parallel mode. But the weird thing is, is that the parallel mode is a bit slower. In SW serial I got a refresh rate of 6 to 7 frames per sec and in 8bit it goes down to 4 to 5.

Is this normal behavior or am I doing something wrong?

I have improved speed for the parallel mode by 30%. This fix will be available with the next regular release. Please send PM for a beta release including this fix.



I'm using u8glib for an LCD screen I pulled out of an old Dell LTO tape backup library. It turned out to be a LC7981 chipset at 240x128. I was able to modify the library files for the screen, based on some other mods I found already in the files and all is well. (U8GLIB_LC7981_240X128)

I have a question about fonts - I'd like to create my own font, both for a custom look and to save some memory by omitting characters I know I won't need. Can you post some info for how to create/add custom fonts? I've been looking at u8g_font_data.c and it looks like they're just a big bitmap with some parameters indicating the boundaries of each character, but I can't seem to get my head around the array structure.

It will soon be a super deluxe HVAC controller:



Nice work. Glad to see that u8glib is usefull for you.

The U8glib font format not only contains the bitmat data but also a lot of glyph information for precise font rendering (mainly used for my other lib m2tklib). Some information available in the fonts are described here: http://code.google.com/p/u8glib/wiki/tstring. The U8glib font format also tries to crop the bitmap data to save as much ROM as possible. All the glyph metric calculation, the bitmap reduction and the font encoding is done by an external program: http://code.google.com/p/u8glib/source/browse/tools/font/bdf2u8g/bdf2u8g.c. Simply compile the c-file with a unix or windows c-compiler (or send me a PM if you need the executable).

bdf2u8g requires a font in the bdf format: http://en.wikipedia.org/wiki/Glyph_Bitmap_Distribution_Format

On the internet several fonts are available as bdf files, see for example here: http://cgit.freedesktop.org/xorg/font/

But it is also possible to convert truetype fonts (ttf) to bdf: I have used http://sofia.nmsu.edu/~mleisher/Software/otf2bdf/ and http://fontforge.org/. I am sure there are more tools (google has some 100.000 hits for "ttf bdf").


Cool, thanks! I'll see if I can get anywhere with this. I have little knowledge of how fonts work, so this may be more than I have patience to do. ;)

U8glib is a really nice library, BTW - pretty easy to use and modify. I was a little intimidated at first, but dug into the files and figured out how to create a new constructor. I have two other LCDs I've pulled out of old equipment that I'm going to try and get working. One is a little 5 x 2 character out of a Dell server (it's the little status/diag LCD). I haven't figured out what chip is on it yet. The other came from a Quantum tape library and I believe is a ST7565 128 x 64 chip-on-glass type. Both have ribbon cables so I need to get breakout boards to use them.

Anyway, thanks for your help and the LCD library!

Thank you Oliver for your wonderfull work!

I tested the DFRobot st7920 witch has an spi module attatched to take care of contrast etc. and it works fine in arduino environment. I would like to use it in pure C but the constructor requires an A0 connection,while the arduino library does not.

How could i resolve this?

Thanks again!


The st7920 does not require an A0 line. Instead it has a very special low level protocol. Unfortunately i have not yet ported the Arduino version of the low level driver: http://code.google.com/p/u8glib/source/browse/csrc/u8g_com_arduino_st7920_spi.c

I have put this as issue 85 on the u8glib issue list.

Thanks, Oliver

Thanks for the reply.. Ill will use the arduino library then,no problem!


I have added support for the st7920 with avr to u8glib: The test environment includes my NHD 192x32 display with ST7920 controller (upper right, the bright light from upper left makes the contrast a little bit weak). Lower left is an unused EA 132x32 display. Lower right the ATMEGA 328 with green power LED. Upper left the AVR programmer.

A beta release with support for st7920 for avr is avilable on request.



I have released version 1.08 of u8glib. The new release has been optimized for speed and includes support for some more OLED chips. See details here: http://code.google.com/p/u8glib/.

This release also has a new COM interface for I2C/TWI based displays. The first supported I2C display is the Seeedstudio 96x96 OLED.

Thanks to all testers of the beta releases!


Oliver, I've looked but can't seem to locate any information on the bitmap pixel format. i.e. things like is it LSB to MSB, 8 bit vs 16 bit, vertical vs horizontal encoding etc... Is it universal in that it works on any glcd or is the bitmap format just a raw image for the given glcd so each glcd has a different pixel format? Have I missed this somewhere?

--- bill

Hi Bill

The drawBitmap procedure expects a byte array, which is printed from left to right, MSB on the left. The drawXBM also expects a fixed format, but i can't remember the bit orientation.

The fact that each display might have a different byte orientations forces U8glib to perform a bitmap translation step from the high level command to the native display byte orientation. Indeed this is one of the most time consuming steps in U8glib. Unfortunately i do not know how to avoid this. There is not common memory layout for the displays. Each chip has an individual memory setup. Everytime I add a new chip, I am surprised to see another new memory layout :roll_eyes:

Because i anyway had to add such a bitmap translation, it was not a big task to add the 90 degree rotation for the display orientation. Indeed this is something what i got almost for free (with respect to computation time): I just had to exchange the bitmap translation procedures, when such a different display orientation is requested.

For one of the newly added OLEDs I had to implement a completly new memory layout: - I noticed that the new memory layout reduces speed (of course only for this display) - So i decided to work on an overall speed optimization. - All of the u8glib code was ported to my desktop so that i can apply "gprof" to it. - I did a lot of gprof tests with the code to identify those procedures where most of the computation time is lost - This all lead to several improvements, including one, where i had to restructure parts of the high level/low level communication. - Depending on the high level comands, speed is now improved by up to 30%, but still, GLCD is much faster. - After spending many many hours on speed and performance analysis this summer, i know that there is not much room for further improvements.

U8glib offers flexibility and trades this for speed.

The good news is, that u8glib still is faster than many existing libraries (except GLCD). ;)