Graphic LCD (KS0108) library now available

Hello all,
Just wondering if anyone has tested or gotten to work the Graphic LCD from Sparkfun.
part # LCD-00710

My GLCD has garble even though I checked every connection at least 4x and followed the KS0108 Graphics LCD library page carefully.
I'm using the example code given on the Arduino library page.

thanks...

Argo,

If this is a KS0108 panel i am sure you will get to work.

Have you tested to add more "nop\n\t" to the ks0108.cpp file, any diffrence?

I had some trouble with one of my panels as you can read in this thread and in the end i got it working using a new updated KS0108 library.
If you wait for couple of days i am sure that mem will realese this updated version so it can be downloaded and used.
He is working on it right now and have improved it so it will adjust according to your panel hardware speed.

But then i am not the one to say what mem will do and not :slight_smile: .
I am sure he will jump in this thread soon and give us all more news on the updated version.

Hi Argo,

If your panel is wired correctly then the most likely cause of garbled display is that its being driven too quickly. You can add delays into the library (there is information here: http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1210427907/42#42) but it is not easy to do if you are not an experienced programmer.

As hulk says, I am working on a new version of the library that adapts to the speed of the panel that should get you going. I expect to have a version you could try in the next few days, I will post here when it is available.

thanks for the quick replies. I'll follow the suggested link post ( lcd driven to quickly...) and also be on the look out for the updated library.

thanks again, :slight_smile:

Hello all,
Interesting find. I had to add about 46 "nop\n\t" to the ks0108.cpp file for it to finally work. thanks for the solution and still will download your latest update mem.

The GLCD I bought is from sparkfun. Graphic LCD 128x64 STN LED Backlight - LCD-00710 - SparkFun Electronics

thanks again.

I wanted to get the GLCD to work with the 74HC595 to be able to save 5 pins on the arduino. To test this fast I just did a fask hack to try if it was possible to do.
The answer to that is that it is possible. The big loss with this is that it is not possible read from the GLCD and therefor if you write to the same area more then one time with different data only the last data will show.
For me that has not been a big problen because I mostly present text in the display and I use a font with fixed width. Therefor all the old characters are coverd with the new ones if the same amount of characters are used.

If someone is interested in how I did this fast hack here is the answer.
This is what I did in the ks0108.h file:

  1. I defined the pins needed for the 74HC595 to work.
#define DataPin      2
#define ClockPin      3
#define LatchPin      4
  1. I added the ShiftOut macro from MartinFick that he posted in the thread “Arduino Forum ? Software ? Bugs & Suggestions ? Higher Performance IO”.
#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))
#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))

#define sbipin(pin) sbi((pin)<8 ? PORTD:PORTB, (pin) - ((pin)<8 ? 0:8))
#define cbipin(pin) cbi((pin)<8 ? PORTD:PORTB, (pin) - ((pin)<8 ? 0:8))

#define bitWrite(pin, val) { \
  if ((val) == LOW) cbipin(pin); \
  else              sbipin(pin); \
}

#define shiftOutBit(dataPin, clockPin, val, bit) { \
  bitWrite(dataPin, ((val) & (1 << (bit))) ? HIGH:LOW); \
  bitWrite(clockPin, HIGH); \
  bitWrite(clockPin, LOW); \
}

#define shiftOutByte(dataPin, clockPin, bitOrder, val) { \
  shiftOutBit(dataPin, clockPin, val, (bitOrder) == LSBFIRST ?0:7); \
  shiftOutBit(dataPin, clockPin, val, (bitOrder) == LSBFIRST ?1:6); \
  shiftOutBit(dataPin, clockPin, val, (bitOrder) == LSBFIRST ?2:5); \
  shiftOutBit(dataPin, clockPin, val, (bitOrder) == LSBFIRST ?3:4); \
  shiftOutBit(dataPin, clockPin, val, (bitOrder) == LSBFIRST ?4:3); \
  shiftOutBit(dataPin, clockPin, val, (bitOrder) == LSBFIRST ?5:2); \
  shiftOutBit(dataPin, clockPin, val, (bitOrder) == LSBFIRST ?6:1); \
  shiftOutBit(dataPin, clockPin, val, (bitOrder) == LSBFIRST ?7:0); \
}
  1. In the private section I added a new function.
void lcdDataShiftOut(uint8_t data);

In the ks0108.cpp file I did these changes:

  1. All the lines that uses the ReadData() function I changed to a fake readout with 0. This is because it's no longer possible to read from the GLCD.
    e.g. “data = this->ReadData();” became
    data = 0x00; //this->ReadData();
  2. In the “Init(Boolean invert)” function I added the outputs needed for the 74HC595.
pinMode(LatchPin,OUTPUT);
pinMode(DataPin,OUTPUT);
pinMode(ClockPin,OUTPUT);
  1. A shiftout function was added to write to the GLDC using the macros in the .h file.
