Pages: [1] 2 3   Go Down
Author Topic: LCD4Bit for 20x4 displays!  (Read 5640 times)
0 Members and 1 Guest are viewing this topic.
0
Offline Offline
Newbie
*
Karma: 0
Posts: 7
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi everyone,

I've made a modified version of the LCD4Bit for allowing it to work with my 20x4 displays, it should continue to work with 20x1, 20x2 and others display (I hope so). Hope it'll help some of you!

My display: White on Blue retro with two KS0066U-00PCC and KS0065BPCC controllers (they are HD44780 code compatible but offers some characters and other functions) from Lextronic France (http://www.lextronic.fr/ODT/4x20.htm it's not exactly the one on the pictures, I got one from them for only 12 euros last year, their new ones are a little bit more expensive).
Datasheet: http://www.lextronic.fr/ODT/20x4/20416D.zip
Library: http://lutingaia.free.fr/LCD4Bit_20x4.zip

If you have any question feel free to ask!

Jonathan.
Logged

London
Offline Offline
Newbie
*
Karma: 0
Posts: 47
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Nice!  Also, thanks for writing it up in the wiki.  I'm short for time at the moment, but I'll try to retest this library on the 1 and 2 line displays so that we can just offer this one version.
Logged

0
Offline Offline
Newbie
*
Karma: 0
Posts: 7
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Could also add this to add user-defined characters:


Code:
void LCD4Bit::WriteCGRAM(int adress, char code[]) {
   commandWrite(0x40+(adress<<3));

   for (int i=0 ; i <= 7 ; i++)
        {
                print(code[i]);
        }
   commandWrite(CMD_HOME);

}

I'm using the CMD_HOME to return to the DDRAM adress of the beginning of the screen. I don't know how to read the DDRAM adress from the LCD to send it back to it after CGRAM writing (we needed to do that because the controller only has one memory pointer).
Logged

0
Offline Offline
Newbie
*
Karma: 0
Posts: 7
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

New version that includes:

_ CGRAM through WriteCGRAM (int character, char code[])
_ Speed optimization of  cursor positioning (by a factor "position")

http://lutingaia.free.fr/LCD4Bit.zip

Please test it with 1,2 and 4 lines displays if you can!


Logged

0
Offline Offline
Newbie
*
Karma: 0
Posts: 17
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Jonathan
i have the same display (not working yet), can you show the wiring diagram you used, and the modifications you made to the sample code.  also, did you ground RW ? ( as indicated in reply #10 of http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1160586800/0#0)
thx
!!
detailed version http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1173804342
---------------------------------------------------

Quote
Hi everyone,

I've made a modified version of the LCD4Bit for allowing it to work with my 20x4 displays, it should continue to work with 20x1, 20x2 and others display (I hope so). Hope it'll help some of you!

My display: White on Blue retro with two KS0066U-00PCC and KS0065BPCC controllers (they are HD44780 code compatible but offers some characters and other functions) from Lextronic France (http://www.lextronic.fr/ODT/4x20.htm it's not exactly the one on the pictures, I got one from them for only 12 euros last year, their new ones are a little bit more expensive).
Datasheet: http://www.lextronic.fr/ODT/20x4/20416D.zip
Library: http://lutingaia.free.fr/LCD4Bit_20x4.zip

If you have any question feel free to ask!

Jonathan.
Logged

0
Offline Offline
Newbie
*
Karma: 0
Posts: 7
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I used exactly the wiring scheme for LCD4bit classic version.
The modifications were only on the initialisation code of the library (to allow 4 lines selection), and in cursor position.


---
How to use it

The library is intended to be a 4-bit replacement for the original LCD tutorial code and is compatible with very little change. Here's what you must do after the setup described in the original tutorial:

    * In your circuit (1): You must tie the LCD's R/W pin to ground. (This frees another arduino pin for you). See this forum post for more troubleshooting.
    * In your circuit (2): remove the 4 lower bits of the data bus between the arduino and the LCD. We only use DB4~7.
    * In your code: The constructor now requires to know if your display is 1 or 2 lines. e.g.
      LCD4Bit lcd = LCD4Bit(1);

---

On the last line you can use LCD4Bit(4) for allowing 4 lines use.


Hope it will work for you too! (please let me know)
Logged

0
Offline Offline
Newbie
*
Karma: 0
Posts: 17
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

thx.. for the answers..

in post #1, its hard to tell looks like d1 & d0 is wired ? <that's different from mine>

I followed  http://www.arduino.cc/playground/uploads/ScematicLcd/scematic_lcd.pdf, nothing is connected to d0/1/2/3

i guess my next step is to wire up the 8bit, and then try 4bit..
-could it be that something gets loaded in 8bit mode that allows 4bit to work?
Logged

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

I tried your modified version of the LCD4Bit on tm404a:http://www.tianma.com/index.php?mod=productmgr&task=product&idcat=1&id=139.
It worked very fine on the first two lines of my display.

This display has a second HD44780 for the third and fourth line with its own Enable Input.
So I wired the second Enable Input to pin 3 on the arduino and edited mainly LCD4Bit::cursorTo(int line_num, int x) a little to work with this display.
Code:
//non-core stuff --------------------------------------
//move the cursor to the given absolute position.  line numbers start at 1.
//if this is not a 2-line LCD4Bit instance, will always position on first line.
//
//legba7: second controller, with its own Enable input, for line 3 and 4
void LCD4Bit::cursorTo(int line_num, int x){

  //if we are on a 1-line display, set line_num to 1st line, regardless of given
  if (g_num_lines==1){
    line_num = 1;
    Enable = Enable1;
  }
  //offset 40 chars in if second line requested
  //
  switch (line_num){
  case 1:
    Enable = Enable1;
    x=0x00 ; break;;
  case 2:
    Enable = Enable1;
    x= 0x40 ; break;;
  case 3:
    //line_num = 1;
    Enable = Enable2;
    x=0x00; break;;
    //x+= 0x14 ; break;; // In fact, line 3 is an extension of the line 1 (beyond the 20 first characters)
  case 4:
    Enable = Enable2;
    //x+= 0x54 ; break;; // Line 4 is an extension of line 2
    x= 0x40 ; break;; // Line 4 is an extension of line 3
  }
  
  commandWrite(0x80+x);
}
and the pinpart
Code:
// --------- PINS -------------------------------------
//is the RW pin of the LCD under our control?  If we're only ever going to write to the LCD, we can use one less microcontroller pin, and just tie the LCD pin to the necessary signal, high or low.
//this stops us sending signals to the RW pin if it isn't being used.
int USING_RW = false;

//RS, RW and Enable can be set to whatever you like
int RS = 12;
int RW = 11;
//legba7: two HD44780; per HD44780 one Enable Input
int Enable1 = 2;
int Enable2 = 3;
int Enable = Enable1;
//DB should be an unseparated group of pins  - because of lazy coding in pushNibble()
int DB[] = {7, 8, 9, 10};  //wire these to DB4~7 on LCD.

//--------------------------------------------------------

//how many lines has the LCD? (don't change here - specify on calling constructor)
int g_num_lines = 2;
the library is now a little bit different to handle, example:
Code:
// --------- PINS -------------------------------------
//is the RW pin of the LCD under our control?  If we're only ever going to write to the LCD, we can use one less microcontroller pin, and just tie the LCD pin to the necessary signal, high or low.
//this stops us sending signals to the RW pin if it isn't being used.
int USING_RW = false;

//RS, RW and Enable can be set to whatever you like
int RS = 12;
int RW = 11;
//legba7: two HD44780; per HD44780 one Enable Input
int Enable1 = 2;
int Enable2 = 3;
int Enable = Enable1;
//DB should be an unseparated group of pins  - because of lazy coding in pushNibble()
int DB[] = {7, 8, 9, 10};  //wire these to DB4~7 on LCD.

//--------------------------------------------------------

//how many lines has the LCD? (don't change here - specify on calling constructor)
int g_num_lines = 2;
i put the stuff under http://www.arduino.cc/playground/Code/LCD4BitLibrary-tm404a
with kind regards,
legba7
Logged

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

The link http://lutingaia.free.fr/LCD4Bit.zip returns an error for me  :'(

Does anyone know where I can get hold of this library?

Thanks
Logged

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

Quote
The link http://lutingaia.free.fr/LCD4Bit.zip returns an error for me  :'(

Does anyone know where I can get hold of this library?

Thanks

I have the same problem. How has the zip for me?

Tanks a lot!
Logged

Switzerland
Offline Offline
Sr. Member
****
Karma: 0
Posts: 268
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

This could help you...
http://www.tekcrack.com/interfacing-arduino-with-a-purdy-lcd-4x40-modified-lcd4bit-library.html

let me know if it works!

Thx
Andy
Logged

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

Quote

Yes the Zip files work fine.
But that code is for a 4x40 LCD with two enable signals, anybody got the original version code for only one enable signal?

Logged

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

In my 4x20 display, line 3 starts just after the 20th position of  line 1 and line 4 starts just after the 20th position of line 2.

So this code in the cursor position method works for me on a 4x20 display, you will need to find the right values for a display with a different width

  switch (line_num){  // lines start from 1, no offset needed for x if displaying on line 1
    case 2:
      x+= 40 ; break;
    case 3:
      x+= 20 ; break;
    case 4:
      x+= 60 ; break;
  }

You will need to search the cpp file to modify any code that is aware of the total number of lines. In the 4bit library I think there is a global variable called g_num_lines, search on that and modify the code as necessary to respect values from 1 to 4 as valid.

So something like:
  if (g_num_lines < 1 || g_num_lines > 2)
    g_num_lines = 1;

becomes:
  if (g_num_lines != 1 && g_num_lines != 2 && g_num_lines != 4)
     g_num_lines = 1;

and
  int num_lines_ptn = g_num_lines - 1 << 3;

becomes:
  int num_lines_ptn ;
  if (g_num_lines != 4)
      num_lines_ptn = g_num_lines - 1 << 3;
  else
      num_lines_ptn = 2 - 1 << 3; // control the 4 lines display as if 2 lines
« Last Edit: August 07, 2008, 11:22:31 am by mem » Logged

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

Mem,

Aha, did not figure that out, works fine on my 4x20 LCD.
No need to change the code in that case.

Thanks again...
« Last Edit: August 07, 2008, 01:06:57 pm by HULK » Logged

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

I changed the origenal 4bit library code my self to let it work with my 4x20LCD, KS0066u Based.
I got it working perfectly.
Below the code for those of you who have the same LCD.

LCD4Bit.cpp:
changes i made
just replace the origenal ones with this ones.


The new constructor:

LCD4Bit::LCD4Bit (int num_lines) {
  g_num_lines = num_lines;
  if (g_num_lines < 1)
  {
    g_num_lines = 1;
  }
  if (g_num_lines > 4)
  {
    g_num_lines = 4;
  }
}



function cursorTo

void LCD4Bit::cursorTo(int line_num, int x){
  //first, put cursor home
  commandWrite(CMD_HOME);
  if (x>19)
  {
        x=19;
  }
switch (line_num)
  {
 case 1:
    x+=0x00 ; break;
  case 2:
    x+= 0x40 ; break;
  case 3:
    x+= 0x14 ; break; // In fact, line 3 is an extension of the line 1 (beyond the 20 first characters)
  case 4:
    x+= 0x54 ; break; // Line 4 is an extension of line 2
  }
  //
  commandWrite(0x80+x);
}


Test program:

#include <LCD4Bit.h>
LCD4Bit lcd = LCD4Bit(4);

void setup() {
  pinMode(13, OUTPUT);  //we'll use the debug LED to output a heartbeat
  lcd.init();
}

void loop() {  
  digitalWrite(13, HIGH);  //light the debug LED
  lcd.clear();
  lcd.cursorTo(1,0);
  lcd.printIn("Line 1");
  lcd.cursorTo(2,0);
  lcd.printIn("Line 2");
  lcd.cursorTo(3,0);
  lcd.printIn("Line 3");
  lcd.cursorTo(4,0);
  lcd.printIn("Line 4");
  delay(1000);
  digitalWrite(13, LOW);  //clear the debug LED
 }



Hope it works for you to!

Logged

Pages: [1] 2 3   Go Up
Jump to: