Go Down

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


Jun 28, 2010, 08:21 am Last Edit: Jun 28, 2010, 08:53 am by maujabur Reason: 1
Ok, no rotation then... I would use it for a temperature logger so the y-axis would have more definition (128 pixels high)

My display is made by FORDATA, it's model is FDCG12864G and I'm not sure, but it's pinout seems to be different from the types "A" and "B" - I just followed the pin names and it worked OK from the beggining - tho I had to increase the delay a bit - it was missing some pixels

You can see a datasheet here:http://www.soldafria.com.br/datasheet/FDCG12864G.pdf

I plan to scroll the graph, so this week I'll give a go on the frame buffer mod, but i saw it was made for a older version of the library, any news on that front?

I also found a display with a LC7981 controller, but didn't have the time to take a look on how it works. When I get to know, I'll share. Do you know if is it possible to adapt your library for that?

THANKS a lot for your good work and quick replies on this topic!!!

If you think I can help, just ask and I will


I looked at the data sheet for the FORDATA module.
I've seen 8 or 9 different pinouts for ks0108 modules, but that one is a new one.
That data sheet didn't have any hardware timings in it.

With respect to the timing. The ks0108 library wasn't handling the delay timing very well and certain hardware delays were not properly accounted for.
The new code has proper delays for all the necessary hardware setup times. As a result, the new code is much more robust and also allows adjusting individual timing values in nanoseconds rather than some odd loop counter value.
That said, the new code should work "out of the box" as we have tested it on many different panels, processors, boards, and configurations with no issues. The new code is also quite a faster than previous version.

The LC7981 is different type of chip. (it is smarter with additional capabilities) While it definitely can be made to work with the library, it would be nice to take advantage of some of the additional features - like built in fonts.
At first glance this chipset looks similar in functionality to the SED1330F which we are just starting to look at.

Support for this kind of chip is on the radar, but for now the immediate focus is to get the new version of the library out to people so that they can start using it.

--- bill


I'm not sure what you mean by  a "frame buffer mod".
Fill me in on what you mean by that.

--- bill


I read that todotani was modifying the libraryto use a frame buffer with the arduino mega - I'm using a mega.
The reply number is 124 I guess.

Yesterday I finally read one datasheet for the Lc7891 and my first impresion is that it has a text mode and a graphic mode. the fonts are just for the text mode. On the graphics mode it has a set pixel command that deals with individual pixels. Also read that the pixel are organized on horizontal bytes, what is different from the  ks0108.

Are you working on a new version? I didn't get it right from your message - or you mean by NEW the current version 2?

Thanks again!


Jun 28, 2010, 07:10 pm Last Edit: Jun 28, 2010, 07:19 pm by bperrybap Reason: 1
On the new library.
Michael (mem) and I are finishing up a new version of the ks0108 library.
(it is currently in early beta testing and will eventually replace the current ks0108 library on his ks0108 playground)
While it is an update to the ks0108 library, it is now called "glcd" rather than ks0108 as it supports more than the ks0108 chip. It has many updates/fixes and new features. While backward compatible with the ks0108 library. The underlying i/o has been completely redone to make things much easier to configure, more flexible and is also higher performance.

With respect to using a frame buffer.
This is actually quite a complex subject. The end result
is not always what is initially expected.

It is possible to write code to use a frame buffer. Many implementations that provide the type of functionality in the glcd library
(especially the new multiple scrolling text areas) do use a frame buffer. When using a frame buffer, the code is actually easier to write, smaller and in some cases (but not all), faster. One big problem is the frame buffer itself. For example, when using a 128x64 display a frame buffer would use 1k of RAM. While not that big an issue for chips like the mega1280 or mega1286/7, it  is 100% of what is available on a m168 and half of what is available on a m328.
And that is for a 128x64 glcd.
The glcd library supports glcds up to 256x256 and there users out there already using displays of 240x64.
NOTE: with some slight modifications the code could go beyond the 256x256 limit. The current limitation is due to using 8 bit variables to save code space and increase speed.

