LCD4Bit for 20x4 displays!

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.

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.

Could also add this to add user-defined characters:

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

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!

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

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.

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)

thx.. for the answers..

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

I followed Arduino Playground - HomePage, 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?

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.

//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

// --------- 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:

// --------- 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 Arduino Playground - LCD4BitLibrary-tm404a
with kind regards,
legba7

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

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

Thanks

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

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!

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

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

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?

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

Mem,

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

Thanks again...

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!

hmm one question:
I always get this error after compiling:
Couldn't determine program size:

What's the matter?

cheers
Geko

you forgot to show your error, but maybe this helps. I had errors to when compiling. The reason was that i had more liberies to control the lcd in the libary directory that use the same files.
Try to tempery move other libs and try again.

I hope this hepls you.

hmm that worked!

Ok but now as I uploaded the sketch nothing
appears on the screen.

Hmm could you pls send me your library and sketch...
I think I messed it up...

PS: The Display shows:

Geko

hmm that worked!

Hmm could you pls send me your library and sketch...
I think I messed it up...
Geko

This evenig i wil send it to you when i'am home.

Hi,

I put my library online at:
http://www.ineonline.nl/download/LCD4Bit.zip

Good luck.