Pages: 1 2 [3] 4 5 ... 29   Go Down
Author Topic: Graphic LCD (KS0108) library now available  (Read 35383 times)
0 Members and 1 Guest are viewing this topic.
0
Offline Offline
Newbie
*
Karma: 0
Posts: 2
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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 :-( )
Logged

0
Offline Offline
Newbie
*
Karma: 0
Posts: 2
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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
Logged

London
Offline Offline
Faraday Member
**
Karma: 8
Posts: 6240
Have fun!
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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.
« Last Edit: September 24, 2008, 05:35:21 am by mem » Logged

London
Offline Offline
Faraday Member
**
Karma: 8
Posts: 6240
Have fun!
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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
Logged

0
Offline Offline
Newbie
*
Karma: 0
Posts: 10
Arduino mola
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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.
Logged

Sweden, Malmö
Offline Offline
Full Member
***
Karma: 2
Posts: 200
Rooky
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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:
Code:
#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
Logged

London
Offline Offline
Faraday Member
**
Karma: 8
Posts: 6240
Have fun!
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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.
Logged

Sweden, Malmö
Offline Offline
Full Member
***
Karma: 2
Posts: 200
Rooky
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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
« Last Edit: October 04, 2008, 01:57:37 am by HULK » Logged

London
Offline Offline
Faraday Member
**
Karma: 8
Posts: 6240
Have fun!
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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.
« Last Edit: October 04, 2008, 02:22:32 am by mem » Logged

Sweden, Malmö
Offline Offline
Full Member
***
Karma: 2
Posts: 200
Rooky
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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:
Code:
#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:
Code:
#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...
« Last Edit: October 04, 2008, 03:09:56 am by HULK » Logged

London
Offline Offline
Faraday Member
**
Karma: 8
Posts: 6240
Have fun!
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
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.
« Last Edit: October 04, 2008, 04:10:49 am by mem » Logged

Sweden, Malmö
Offline Offline
Full Member
***
Karma: 2
Posts: 200
Rooky
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
Quote:
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.

Moved this issue to:
http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1223141170/0#0
Logged

London
Offline Offline
Faraday Member
**
Karma: 8
Posts: 6240
Have fun!
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

 
Here is an updated version of the ks0108.cpp file for those that want to play with modifying the timing delays for displays that can't handle the 450ns updates.

I am making some other changes to the library to make it compatible with other chips, like the ATmega644 and will wait until this is completed before updating the playground code. I would appreciate if anyone that has had trouble with slow displays could try this code and see if it fixes the problem.
The delays can be tweeked by changing some constants added at the beginning of the file.
#define DELAY_EN_ON  10  // tweek these two to optimize speed
#define DELAY_EN_OFF 10


#define DELAY_RD_ON   2 // these two probably don't need tweeking for any display
#define DELAY_RD_OFF  2

The values above work on my 'slow' LCD, my fast LCD works with all constants equal to 2

Don't forget you need to delete the .o file before each recompile

There isn't room for the entire file here so I have removed all the methods at the start of the file. You will need to past these back if you want to test this code,
Here is the fragment:
Code:
// ks0108.cpp fragment

// the following four defines determine delays on the enable pin
// values as below work on my slowest display, my fastest works with all values of 2
// 2 is around 0.5us, 4 = 1us, 8 = 2us 10= 2.5us
#define DELAY_EN_ON  10  // tweek these two to optimize speed
#define DELAY_EN_OFF 10

#define DELAY_RD_ON   2 // these two may not need tweeking for any display
#define DELAY_RD_OFF  2

#include "ks0108.h"
extern "C" {
#include <inttypes.h>
#include <avr/io.h>
#include <avr/pgmspace.h>
#include <wiring.h> // added 18 Sept 2008 for Arduino release 0012
}

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

// all methods before delay450ns have been removed here to fit the post.
// You need to past these in here from you existing file

