Go Down

Topic: Graphic LCD (KS0108) library now available (Read 113802 times) previous topic - next topic


Thanks, this is exactly what i mean, your reply was very helpful :)



Thanks for your help.
Problem is in connection of LCD to IDE cable - I had to solder pins :(
One LCD looks like could be working - second one even after soldering shows garbled pixels ... I need to re-solder everything :(


Jun 02, 2010, 11:49 am Last Edit: Jun 02, 2010, 03:54 pm by robinet_pl Reason: 1

After re-soldering everything - one LCD is totally broken - shows nothing "readable".

Second one - shows everything almost perfectly fine - with FPS=9 for EN_DELAY_VALUE=1 ... almost, because contents of 2nd chip is duplicated on 3rd chip and on 4th chip ... but no wires is attached to CS3 and CS4 ?!?!

And the correct datasheet is here:
It's not MSC-G24064DVSV-1N-E - but MSC-G24064DYSY-1N-E.
It has LED backlight which works fine with 4.5V.

after grounding CS3 and CS4 - everything seems to work fine on "good" LCD module :)


Hi all.

Are there any instructions out there that explain how to use the FontCreator software?


Thanks for the library.

Works really well on a GLCD from newhavendisplay.com (NHD-12864WG-BTFH-V#N in case anyone is looking for a part.)

I was running into some problems with very large font sizes, but made a small change to ks0108.cpp to fix this. I altered the PutChar(char c) method. The page variable was declared as a byte, which didn't hold enough locations for my large characters.

Changing its declaration to 16 bit fixed this. That is, I changed line 392 from:
           uint8_t page = i*width;
           uint16_t page = i*width;

and now my large fonts draw correctly.

In case it helps anyone...


oooo.. Interesting. Are you using a font that is 32 pixels or wider?
The new version of the library renders fonts very differently but looks like it will suffer from the same overflow issue.
I'll look into fixing this in the new version of the library.

--- bill


I haven't seen any documentation.
You kind of have to play with it and look at the generated file to see what happens.
Make sure you get the right version of "FontCreator2".
Don't get the Microelectronika version.
Make sure to use the one with the link at the bottom of the palyground page.

--- bill



I have small issue with method ks0108::WriteData.

When the yOffset is properly aligned it simply overwrites single page.
But when doesn't it will use logical OR for split bits into two pages, which can produce unexpected results on the LCD. Probably that code assumes that screen was cleared earlier.

So to prevent it i just clear used bits before that OR operation.

Code: [Select]

// first page
displayData &= (uint8_t) ~(0xff << yOffset);
displayData |= data << yOffset;
// second page
displayData &= (uint8_t)  (0xff << yOffset);
displayData |= data >> (8-yOffset);


Jun 21, 2010, 09:11 pm Last Edit: Jun 22, 2010, 12:51 am by bperrybap Reason: 1
This is actually much more difficult to solve than you might think.
The only real solution is to dump and re-write the putchar rendering routine
(which is what I've done in the new version of the library - that is just entering beta testing).

The original code from Thiele which was used for the current ks0108 library
attempted to solve the lcd page spanning issue as you have noted.
It keeps the rendering very simple but there are many issues
because the WriteData() routine does not know which bits in the byte
are part of the character bitmap data and which are not.

Some of the zero bits in the byte are legitimate zero bits that should
be set to 0 but some of the zero bits are actually not part of the
data at all and should be left alone.
And there is the dilemma.
The only entity that has access to this information, PutChar(), isn't
using it or communicating it to anybody else.

One big factor with doing things like pre-clearing the bytes as you have done done potentially creates other problems as it stomps on pixels above or below the boundary of the character glyph.
Consider a font that is 9 pixels tall. This will span 2 pages. If your font starts on a page boundary and you clear
the pages before ORing in the data, in this case, the 7 pixels below the character data are also cleared. That is often not desired, particularly
if you are re-writing a line of text above an existing line of text.
This effect even happens with the system font when the y coordinate is not on a page boundary. i.e. using the system font on y coordinate 1, the lower 7pixels of lower page will be clobbered rather than left alone.
Move the starting y coordinate to say 7, and you have the opposite problem. The 7 pixels above the font get clobbered.
So if you try to put a line of text below another line, the pixels from line of text above gets stomped  on.

Things also get really hairy when trying to support inverted/reverse-video text.

There are so many issues that crop up
with trying to let the WriteData() handle the lcd page spanning.
It is so seductively simply sounding
yet the bottom line is that there is no way to fix this kind of stuff in WriteData().

The only way to make it work reliably and consistently, is actually to write a better character rendering routine that sets and clears only the bits within the character data and leaves the bits in the page outside the character data alone - which is what is in the new version of the library.

The new PutChar() is actually quite complex, but it is all necessary to properly handle allowing any font size to be rendered on any horizontal or vertical pixel boundary along with normal and inverted text. It turned out that adding text areas was a  simple addition, so the new PutChar() code also supports scrolling,
wrapping and multiple user defined scrollable text areas.

So with the new rendering method used in the new library, not only is wrapping and scrolling supported but you can do over-strike properly as well as inverted text and even move the text right up close to a graphic object above or below the text and not have to deal with all the crazy rendering problems which vary depending on font size and y location that are in the current code.

--- bill


Thanks for clearing this up. Indeed i was too hurry. I have this problem during tests with animated bitmap (just drawing few frames loaded from external eeprom) and i completely forgot that it affect also fonts :-[

I can't wait for new version :)


If all you need is a fix for bitmaps:
Insert this code (which is in the new version of the library)
in function DrawBitmap()

Code: [Select]
 if( (y & 7) || (height & 7))
       this->FillRect(x, y, width, height, WHITE);

Just above the for loop.
Code: [Select]
for(j = 0; j < height / 8; j++) {

This code will pre-clear the area under the bitmap when necessary.

--- bill


I just ported a routine to plot ellipses:

Code: [Select]
void PlotEllipse(long CX, long  CY, long XRadius,long YRadius, int color) {
// portted the algorithm found at
// http://homepage.smc.edu/kennedy_john/belipse.pdf
// by John Kennedy

 long X, Y;
 long XChange, YChange;
 long EllipseError;
 long TwoASquare,TwoBSquare;
 long StoppingX, StoppingY;
 TwoASquare = 2*XRadius*XRadius;
 TwoBSquare = 2*YRadius*YRadius;
 X = XRadius;
 Y = 0;
 XChange = YRadius*YRadius*(1-2*XRadius);
 YChange = XRadius*XRadius;
 EllipseError = 0;
 StoppingX = TwoBSquare*XRadius;
 StoppingY = 0;

 while ( StoppingX >=StoppingY ) //first set of points,y'>-1
   StoppingY=StoppingY+ TwoASquare;
   EllipseError = EllipseError+ YChange;
   if ((2*EllipseError + XChange) > 0 ) {
     StoppingX=StoppingX- TwoBSquare;
     EllipseError=EllipseError+ XChange;
 //{ first point set is done; start the 2nd set of points }

 Y = YRadius;
 X = 0;
 YChange = XRadius*XRadius*(1-2*YRadius);
 XChange = YRadius*YRadius;
 EllipseError = 0;
 StoppingY = TwoASquare*YRadius;
 StoppingX = 0;
 while ( StoppingY >=StoppingX ) //{2nd set of points, y'< -1}
   StoppingX=StoppingX + TwoBSquare;
   EllipseError=EllipseError+ XChange;
   if ((2*EllipseError + YChange) > 0 ) {
     StoppingY=StoppingY- TwoASquare;
     EllipseError=EllipseError+ YChange;
}; //{procedure PlotEllipse}

void Plot4EllipsePoints(long CX,long  CY, long X, long Y, int color){
 GLCD.SetDot(CX+X, CY+Y, color); //{point in quadrant 1}
 GLCD.SetDot(CX-X, CY+Y, color); //{point in quadrant 2}
 GLCD.SetDot(CX-X, CY-Y, color); //{point in quadrant 3}
 GLCD.SetDot(CX+X, CY-Y, color); //{point in quadrant 4}


The ellipse code looks like a modified version of the
the midpoint circle algorithm.
With a small tweak, it can also fill the ellipse as well.
(I've tested the code above with both ellipses and modifed code for filled ellipses)
The new library already has circle routines (draw and fill),
but I'll look at folding in ellipse capability as well.

I'd prefer to fold in ellipse capability in with circle and rounded rectangle
code to save space.

--- bill



I'd love to see it integrated into the library! I just bought a LCD and the pixels are not square, so when I draw a circle I see an ellipse, so - to correct the aspect ratio, I'm using that function. Maube I'll code something for automatic aspect ratio correction...or maybe it's overkill...

I'd like to ask another question:

Is it possible to print the text rotated by 90 degrees?

I'm thinking about using it on portrait orientation (width = 64 and height = 128)


Who makes the GLCD that you have?

I totally understand about the non square pixels.
Luckily most of the ks0108 128x64 GLCDs have square pixels, but
I do have some GLCDs (sed1520) that are not square pixels and circles on those are not "round".

As far as rotated text goes....
Technically, the answer is yes, but not with this glcd library.
There are several things that enter into this.
Right now, the text rendering code is "hard coded" to the current orientation.
Currently, the fonts themselves are encoded with the bits in the
the same positions as the GLCD memory pages when in this orientation.
i.e. byte 0 of a font glyph is up to 8 vertical pixels on the left side of the glyph. (same is true for bitmap data)

Also, the ks0108 and other chips have an auto address increment mode inside the chip that advances each time a byte is written.
On the ks0108, the column address increments. The rendering code takes advantage of this as well
as it draws up to 8 pixels tall horizontally across the glyph, then drops down if there are additional vertical pixels to render.

So while the code could be written to rotate things around to render it
in a different orientation which is potentially different from the bit
representation in the data (font & bitmap), the current code does not support this.

Michael and I have talked about it, but decided it was too big of a change to tackle at this point in time for this upcoming release.

--- bill

Go Up