I think one of the big pluses of the glcd library is it can run on a m168 even with a very large display as currently the code only needs a small calling stack frame, a few working temporaries and only 3 bytes of "buffering" to do all the rendering regardless of the size of the display.

With a frame buffer you need to have a dedicated ram buffer large
enough to hold all the pixels of the display. This can get very large
as the display get large.
As far as performance with a RAM buffer goes, it isn't always necessarily faster. It depends on the nature of the updates.
When using a frame buffer, the fastest way to update the physical
display from the frame buffer is to slam it all out, potentially overlapping
writes to the multiple chips memory to allow the internal updates to happen in parallel and also take advantage of the internal automatic column address increments.
While very fast, it is sending every single byte to the display.
Also, when using a RAM frame buffer, you have to deal with the pixel
data multiple times.
- once to write to the ram buffer
- once a bit later to read it from the ram buffer
- once to write to the glcd.

So if you are only updating small portions of the screen, the additional
overhead of sending all the bytes to the display can overshadow
the slightly slower i/o method of sending only the data you need to send
to update the small portion of the screen.

Additional code can be added to try to avoid sending portions
of the RAM to the screen that have not been updated, but eventually it starts
to get quite complex and you end up doing about the same thing as the current code does when updating the glcd.

For very large updates such as bitmaps, the current code should be just as fast if not faster than using a RAM buffer for bitmaps that are page aligned (8 pixel boundaries) and multiple of a page size (8 pixels) tall.

The biggest thing a ram buffer does is "time shift". For example, it allows moving around when the physical display is updated.
It allows the updates to the ram buffer to accumulate and then
to flush those updates to the physical screen when convenient.
It also allows interrupt contexts to update the ram buffer which eventually are flushed to physical display.
Without a RAM buffer it is not possible to have foreground and interrupt contexts both updating the display.
So if you want/need to update the display from in interrupt routine,
a RAM buffer is pretty much a necessity.

The good news is that the new version of the library, through the use of some somewhat complex code, now only does the minimum i/o accesses to the chips. If the chip is already where it needs to be it is no longer told to reset its registers. The code also takes advantage of the internal auto address increment and scrambles around the font rendering to ensure the absolute minimum number of access to the GLCD page memory. While this may look like larger/slower code
it is actually quite a bit faster as it is avoiding talking to the GLCD chips
and glcd memory as much as possible since some of those operations
can be costly in terms of time.

So its all kind of a trade off.
Right now it appears that the best alternative for a generic glcd library that supports a broad range of glcds of different sizes on many different AVR chips, is to not depend on the use of a frame buffer.

--- bill


Jun 28, 2010, 07:31 pm Last Edit: Jun 28, 2010, 07:34 pm by maujabur Reason: 1
May I suggest scrolling graphics? That's what I need! Even if it's restricted to multiples of 8 pixels high.

How to I obtain the beta version of the library?

Last night I found sombody who did something like what I'm doing: http://www.youtube.com/watch?v=_sH5kaKO8Vw&feature=related

I'll try to code something today only drawing lines and verifiy if it's fast enough.

Sorry if I'm bugging you with all these questions. I swear I'm coding as well, but who's better than you to give me the hints?

Again, thanks a lot!

[edit]I'll try to scroll each page and then only add the last column of temp data. That's how you scroll text isn'it?[/edit]


If you have all the data sample values in memory, then it might be quicker to redraw all the shifted line segments for each sample value in the graph rather than move the existing graph over.
This is because to move data requires reading the GLCD memory as well as writing to it, whereas to re-draw the graph segments is primarily writes.
(might be only writes depending on how it is done).

--- bill


Yeah, I was thinking about it, and scroll the pages won't work for me, as I plan to use a auto scale for the graph.