/*
static void delay450ns(void){   // delay 450 nanoseconds
 asm volatile("nop\n\t"
        "nop\n\t"
        "nop\n\t"
        "nop\n\t"  // todo, remove some nops if clock is less than 16mhz
        "nop\n\t"
        ::);
 }
 */
__inline__ void ks0108::Enable(void) {  
  fastWriteHigh(EN);                              // EN high level width min 450 ns
  asm volatile( "ldi  r24, %0 \n\t"
    "subi r24, 0x1 \n\t"
    "and  r24, r24 \n\t"
    "brne .-6      \n\t"
    ::"M" (DELAY_EN_ON) :
  "r24" );
  //      delay450ns();
  fastWriteLow(EN);
  asm volatile( "ldi  r24, %0 \n\t"
    "subi r24, 0x1 \n\t"
    "and  r24, r24 \n\t"
    "brne .-6      \n\t"
    ::"M" (DELAY_EN_OFF) :
  "r24" );
  //      delay450ns();

}

uint8_t ks0108::DoReadData(uint8_t first) {
  uint8_t data;

  lcdDataOut(0x00);
  lcdDataDir(0x00);                              // data port is input

  if(this->Coord.x < CHIP_WIDTH) {
    fastWriteLow(CSEL2);                  // deselect chip 2
    fastWriteHigh(CSEL1);                  // select chip 1
  }
  else if(this->Coord.x >= CHIP_WIDTH) {
    fastWriteLow(CSEL1);                  // deselect chip 1
    fastWriteHigh(CSEL2);                  // select chip 2
  }
  if(this->Coord.x == CHIP_WIDTH && first) {            // chip2 X-address = 0
    this->WriteCommand(LCD_SET_ADD, CHIP2);       // wuff wuff
  }

  fastWriteHigh(D_I);                        // D/I = 1
  fastWriteHigh(R_W);                        // R/W = 1

  fastWriteHigh(EN);                   // EN high level width: min. 450ns
  asm volatile( "ldi  r24, %0 \n\t"
    "subi r24, 0x1 \n\t"
    "and  r24, r24 \n\t"
    "brne .-6      \n\t"
    ::"M" (DELAY_RD_ON) :
  "r24" );
  //      delay450ns();
#ifdef LCD_DATA_NIBBLES
  data = (LCD_DATA_IN_LOW & 0x0F) | (LCD_DATA_IN_HIGH & 0xF0);
#else
  data = LCD_DATA_IN_LOW;                     // low and high nibbles on same port so read all 8 bits at once
#endif

  fastWriteLow(EN);
  asm volatile( "ldi  r24, %0 \n\t"
    "subi r24, 0x1 \n\t"
    "and  r24, r24 \n\t"
    "brne .-6      \n\t"
    ::"M" (DELAY_RD_OFF) :
  "r24" );
  //      delay450ns();

  lcdDataDir(0xFF);

  this->GotoXY(this->Coord.x, this->Coord.y);

  if(this->Inverted)
    data = ~data;
  return data;
}

inline uint8_t ks0108::ReadData(void) {  
  this->DoReadData(1);                  // dummy read
  return this->DoReadData(0);            // "real" read
}

void ks0108::WriteCommand(uint8_t cmd, uint8_t chip) {
  if(chip == CHIP1) {
    fastWriteLow(CSEL2);            // deselect chip 2
    fastWriteHigh(CSEL1);            // select chip 1
  }
  else if(chip == CHIP2) {
    fastWriteLow(CSEL1);            // deselect chip 1
    fastWriteHigh(CSEL2);            // select chip 2
  }
  fastWriteLow(D_I);                  // D/I = 0
  fastWriteLow(R_W);                  // R/W = 0      

  lcdDataDir(0xFF);
  lcdDataOut(cmd);
  this->Enable();                  // enable
  lcdDataOut(0x00);
}

