Graphic LCD (KS0108) library now available

Hello!
I am developing some electronics for a little sailboat based on arduino diecimilia. I have decided to include a display and use the library for the KS0108.
I have been searching for a display and I have bought the following reference: LCD12864C from ledsee.com
You can find the datasheet searching the reference in the ledsee website
As you can imagine, I have had to change the wiring (hardware) and adapt the interface following the pinout detailed in the datasheet and the article in the Arduino Playground as they did not match.
Everything has worked reasonably well but the text or lines in the display do not look well. Text and Graphics move randomly and the text is hard to read. The example proposed in the library runs but the images are garbled.
I have reviewed the wiring three times.
What may I do to isolate the problem?
Thanks in advance,
Mario.

Hi Mario, sorry to hear you are having trouble.

That's a pin configuration I have not seen before but lets see if we can get it going.

Can you take some pictures that show the problem. It will be easier for me to comment if I can see what is happening on the display. You can't directly post the pictures here but if you can put them on a site like flickr you can add links to the pictures in a post.

Also, did you change the ks0108.h file or did you just wire the pins so it matches the information in the playground?

Edit: My guess is that if you can read the text then your panel is probably wired to the correct pins. But I need to understand more about what you mean by “Text and Graphics move randomly and the text is hard to read”

Hello Mem,
I have posted a short video in youtube:

I also insert here the code for the sample program.

#include <ks0108.h>
#include <Arial14.h>  // font definitions 
int n=0;
int m=0;

void setup(){
  GLCD.Init(NON_INVERTED);   // initialise the library, non inverted writes pixels onto a clear screen
  GLCD.SelectFont(Arial_14); // you can also make your own fonts, see playground for details  
}

void  loop()
{
  if (n>128)
    {
      n=0;
      m++;
     }
  if (m>64)
  {
    n=0;
    m=0;
   }
  GLCD.ClearScreen();
  GLCD.GotoXY(n,m);  // position cursor  
  GLCD.Puts("Hi Mem!");     // write a string to the current cursor position 
  n++;
  delay(100);
}

Thanks,
Mario

In the hardwired connections I just have respected the pins identityes and connect with the corresponding arduino layout.
The only software change in pinout has been to swap the chipselect pins.
Thanks again.
Mario.

Very strange! Two things come to mind as a possible cause:

  1. There is a short (or open) circuit (perhaps intermittent) that is interfering with the signal lines, this could be on the LCD PCB or in the wiring.
  2. The LCD is not able to respond to the timings provided by the library code.

I don't think its timing because the datasheet timings appear to be standard ks0108 values that have worked on other boards. That said, it may be that your board is overly fussy about timing. You can try to slow the library down by adding some extra delay in the delay450ns function in the ks0108.cpp file, but I would be surprised if that fixed it (but happy for you if it did). Don't forget to delete the ks0108.o file after a change:

static void delay450ns(void){   // delay 450 nanoseconds
    asm volatile("nop\n\t" 
       "nop\n\t"  // add these two more nops to slow things down a little
       "nop\n\t"

             "nop\n\t"
             "nop\n\t"
             "nop\n\t" 
             "nop\n\t"
             ::);
}

Not sure what else to suggest, other than have a look a what happens when the pixel rate is slowed right down. You do that by uncommenting the following line in ks0108.cpp

//#define GLCD_DEBUG // uncomment this if you want to slow down drawing to see how pixels are set

You should then see each vertical block of up to 8 pixels being drawn. Perhaps a video of that may tell us more.

You may also want to modify your test so there is a fixed black rectangle somewhere on the screen so we can see if any of these are erased at random. Try this without clearing the screen on every write ( move your call to clearscreen in the if(m> 64) block and change n++ to n = n + 32, change m++ to M + = 12;

...If the number of "nop\n\t" increase your surprise, prepare for this...
To remove all little dots and leave the original example inside the library runing clearly, I have had to add 26. :o
The FPS are 6 and works perfect.
I appreciate very much your help and now I can keep on programming on mi project.
If I can help somehow to add this lcd module in the arduino playground for example, please let me know as I would collaborate gladly. I prefer you to do it after you find an explanation about what has happened with the signals timming in this model.
Thanks for everything,
Mario.

I am very happy you got it going and am surprised that your LCD needs such a long delay. Adding 26 nops makes the delay around 2 microseconds, the spec sheet says it that 450ns should be sufficient.

Anyway, I wonder if you can test some code that I could add to the library that would make it easier to support panels that need a long delay.

Could you comment out all the nops that you added and instead replace the code in the Enable function in ks0108.cpp with the following :

 #define XTREME_ENABLE_DELAY  4

__inline__ void ks0108::Enable(void) {  
    fastWriteHigh(EN);      // EN high level width: min. 450ns
      delay450ns();
      fastWriteLow(EN);
#ifdef XTREME_ENABLE_DELAY
      for(volatile uint8_t i=0; i< XTREME_ENABLE_DELAY; i++);  
#else
      delay450ns();
#endif
}

You may need to increase the value of XTREME__ENABLE_DELAY from 4 to 5 or perhaps even 6, but if a value of 8 isnt' enough then I will suggest a slightly different place to add the delay.

Keep me posted.

Hello Mem,
I have made the changes in the .c file as you suggested, the delay seems not to be placed in the right position. The text is not working properly again even with the variable set to 10.
I have returned to the previous "26 nops" version.
Tell me what else we can do.
Regards,
Mario.

Ok, lets put the Enable(void) method back the way it was and increase the generic delay. This will do the same things as your added nops but uses less code, and it can be easily enabled or disabled if I put it into the distributed file.

#define BIG_DELAY  4   // uncomment this to increase the delay to by a few microseconds

static void delay450ns(void){   // delay 450 nanoseconds
#ifdef BIG_DELAY  
      for(volatile uint8_t i=0; i< BIG_DELAY  ; i++);  
#else
    asm volatile("nop\n\t" 
       "nop\n\t"
       "nop\n\t"
       "nop\n\t"                           "nop\n\t"
       ::);
#endif
}

First post - so here goes. Firstly many thank mem for a great library - my project would not be possible without this.

I have a very similar problem to Mario_B so thought I would chip in my findings.

I am using a KS0108B based 128x64 lcd from Sure Electronics
(type B pinout ). Bought from ebay - cheap as chips IF it can be made to work OK.

I had to add 48 (yes count them!) nop instructions to get a steady display at which point my FPS count is 5.

Like Mario_B using XTREME_ENABLE_DELAY method did not work even when using large values (e.g. 200)

Using the BIG_DELAY method works a treat and I can decrease BIG_DELAY to 1 - at which point my FPS is 5.

Other thoughts/advice needed-

Is an FPS of 5 likely to impact my project - ie should I look for a better lcd before proceeding?

Could my wiring be too long. I'm running on a solderless breadboard currently and the wires between arduino and lcd are about 5 inches long.

Similar problem (with a different lcd) reported in sparkfun forum

A responder thinks that this might be due to "reflections" and that "terminating with a couple of 50 ohm resistors might help". I can try this out if someone can tell me in detail how to wire this up.

Thanks
(had included links to sparkfun and sure electronics but system wont allow me to post these in first post :frowning: )

If helpful sure electronics spec (minimal )here
http://www.sure-electronics.net/mcu,display/DE-LM112_Ver1.0_EN.pdf

Sparkfun post here
http://forum.sparkfun.com/viewtopic.php?p=54266&sid=8780ce9c9529416bb23df535091842b5

Hi Rower, thanks for the information. It is possible that very long cable lengths could be an issue, but I use 5 inch long wires and mine works great, so I think it unlikely that is the problem. Anyway, don't use 50 ohm resistors, that will put much too much load on the arduino pins.

I think I may have a CFAG12864B LCD buried away somewhere here, if that is the same as yours I will try it and see if I also need the big delay.

Running with an FPS of 5 is not a problem if your sketch runs fast enough.

I found the GLCD panal I got from Sure electronics a while ago but it's not the same as Rower's (mine is a type 'A' Crystalfontz panel), so I am no clearer on why some of the type 'B' panels need extra delays.

For those reading this thread looking to decide which panel to get, I think the type 'A' panels (+v on pin 1, data0 on pin4 etc) have been easier to integrate then type 'B' panels.

I wonder if there would be much interest if I offered to supply a full performance ready to run 128x64 GLCD panel that included wired connectors and the little PCB with contrast and backlight resistors

I think I could probably do them for around $20 plus shipping if there was enough interest. PM me if you want one (don't post here, lets keep this thread to technical discussions)

Arduino not included

Hello Mem,
Your last proposed delay450ns(void) function works overally well but I want to make the following remarks:
-The BIG_DELAY definition can be lowered down to 1 and it still works.
-The frames per second is decreased from 6 to 5 comparing this version with the "26 nops" version. It Seems it can be fine tuned better adding nops.
That is all I have found.
Thanks,
Mario.

Mem,

Found my LCD washing my clothes this week in a pair of pants, lucky i did check my pockets before washing. Allways check your pockets before washing, never know what you can find ;D .
So after my PopDuino creation today i continued with connecting the LCD.
So i have updated my H-file to this:

#define CSEL1                        31            // CS1 Bit   // swap pin assignments with CSEL2 if left/right image is reversed
#define CSEL2                        30            // CS2 Bit
#define R_W                              29            // R/W Bit
#define D_I                              28            // D/I Bit 
#define EN                              37            // EN Bit

/* Arduino pins used for LCD Data 
 * un-comment ONE of the following pin options that corresponds to the wiring of data bits 0-3 
 */
//#define dataPins8to11   // bits 0-3 assigned to arduino pins 8-11, bits 4-7 assigned to arduino pins 4-7
//#define dataPins14to17 //bits 0-3 assigned to arduino pins 14-17, bits 4-7 assigned to arduino pins 4-7. (note command pins must be changed)
#define dataPins0to3  // 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.

Using digital pins 0-7 and analog pins 0-4 that are supposed to be pins 31-27. But no luck, wrong pin assignment by me?
http://sanguino.cc/useit
Could it be the sanguino code that is missing nedeed code to complete the task?
http://code.google.com/p/sanguino/downloads/list

Hi Hulk,

The mapping of pins to ports won't work for pin numbers that are different than the arduino. Also, arduino digital pin numbers are not the same as the chips pin numbers.

When I can find some time I will look at the chip you are using and post some macros for you. But it would be easier of you can connect the LCD using the pins that correspond to the standard arduino pins.

Morning Mem,

Was reading your post about the ATMega 644 and the arduino compatibillity.
So i guess i will not be able to change around pins using the existing Atmel ATmega specification?
Or could i use the PC, PD, PB pin indications as referance?
Or should i use ADC0... for analog and T0, T1, AINO, AIN1, ICP, OC1, SS, MOSI for digital.

By the way the updated Ks0108 Library compiles with out problems with my Arduino 0012 software and Windows XP, just having problems viewing the update on the LCD ;D

Did you try it on the ATMega 644 using the default pins (the pins as defined in the library header file)? If that works then perhaps you could use the extra pins on the chip for your other interfaces. If the standard arduino pins as defined in the header don't work or it's not convenient to use the other pins for your other interfaces, I would question the sanguino folks about the claimed compatibility with the arduino.

If the issue is sanguino compatibility with arduino code, lets move this discussion to another thread where others more experienced in this area can contribute. I don't have an ATMega 644 and have no direct experience with it so am not in a good position to help.

Mem,

I did connect the LCD Ks0108 pinout type B to the ATMega 644 as follows:
Digital pins 0-7 and analog pins 0-4 to pins 31-27 and therefore i updated the header to:

#define CSEL1                        31            // CS1 Bit   // swap pin assignments with CSEL2 if left/right image is reversed
#define CSEL2                        30            // CS2 Bit
#define R_W                              29            // R/W Bit
#define D_I                              28            // D/I Bit
#define EN                              27            // EN Bit

/* Arduino pins used for LCD Data
 * un-comment ONE of the following pin options that corresponds to the wiring of data bits 0-3
 */
//#define dataPins8to11   // bits 0-3 assigned to arduino pins 8-11, bits 4-7 assigned to arduino pins 4-7
//#define dataPins14to17 //bits 0-3 assigned to arduino pins 14-17, bits 4-7 assigned to arduino pins 4-7. (note command pins must be changed)
#define dataPins0to3  // bits 0-3 assigned to arduino pins 0-3 , bits 4-7 assigned to arduino pins

Using digital pins 8-11 would be a problem due to tx and rx being pin 8 and 9.
But what you are saying is that if i try it may work? Should i keep the analog pins 27-31 or use the default 18-15?
So the code should be exactlly:

#define CSEL1                        15            // CS1 Bit   // swap pin assignments with CSEL2 if left/right image is reversed 
#define CSEL2                        14            // CS2 Bit 
#define R_W                           16            // R/W Bit 
#define D_I                            17            // D/I Bit  
#define EN                              18            // EN Bit

/* Arduino pins used for LCD Data 
 * un-comment ONE of the following pin options that corresponds to the wiring of data bits 0-3 
 */
#define dataPins8to11   // bits 0-3 assigned to arduino pins 8-11, bits 4-7 assigned to arduino pins 4-7
//#define dataPins14to17 //bits 0-3 assigned to arduino pins 14-17, bits 4-7 assigned to arduino pins 4-7. (note command pins must be changed)
//#define dataPins0to3  // 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.

I think i need to make sure that it is not me that is doing something wrong before posting the sanguino compatibility...

Using digital pins 8-11 would be a problem due to tx and rx being pin 8 and 9...
I think i need to make sure that it is not me that is doing something wrong before posting the sanguino compatibility...

I think the sanguino guys are much better positioned to answer your question than me, I really have no idea how to map pins on the ATMega 644 chip for use with arduino software.

I hope the following helps you phrase your questions to them:

A specific question is: given that this arduino library uses thirteen of the twenty arduino defined digital pins, eight accessed through direct port io, five through arduino digital pin mappings, should this code work unchanged on the sanguino, if not, where can guidelines be found for running arduino code to the sanguino

This question expressed more generally is:
What are the issues with arduino software (such as different mappings to ports and/or resources) using digital pins 0-19 on the ATmega644, either with digitalWrite or using direct port access?

As I mentioned above, I think this discussion is better placed in a thread on sanguino and/or ATmega644 compatibility. I will be happy to post any conclusions here that relate to the GLCD library, but the issue you raise is how to get a chip that claims arduino compatibility working with arduino code, and I think this is an interesting and potentially involved discussion that doesn't belong in a thread dedicated to the Graphics LCD library.