Didn't realise it could be only writes, how to do that?

I made a test routine scroling the graph and drawed it using the filled rectangle function, it's pretty fast, but I cleared the screen every update and it caused the graph to flicker.

My idea now is to rewrite it to update each column of the graph at a time, scanning the whole graph every update (1 a second or 1 every 5 seconds maybe). My first impulse was to draw a black rectangle for the value and above it a white rectangle to clear some eventual old value printed over there.  It should eliminate the flickering, I guess.

After I test it, will post the result if it works.

Other thing, I was reading the library and found some "fastWrite" functions, but I just took the .cpp file with me. Is it defined somewhere else? can I use it in my code for my I/O pins? Anyway, I'll google it after, but if you can give me the tip I'll appreciate it.


Check your PMs.

The "fastwrite" stuff is not intended for user code.
It is not part of the API and can't really help out.
It is for setting digital pin values and replaces the VERY SLOW arduino
function digitalWrite().
Slow is relative. In my world of fast i/o, "slow" is tens of microseconds
where as a direct i/o pin write on a 16mhz AVR is only 62.5 nanoseconds.

To speed up your graph drawing, you can write the code to avoid drawing both the white and the black "bars".
Simply store the data in an array but use a circular index to indicate where the data starts. That way you don't ever move the data around just the index. Then because it is circular, you can also know the previous value stored at any location in the graph as you update it.

Because you can know the previous value of a vertical "bar" in your graph, all you need to know is if the new value in that position is larger or smaller or the same as the value that was previously drawn there.
If the same, you draw nothing and leave that position alone
If it is larger, draw the black portion.
If it is smaller, draw the white portion on top which will erase some of the previous bar.

In the case of something like temperature readings, the values may tend to move fairly slowly so comparing if the value is equal to the previous value may eliminate many updates.

If you have enough information and want to, you could even optimize it
further by only updating the individual portions of the bar that need to be overwritten to make the bar taller or shorter as needed.
For example, if the previous bar was 8 "ticks" tall and you need a bar 10 "ticks" tall, then you draw the 2 "ticks" on top of the existing 8 "ticks" that are already on the glcd screen rather than the full 10 "ticks". Likewise if the previous bar was 8 "ticks" and you need to draw a bar 6 "ticks" in that position, you draw 2 white "ticks" to erase the top 2 "ticks".

--- bill


Hi everyone,

Has anyone got any experience with these LCD drivers? I want to drive on from my Duemilanove.






I never worked with this display, but found some products that share the same controller:

SED 156x series
Nokia 7110      96 x 65      monochr.      
NEC 21a      132 x 32
LPH7508      100 x 64       - display kit sold by pollin
Hyundai HP12542R      - display kit sold by pollin

This info was found here: http://serdisplib.sourceforge.net/ wich seems to be a library writen in C for displays, but I still don't know if it's for use on a PC or on a microcontroller. [edit]UPDATE: it's for linux[/edit]

I would google the display names above with the arduino word to see what comes up.

some results:



Hi thanks for this.

I'll pursue the Nokia route as that seems to be a common one.

Just to mention when I brought this display I got two PDF manuals and all the code to get it working with a PIC18.
Now if I was a smarter lad I could work with this and get it running with my arduino..... sadly not.
I can show people if you want. It's all in a 418k zip.

So say I bail on this gLCD and get a very arduino supported one. What do you recommend?




I've been using a display with the KS0108B controller without problems!
If you want, send me the PDFs and I'll take a look, but I don't promise a fast response nor that I'll make it work, I'm not super skilled, but have done some code tranlations from pic to arduino.

Check your PMs


An early beta release of the next version of the GLCD library is now available, see this thread for details


In response to spinnay, I translated the code he sent me (PIC originally)
to the arduino, but something seems not to be quite right.

If someone else could help, please. I am not sure the SPI library works, if somebody could check it.

Where should I upload the code to make it available here?

Go Up