void ks0108::lcdDataShiftOut(uint8_t data)
{
      fastWriteLow(LatchPin);
      shiftOutByte(DataPin, ClockPin, MSBFIRST, data);
      fastWriteHigh(LatchPin);
}
  1. And finally in the “WriteData(uint8_t data)” and “WriteCommand(uint8_t cmd, uint8_t chip)” functions I commented out the use of “lcdDataOut()” macro and replaced it with the “lcdDataShiftOut(uint8_t data)”.
    e.g. “lcdDataOut(cmd);” was commented out and “lcdDataShiftOut(cmd);” was added.

I hope that someone find this usefull. It works fine with my GLCD (ATM12864D). If I test it with the testcode made by mem I got 12 FPS but it do not look that good in the display because there is not possible to read anything from the GLCD. Do not use the 74HC595 if you tend to use a lot of graphics in the GLCD.
\Frisken

Firsken, good to hear you have that going with the shift register. As you say, that solution works well with text. The next version of the library will contain a 5x7 fixed pitch 'system' font which gives up to 8x20 character text display on a 128x64 panel. The release is taking a little longer than I had expected so FWIW, here is the fixed pitch system font definition for those that want do something similar to you:

/*
 * System5x7
 *
 * File Name           : System5x7.h
 * Date                : 28 Oct 2008
 * Font size in bytes  : 470
 * Font width          : 5
 * Font height         : 7
 * Font first char     : 32
 * Font last char      : 127
 * Font used chars     : 94
 *
 * The font data are defined as
 *
 * struct _FONT_ {
 *     uint16_t   font_Size_in_Bytes_over_all_included_Size_it_self;
 *     uint8_t    font_Width_in_Pixel_for_fixed_drawing;
 *     uint8_t    font_Height_in_Pixel_for_all_characters;
 *     unit8_t    font_First_Char;
 *     uint8_t    font_Char_Count;
 *
 *     uint8_t    font_Char_Widths[font_Last_Char - font_First_Char +1];
 *                  // for each character the separate width in pixels,
 *                  // characters < 128 have an implicit virtual right empty row
 *
 *     uint8_t    font_data[];
 *                  // bit field of all characters
 */

#include <inttypes.h>
#include <avr/pgmspace.h>

#ifndef SYSTEM5x7_H
#define SYSTEM5x7_H

#define SYSTEM5x7_WIDTH 5
#define SYSTEM5x7_HEIGHT 7