void ks0108::WriteData(uint8_t data) {
  uint8_t displayData, yOffset;
#ifdef LCD_CMD_PORT      
  uint8_t cmdPort;      
#endif

#ifdef GLCD_DEBUG
  volatile uint16_t i;
  for(i=0; i<5000; i++);
#endif

  if(this->Coord.x >= DISPLAY_WIDTH)
    return;

  if(this->Coord.x < CHIP_WIDTH) {
    fastWriteLow(CSEL2);                  // deselect chip 2
    fastWriteHigh(CSEL1);                  // select chip 1
  }
  else {
    fastWriteLow(CSEL1);                  // deselect chip 1
    fastWriteHigh(CSEL2);                  // select chip 2
  }

  fastWriteHigh(D_I);                              // D/I = 1
  fastWriteLow(R_W);                          // R/W = 0      
  lcdDataDir(0xFF);                              // data port is output


  yOffset = this->Coord.y%8;
  if(yOffset != 0) {
    // first page
#ifdef LCD_CMD_PORT
    cmdPort = LCD_CMD_PORT;                                    // save command port
#endif
    displayData = this->ReadData();
#ifdef LCD_CMD_PORT             
    LCD_CMD_PORT = cmdPort;                                    // restore command port
#else
    fastWriteHigh(D_I);                              // D/I = 1
    fastWriteLow(R_W);                              // R/W = 0
    if(this->Coord.x < CHIP_WIDTH) {
      fastWriteLow(CSEL2);                  // deselect chip 2
      fastWriteHigh(CSEL1);                  // select chip 1
    }
    else {
      fastWriteLow(CSEL1);                  // deselect chip 1
      fastWriteHigh(CSEL2);                  // select chip 2
    }
#endif
    lcdDataDir(0xFF);                                    // data port is output

    displayData |= data << yOffset;
    if(this->Inverted)
      displayData = ~displayData;
    lcdDataOut( displayData);                              // write data
    this->Enable();                                                // enable

      // second page
    this->GotoXY(this->Coord.x, this->Coord.y+8);

    displayData = this->ReadData();

#ifdef LCD_CMD_PORT             
    LCD_CMD_PORT = cmdPort;                                    // restore command port
#else            
    fastWriteHigh(D_I);                              // D/I = 1
    fastWriteLow(R_W);                               // R/W = 0      
    if(this->Coord.x < CHIP_WIDTH) {
      fastWriteLow(CSEL2);                  // deselect chip 2
      fastWriteHigh(CSEL1);                  // select chip 1
    }
    else {
      fastWriteLow(CSEL1);                  // deselect chip 1
      fastWriteHigh(CSEL2);                  // select chip 2
    }
#endif
    lcdDataDir(0xFF);                        // data port is output

    displayData |= data >> (8-yOffset);
    if(this->Inverted)
      displayData = ~displayData;
    lcdDataOut(displayData);            // write data
    this->Enable();                              // enable

      this->GotoXY(this->Coord.x+1, this->Coord.y-8);
  }
  else {
    if(this->Inverted)
      data = ~data;
    lcdDataOut(data);                        // write data
    this->Enable();                              // enable
    this->Coord.x++;
  }
  lcdDataOut(0x00);
}

// class wrapper

ks0108::ks0108(){
  this->Inverted=0;
}

// Make one instance for the user
ks0108 GLCD = ks0108();
« Last Edit: October 08, 2008, 06:51:20 am by mem » Logged

Sweden, Malmö
Offline Offline
Full Member
***
Karma: 2
Posts: 200
Rooky
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Mem,

I will check during the weekend and give you feedback.

Logged

London
Offline Offline
Faraday Member
**
Karma: 8
Posts: 6240
Have fun!
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi Hulk, I look forward to hearing about your results.

I wonder if Mario and Rower are still around to give this a try?
Logged

Pages: 1 2 [3] 4 5 ... 29   Go Up
Jump to: