Graphic LCD (KS0108) library now available

Hehe, well there is not much of an application yet (almost only your library code and a small testapp). I am thinking on using a 74HC595 IC for sending the data to the LCD.
This will save 5 pins on the arduino hence the 595 IC only needs 3 pins to send 8 bit parallel but it can not receive any data.
I will only present text and numbers on the display and therefore I don't think that I will need to write the same 8 bit part more then one time for each update.

The project is to control the cooling fans in the computer depending on the heat to make it as quiet as possible. I got the idée from a friend that used the arduino in another project of his. It seemed to be easy to use and a lot of projects were already available on the net.
It would be nice with a GLCD to show values and to manually change some fan and heat limits.

I started with the GLCD because it seemed like it would be the most difficult part in the project.
\Frisken

Due to a shipping error I now own a graphic LCD, but it doesn't look like the right kind to use with the Arduino.

http://www.topwaydisplay.com/Pub/Manual/LM6063AFW-Manual-Rev0.1.pdf

I think I could deal with the 3.3v power, but the different controller is probably a deal killer.

Due to a shipping error I now own a graphic LCD, but it doesn't look like the right kind to use with the Arduino.

It won't work with the KS0108 library but you may be able to get it to work if you can find some AVR code for your controller, try a search on the controller: ST7565 or ST7565R

Good luck!

Mem,

I have tested my new KS0108 LCD from Seeedstudio and can say that it works good with the Library.
So you could add it as a tested unit in the playground area.
I am not really sure what the brand is but i think Eric at seeedstudio could provide us with an seeedstudio artical number that can be used or point out the product name.
Could it be called the bluemoon lcd ?
Datasheet i have is found here: http://www.bluemoon-lcd.com/english/pdf/G12864C.pdf

I am runnig the following setup for smooth displaying:
#define DELAY_EN_ON 0
#define DELAY_EN_OFF 15

My other one from http://www.fractronics.com/12864b_full.pdf had to be set as you know to as slow as:
#define DELAY_EN_ON 0
#define DELAY_EN_OFF 27

Eric, at what settings did you manage to run the same lcd before shipping to me?

The green one from ebay that we have Mem is running at:
#define DELAY_EN_ON 4
#define DELAY_EN_OFF 6
I do ask my self why the above two have to be slowed down to a big enable off value but not on the enable on value.

Maybe something that will be solved when and if there will be an automized set up of speed in your library?

HULK - It's the right datasheet you have found.

While we test the LCD, it's not displaying good for the spinning lines. I didn't change the settings, but added delays as discussed in some posts here until we see it work fine. FPS=6

Thanks for the review:)

Intresting.
After some more testing i got the lcd to work with following settings:
FPS = 2
#define DELAY_EN_ON 15
#define DELAY_EN_OFF 0

FPS = 2
#define DELAY_EN_ON 0
#define DELAY_EN_OFF 15

FPS = 1
#define DELAY_EN_ON 0
#define DELAY_EN_OFF 0

Strange thing is that this was tested by seeedstudio but with ATMega 168 i assume and FPS was 6.
I will do some more testing with my ATMega644 and maybe also connect it to a ATMega 168 to check.

hmmm, could it be the ports that i am using
//bits 0-7 assigned to sanguino pins 0-7

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!