Arduino LCD playground | KS0108 Graphics LCD library

KS0108 Graphics LCD library

KS0108 is an unofficial Arduino library that supports Graphic LCDs (GLCD) that use the KS0108 (or equivalent) chip.

The download includes an example sketch and a readme.txt file to explain the basics of adding a library.

The latest Version (added July 2009) makes it easier to integrate slower panels, supports the Mega and Sanguino boards, and has the following new features:

  • Supports fixed width fonts that provides up to 8 x 21 character display with the supplied system font.
  • CursorTo method to position the cursor to a given font location (fixed width fonts only)
  • DrawBitmap function to display bitmap images stored in Flash memory. A Processing utility is provided in the download to convert a monochrome bitmap file to a header file automatically stores the image in flash for use by the DrwBitmap method.

Picture of a test sketch running on a max232 Freeduino board with a low cost GLCD panel

The library is based on the excellent ks0108 graphics routines written and copyright by Fabian Maximilian Thiele. The sitelink in his code does not respond but you can obtain a copy of his original work in the download section at the end of this article.

The code here has been converted to an Arduino library, has more flexibility in port addressing and improvements in I/O speed. The interface has been made more Arduino friendly and some convenience functions added. The method naming is mostly unchanged to facilitate porting of code written for the original version. Some methods now have default arguments to make them easer to use.

The test sketch included in the download demonstrates many of the capabilities of the library and if you start with this and use the default Arduino pin assignments, it is a good way to make sure that everything is working before you customize your configuration. Here is a simplified verison of the example sketch in the download:

Example GLCD sketch
  #include <ks0108.h>  // library header
  #include <Arial14.h>  // font definition for 14 point Arial font.
  #include "SystemFont5x7.h"   // system font
  #include "ArduinoIcon.h"     // bitmap  

  unsigned long startMillis;
  unsigned int iter = 0;

void setup(){

  GLCD.Init(NON_INVERTED);   // initialise the library
  GLCD.ClearScreen();  
  GLCD.DrawBitmap(ArduinoIcon, 32,0, BLACK); //draw the bitmap at the given x,y position
  delay(3000);
  GLCD.ClearScreen();
  GLCD.SelectFont(System5x7);       // select fixed width system font 

}

void loop(){ // run over and over again

  startMillis = millis();
  while( millis() - startMillis < 1000){ // loop for one second
    GLCD.DrawRect(0, 0, 64, 61, BLACK); // rectangle in left side of screen
    GLCD.DrawRoundRect(68, 0, 58, 61, 5, BLACK);  // rounded rectangle around text area   
    for(int i=0; i < 62; i += 4)
      GLCD.DrawLine(1,1,63,i, BLACK);  // draw lines from upper left down right side of rectangle  
    GLCD.DrawCircle(32,31,30,BLACK);   // draw circle centered in the left side of screen  
    GLCD.FillRect(92,40,16,16, WHITE); // clear previous spinner position  
    GLCD.CursorTo(5,5);               // locate curser for printing text
    GLCD.PrintNumber(++iter);         // print current iteration at the current cursor position 
  } 
  // display number of iterations in one second
  GLCD.ClearScreen();               // clear the screen  
  GLCD.CursorTo(13,2);              // positon cursor  
  GLCD.Puts("FPS= ");               // print a text string  
  GLCD.PrintNumber(iter);           // print a number 
 }
Functional overview :

This is a list of functions supported by the library

 GLCD.Init(invert) initialize the library for normal or inverted drawing. If invert is false,
  drawing sets pixels, if true pixels are cleared when drawn (see also SetInverted method) 
 GLCD.GotoXY(x,y) locate the graphic cursor at positions x and y, 0,0 is upper left corner
 GLCD.ClearScreen() clear the LCD screen

 // Graphic Drawing Functions (color WHITE clears pixels, BLACK sets pixels)
 GLCD.DrawCircle(x, y, radius, color) draw circle with center at x,y
 GLCD.DrawLine(x1,y1,x2,y2,color) draw line from x1,y1 to x2,y2 
 GLCD.DrawVertLine(x, y, length, color) draw vertical line
 GLCD.DrawHoriLine(x, y, length, color) draw horizontal line  
 GLCD.DrawRect(x, y, width, height, color) draw rectangle
 GLCD.DrawRoundRect(x, y, width, height, radius, color) as above with rounded edges
 GLCD.FillRect(x, y, width, height, color) draw filled rectangle
 GLCD.InvertRect(x, y, width, height) invert pixels within given rectangle
 GLCD.SetInverted(invert) set drawing mode to inverted 
 GLCD.SetDot(x, y, color); draw a dot in the given color at the given location
 GLCD.DrawBitmap(bitmap, x, y, color); draw the bitmap at the given x,y position

 // Font Functions 
 GLCD.SelectFont(font, color ) select font, defaults color to black if not specified
 GLCD.PutChar(character) print given character to screen at current cursor location
 GLCD.Puts(string) print given string to screen at current cursor location
 GLCD.Puts_P(string) print string from program memory to screen at current cursor location
 GLCD.PrintNumber(number) print the decimal value of the given number at current cursor location
 GLCD.CursorTo(x, y); // 0 based coordinates for fixed width fonts (i.e. the supplied system font)

Note: valid colors are BLACK (sets pixels) or WHITE (clears pixels)

Wiring and Configuration:

Pin assignments are contained in the appropriate header file for the supported controller chips. There are three controller types supported in the current version:

  • ks0108_arduino.h <- this is for ATmega168 and ATmega328 boards
  • ks0108_mega.h <- for the Arduino Mega (ATmega1280)
  • ks0108_Sanguino.h <- for Sanguino (ATmega644)

See the readme file supplied with the download for more details on configuration.

It is suggested that you wire up the panel using the default pin assignments. This diagram shows how panels should be connected using the default pin assignments in the distributed library.

Connections for common GLCD panels
GLCD Panel Pinouts
Arduino 168 Mega FunctionPinout A Pinout B Comments
5V5V+5 volts1!2! 
GndGndGND2!1! 
externalexternalContrast in33Wiper of contrast pot
822D047 
923D158 
1024D269 
1125D3710 
426D4811 
527D5912 
628D61013 
729D71114 
14 (alog0)33CSEL11215Chip 1 select
15 (alog1)34CSEL21316Chip 2 select
Reset Reset1417Normally high, can go to 5V
16 (alog2)35R_W155Read/write
17 (alog3)36D_I164Data/Instruction (aka RS)
18 (alog4)37EN176Enable
externalexternalContrast out181810k or 20k preset
externalexternalBacklight +51919100 to 330 ohm resistor to +5v
GndGndBacklight Gnd2020 

Pinout A panels:

  • HDM64GS12L-4
  • Crystalfontz CFAG12864B (tested by biomed)
  • Sparkfun LCD-00710CM (tested by biomed)
  • NKC Electronics LCD-0022 (tested by NKC Electronics)

Pinout B panels:

  • HDM64GS12L-5
  • Lumex LCM-S12864GSF (tested by jowan)
  • Futurlec BLUE128X64LCD (tested by tyggerjai)
  • AZ Displays AGM1264F (tested by santy)
  • Displaytech 64128A BC (tested by Udo Klein)
  • Adafruit GLCD (Leave RESET pin disconnected or you may experience upload problems) (tested by Things)
  • DataVision DG12864-88 (tested by wglover)

(your are welcome to add other panels to the above lists that are tested and working with this library)

This diagram shows wiring of the common type A panel. Check to see how your panel datasheet matches the connecter assignments before wiring up. Take particular care that the +5v and ground connections are correct!

Wiring up the external components:

Most GLCD panels require an external preset pot to set the LCD working voltage (contrast) and a fixed resistor to limit the current in the backlight. The datasheet for your panel should provide specific information on the wiring and choice of components. A suggestion for wiring these up is to use a small piece of stripboard with header pins for 5V, ground and Reset providing connection to the Arduino. See the diagram above for layout.

Changing the Arduino pin assignments:

The KS0108 chip needs lots of pins. 8 data pins and 5 command pins are required in addition to the power connections. Ideally the command pins should all be on one port and all the data pins together on another. In practice this is not easy to do on a standard arduino. If you split command pins or data pins across ports the code will run slightly slower, but for all but the most speed critical graphic applications its not significant. To change pin assignments you must modify the ks0108.h header file. Find the section in the file that begins:

 /********************************************************/
 /* Configuration for assigning LCD bits to Arduino Pins */
 /********************************************************/

You will see the defines for the five command pins with their default pin assignments:

        Name    Arduino pin number 
 #define CSEL1   14 (Analog pin 0)
 #define CSEL2   15 (Analog pin 1) 
 #define R_W     16 (Analog pin 2) 
 #define D_I     17 (Analog pin 3) 
 #define EN      18 (Analog pin 4)

Any of these commands can be assigned to any pin (as long as its not used by something else), but try to assign them all in the same Port:

  • Port B 8-13
  • Port C 14-19 (the analog pins)
  • Port D 0-7 (note 0 and 1 are used by hardware serial)

Modifying Data pins is a little more restrictive because in this version the data pins must be assigned in two groups of four, valid options are one of the following options. In ks0108.h, uncomment one of the pin options that correspond to the wiring of data bits 0-3. Note that all options assume data bits 4-7 are connected to arduino pins 4-7

  • dataPins8-11 // bits 0-3 assigned to arduino pins 8-11, bits 4-7 assigned to arduino pins 4-7
  • dataPins14-17 //bits 0-3 assigned to arduino pins 14-17, bits 4-7 assigned to arduino pins 4-7. With this option, the default command pins need to be changed to free ports other than 14-17
  • dataPins0-3 // bits 0-3 assigned to arduino pins 0-3 , bits 4-7 assigned to arduino pins 4-7, this is marginally the fastest option but its only available on runtime board without hardware rs232.

Remember that any changes to the library (header file or source file) will only take affect if you delete the ks0108.o object file in the library directory before re-compiling your sketch.

Troubleshooting

No pixels visible on the display

  • Check +5v and Gnd connections between Arduino and GLCD panel
  • Check that all data and command pins are wired correctly
  • Check contrast voltage (typically between -3 and -4 volts) on contrast-in pin of LCD panel. While the sketch is operating, try gradually adjusting the pot through its range. Some displays are very sensitive to this setting.
  • Check sketch has compiled ok and downloaded to the arduino.

Left and right side of image reversed

  • swap CSEL1 and CSEL2 wires (or swap pin assignments in header file)

Display garbled

  • check all data and command pins are wired correctly and that these match the setting in the header file.
  • if you change the pin assignments in the header file you must delete the ks0108.o object file in the library directory before re-compiling your sketch.

Still having problems, see the forum discussion links below.

On using and modifying libraries

Create your own fonts and icons

There is a free java application available that can convert any of your PC fonts for use with this library. The software is called FontCreator2 and it can produce a header file that stores font definitions in program memory when included in your sketch.

Embeding images in your firmware

A Processing sketch is provided in the download that converts bmp images to files that can be used by the library to display the image on the LCD. See the documentation in the download for more information.

Downloads:

Questions, comments and suggestions on the library and documentation

Forum discussion
PM contact