static uint8_t System5x7[] PROGMEM = {
    0x0, 0x0, // size of zero indicates fixed width font, actual length is width * height
    0x05, // width
    0x07, // height
    0x20, // first char
    0x7f, // char count
    
    // Fixed width; char width table not used !!!!
    
    // font data
    0x00, 0x00, 0x00, 0x00, 0x00,// (space)
      0x00, 0x00, 0x5F, 0x00, 0x00,// !
      0x00, 0x07, 0x00, 0x07, 0x00,// "
      0x14, 0x7F, 0x14, 0x7F, 0x14,// #
      0x24, 0x2A, 0x7F, 0x2A, 0x12,// $
      0x23, 0x13, 0x08, 0x64, 0x62,// %
      0x36, 0x49, 0x55, 0x22, 0x50,// &
      0x00, 0x05, 0x03, 0x00, 0x00,// '
      0x00, 0x1C, 0x22, 0x41, 0x00,// (
      0x00, 0x41, 0x22, 0x1C, 0x00,// )
      0x08, 0x2A, 0x1C, 0x2A, 0x08,// *
      0x08, 0x08, 0x3E, 0x08, 0x08,// +
      0x00, 0x50, 0x30, 0x00, 0x00,// ,
      0x08, 0x08, 0x08, 0x08, 0x08,// -
      0x00, 0x60, 0x60, 0x00, 0x00,// .
      0x20, 0x10, 0x08, 0x04, 0x02,// /
      0x3E, 0x51, 0x49, 0x45, 0x3E,// 0
      0x00, 0x42, 0x7F, 0x40, 0x00,// 1
      0x42, 0x61, 0x51, 0x49, 0x46,// 2
      0x21, 0x41, 0x45, 0x4B, 0x31,// 3
      0x18, 0x14, 0x12, 0x7F, 0x10,// 4
      0x27, 0x45, 0x45, 0x45, 0x39,// 5
      0x3C, 0x4A, 0x49, 0x49, 0x30,// 6
      0x01, 0x71, 0x09, 0x05, 0x03,// 7
      0x36, 0x49, 0x49, 0x49, 0x36,// 8
      0x06, 0x49, 0x49, 0x29, 0x1E,// 9
      0x00, 0x36, 0x36, 0x00, 0x00,// :
      0x00, 0x56, 0x36, 0x00, 0x00,// ;
      0x00, 0x08, 0x14, 0x22, 0x41,// <
      0x14, 0x14, 0x14, 0x14, 0x14,// =
      0x41, 0x22, 0x14, 0x08, 0x00,// >
      0x02, 0x01, 0x51, 0x09, 0x06,// ?
      0x32, 0x49, 0x79, 0x41, 0x3E,// @
      0x7E, 0x11, 0x11, 0x11, 0x7E,// A
      0x7F, 0x49, 0x49, 0x49, 0x36,// B
      0x3E, 0x41, 0x41, 0x41, 0x22,// C
      0x7F, 0x41, 0x41, 0x22, 0x1C,// D
      0x7F, 0x49, 0x49, 0x49, 0x41,// E
      0x7F, 0x09, 0x09, 0x01, 0x01,// F
      0x3E, 0x41, 0x41, 0x51, 0x32,// G
      0x7F, 0x08, 0x08, 0x08, 0x7F,// H
      0x00, 0x41, 0x7F, 0x41, 0x00,// I
      0x20, 0x40, 0x41, 0x3F, 0x01,// J
      0x7F, 0x08, 0x14, 0x22, 0x41,// K
      0x7F, 0x40, 0x40, 0x40, 0x40,// L
      0x7F, 0x02, 0x04, 0x02, 0x7F,// M
      0x7F, 0x04, 0x08, 0x10, 0x7F,// N
      0x3E, 0x41, 0x41, 0x41, 0x3E,// O
      0x7F, 0x09, 0x09, 0x09, 0x06,// P
      0x3E, 0x41, 0x51, 0x21, 0x5E,// Q
      0x7F, 0x09, 0x19, 0x29, 0x46,// R
      0x46, 0x49, 0x49, 0x49, 0x31,// S
      0x01, 0x01, 0x7F, 0x01, 0x01,// T
      0x3F, 0x40, 0x40, 0x40, 0x3F,// U
      0x1F, 0x20, 0x40, 0x20, 0x1F,// V
      0x7F, 0x20, 0x18, 0x20, 0x7F,// W
      0x63, 0x14, 0x08, 0x14, 0x63,// X
      0x03, 0x04, 0x78, 0x04, 0x03,// Y
      0x61, 0x51, 0x49, 0x45, 0x43,// Z
      0x00, 0x00, 0x7F, 0x41, 0x41,// [
      0x02, 0x04, 0x08, 0x10, 0x20,// "\"
      0x41, 0x41, 0x7F, 0x00, 0x00,// ]
      0x04, 0x02, 0x01, 0x02, 0x04,// ^
      0x40, 0x40, 0x40, 0x40, 0x40,// _
      0x00, 0x01, 0x02, 0x04, 0x00,// `
      0x20, 0x54, 0x54, 0x54, 0x78,// a
      0x7F, 0x48, 0x44, 0x44, 0x38,// b
      0x38, 0x44, 0x44, 0x44, 0x20,// c
      0x38, 0x44, 0x44, 0x48, 0x7F,// d
      0x38, 0x54, 0x54, 0x54, 0x18,// e
      0x08, 0x7E, 0x09, 0x01, 0x02,// f
      0x08, 0x14, 0x54, 0x54, 0x3C,// g
      0x7F, 0x08, 0x04, 0x04, 0x78,// h
      0x00, 0x44, 0x7D, 0x40, 0x00,// i
      0x20, 0x40, 0x44, 0x3D, 0x00,// j
      0x00, 0x7F, 0x10, 0x28, 0x44,// k
      0x00, 0x41, 0x7F, 0x40, 0x00,// l
      0x7C, 0x04, 0x18, 0x04, 0x78,// m
      0x7C, 0x08, 0x04, 0x04, 0x78,// n
      0x38, 0x44, 0x44, 0x44, 0x38,// o
      0x7C, 0x14, 0x14, 0x14, 0x08,// p
      0x08, 0x14, 0x14, 0x18, 0x7C,// q
      0x7C, 0x08, 0x04, 0x04, 0x08,// r
      0x48, 0x54, 0x54, 0x54, 0x20,// s
      0x04, 0x3F, 0x44, 0x40, 0x20,// t
      0x3C, 0x40, 0x40, 0x20, 0x7C,// u
      0x1C, 0x20, 0x40, 0x20, 0x1C,// v
      0x3C, 0x40, 0x30, 0x40, 0x3C,// w
      0x44, 0x28, 0x10, 0x28, 0x44,// x
      0x0C, 0x50, 0x50, 0x50, 0x3C,// y
      0x44, 0x64, 0x54, 0x4C, 0x44,// z
      0x00, 0x08, 0x36, 0x41, 0x00,// {
      0x00, 0x00, 0x7F, 0x00, 0x00,// |
      0x00, 0x41, 0x36, 0x08, 0x00,// }
      0x08, 0x08, 0x2A, 0x1C, 0x08,// ->
      0x08, 0x1C, 0x2A, 0x08, 0x08 // <-
    
};

#endif

save the above as SystemFont5x7.h.

usage in sketch:
#include <SystemFont5x7.h>
void setup(){
GLCD.Init(NON_INVERTED);
GLCD.SelectFont(System5x7);
GLCD.ClearScreen();
for(int line=0; line < 64; line+=8){
GLCD.GotoXY(0, line); // note that y position should be evenly divisable by 8
GLCD.Puts("line ");
GLCD.PutChar(line + '0');
}
}

Thanks for the font mem.

In the library there is a private function called WriteData. Is it private for a reason or can you make it public in the next release?

\Frisken

Hi Frisken, I was thinking about adding a method that enables writing of bitmap data to the panel which would be a wrapper around writeData. But if you think having writeData public would be more useful, then I can do that if someone could test it thoroughly.

As you can probably see from looking at the source code, driving this chip is complicated, particularly when data is not written to an even vertical page boundary or if individual pixels need to be set. Alsothe chip requires lots of data contortions because it needs to be read twice to get a single byte of data out, and each double read increments the chips internal address counter which needs to be set back when data is written. All those GotoXYs in the code should take care of it but it really would need some testing if you were accessing writeData externally.

I am almost ready with a beta copy of the new version, I would be happy if you wanted to test using writeData from a sketch.

I would be happy to try it out for you. Is there any specific combination that you think could be troublesome or are you just interested in random testing?

Anything with complex graphics, particularly where individual pixels are written that cross over between controller chips (x = 64) would be a good test. Also where pixels and/or lines are drawn across page boundaries (there are eight pages in the controller, each 8 bits high starting from line 0)

A simple but effective test is to copy small monochrome bitmaps to the various locations in the panel using WriteData.

I probably won't have the version ready tonight, I will pm you and Hulk when it is available.

Anybody know what the maximum cable lenght between the panel and Arduino is?
Are we talking about 30-50cm or just 10cm, at some point the cable lenght has to disturb the signals.

I am sure i can test this myself but hopefully somebody of you have that experience allready :slight_smile:

Hey guys. New member and new Arduino user here. I've been seeing the same issues as Argo. I also have an LCD-00710 screen from Sparkfun. It was garbled just as Argo said. I've tried editing the .cpp file with the "nop\n\t" fix that Argo did as well as add the code that mem posted.

Both of these do in fact clear up the screen a bit, but it's still nothing close to what the pic in the tutorial shows.

Let me know what you guys think I should do. Thanks!

The forum wouldn't let me add a link in my first post, so this is what it currently looks like:

I know it's hard to see. But the circle with the lines from the corner is pretty garbled. In fact it looks like two columns need to be swapped.

Edit: Also note that I'm using twisted pair wire for the data pins. Is this bad?

.. never mind. Turns out that one of my twisted pairs was twisted a little too much (read: hooked up backwards).

All is fixed and I look forward to mem's update!

Hi skeo, good to hear you have it going. Yes, I am also looking forward to the update :wink: Sorry its taken so long but I am testing with lots of different displays and I am still working on code to get the best performance out of some of the slower ones. Progress is slow but steady, hope to have something up real soon now.

Cool, can't wait - I've got a graphical lcd and I want to try and get it working. :slight_smile:

Hello there,

I bought Futurlec BLUE128X64LCD LCD (type B pinout), but I cannot make it work with my Arduino. The backlight is lit up, but there is nothing on the screen. I also cannot adjust the contrast. I've noticed on the Wiki page that the the third leg of the contrast potmeter is connected to the ground. According to the datasheet of Lumex LCM-S12864GSF (another LCD with type B pinout), it should be connected to 5V. Well, I tried in both way (which I probably shouldn't have) but it didn't work anyway. How much voltage should actually be present at pin 18 (Vee)?

Thanks!

Hi Karoly!
I can only speak for what I did and I connected it to the ground and to pin #3 and #18 on the GLCD as in the picture in the ks0108 playground. I also use the B pinout but the contrast is the same in both pinouts. I had to turn the variable 10K resistor to almost 0 before I got anything on the GLCD. Set it to 0 and very slowly increase the resistance. I discovered that the contrast has to be correct otherwise the GLCD shows nothing.
I do not now how much voltage there should be on pin #18. The measurement I got was 9V. That was a surprise for me because I only have 5V in.

Hello!!
I created a new public function in the ks0108 library that calls the private function WriteData like this.

void ks0108::WD(uint8_t data)
{
      WriteData(data);
}

I just wanted to try and add a B/W image of my youngest daughter using this function. Guess what, it works. There is no problems with the border between the two controller chips. I tested it with lines, circles, squares and text both inverted and not, no problem.