Searching \ for '[EE] Problems with LCD-display in 4-bit mode' in subject line. ()
Make payments with PayPal - it's fast, free and secure! Help us get a faster server
FAQ page: www.piclist.com/techref/lcds.htm?key=lcd
Search entire site for: 'Problems with LCD-display in 4-bit mode'.

Exact match. Not showing close matches.
PICList Thread
'[EE] Problems with LCD-display in 4-bit mode'
2009\03\30@104017 by Rikard Bosnjakovic

flavicon
face
I bought some cheap HD44780-compatible LCD-displays on ebay to have
something to play with (never used them before). The seller supplied
some tutorials that I'm working with. I get the display to work on my
breadboard when using 8-bit mode (controlled by a PIC 16F628A), but I
cannot make it work using 4-bit mode. When I use 4-bit, D7-D4 is
connected to RB3-RB0. When 8-bit, D7-D0 is connected to RB7-RB0.

I've switched both the PIC and LCD to eliminate these sources of
errors, so I'm probably doing something wrong in my code. Nothing else
than the LCD-display and my Wisp-programmer is connected to the PIC.

Here's the code:

#include <htc.h>

__CONFIG(INTIO & WDTDIS & PWRTDIS & MCLREN & UNPROTECT & BORDIS & LVPDIS);

#define RS RA2
#define RW RA3
#define E  RA4
#define D4 RB0
#define D5 RB1
#define D6 RB2
#define D7 RB3

void lcd_wait(void) {
   unsigned char i;
   unsigned int j;

   for (i = 0; i < 5; i++) {}
   for (j = 0; j < 6000; j++) {}
}

void init_delay(void) {
   unsigned int i;

   for (i = 0; i < 23456; i++) {}
}

void init_MCU(void) {
   TRISA = TRISB = 0;                          // All outputs
   PORTA = PORTB = 0;                          // Clear garbage
   OSCF = 1;                                   // 4MHz INTOSC
   CMCON = 0b00000111;                         // Disable comparators
   VRCON = 0;                                  // Disable voltage
reference-module
   T1CON = 0;                                  // Disable Timer1
   CCP1CON = 0;                                // Disable CCP
}

void lcd_cmd(unsigned char cmd) {
   // According to the tutorial, only D7-D4 is used when 4-bit mode
   // is selected. RB3-RB0 goes to D7-D4 so we'll mask and shift
   // the commands.
   PORTB = (cmd & 0xF0) >> 4;
   E = 1;
   lcd_wait();
   E = 0;

   PORTB = cmd & 0x0F;
   E = 1;
   lcd_wait();
   E = 0;
}

void lcd_cmd_8bit(unsigned char cmd) {
   PORTB = cmd;
   E = 1;
   lcd_wait();
   E = 0;
}

void lcd_putc(char letter) {
   RW = 0;
   RS = 1;
   lcd_cmd(letter);
}

void lcd_print(char *str) {
   char *p = str;
   while (*p)
       lcd_putc(*p++);
}

void main(void) {
   char snase[]  = "ABC";
   init_MCU();
   init_delay();

   // RA1 is a LED (for debugging)
   RA1 = 1;

   // This works fine in 8-bit, but not in 4-bit
   lcd_cmd(0b00111000);          // Set 4-bit transfer, 2 lines
   lcd_cmd(0b00001111);          // Display on, cursor on, blink, underline
   // lcd_cmd_8bit(0b00111000);          // Set 4-bit transfer, 2 lines
   // lcd_cmd_8bit(0b00001111);          // Display on, cursor on,
blink, underline

   lcd_print(snase);

   RA1 = 0;
   while(1) {
       NOP();
   }
}

What happens in the 4-bit mode is that the display responds to my
commands, but instead of printing three letters (ABC) I get like
"OOOOOO\\\\\\NNNNNN". That is, each letter is repeated and deformed.

But - even weirder - is that this result is not 100% reproducible.
Sometimes the display turns on and cursor blinks *before* the command
is sent, and when this happens no garbled text is printed. This is the
reason I tried to change displays, but the behaviour is similiar on
everyone. 8-bit mode works fine for everyone.

Can anyone shed some light on this? Is my lcd_cmd() erronious?


--
- Rikard - http://bos.hack.org/cv/

2009\03\30@105653 by Harold Hallikainen

face
flavicon
face

> Here's the code:
>
> #include <htc.h>
>
> __CONFIG(INTIO & WDTDIS & PWRTDIS & MCLREN & UNPROTECT & BORDIS & LVPDIS);
>
> #define RS RA2
> #define RW RA3
> #define E  RA4
> #define D4 RB0
> #define D5 RB1
> #define D6 RB2
> #define D7 RB3


Without digging extensively in to your code, I note that you're driving E
with RA4, which is an open drain output. Do you have a pull-up on that
line?

Harold



--
FCC Rules Updated Daily at http://www.hallikainen.com - Advertising
opportunities available!

2009\03\30@111929 by Richard Seriani

picon face

----- Original Message -----
From: "Rikard Bosnjakovic" <spam_OUTbosTakeThisOuTspamgrastorpsik.se>
To: "Microcontroller discussion list - Public." <.....piclistKILLspamspam@spam@mit.edu>
Sent: Monday, March 30, 2009 10:37 AM
Subject: [EE] Problems with LCD-display in 4-bit mode


{Quote hidden}

<snip>
>
>    // This works fine in 8-bit, but not in 4-bit
>    lcd_cmd(0b00111000);          // Set 4-bit transfer, 2 lines

One thing to be noted is that the command for 4-bit data length, 2 lines, is
28h (00101000). You appear to still have this set for 8-bit (38h).

>    lcd_cmd(0b00001111);          // Display on, cursor on, blink,
> underline
>    // lcd_cmd_8bit(0b00111000);          // Set 4-bit transfer, 2 lines
>    // lcd_cmd_8bit(0b00001111);          // Display on, cursor on,
> blink, underline
>
<snip>
>


2009\03\30@122209 by jim

flavicon
face
Rikard,

When I run an LCD in 4 bit mode, I always ground the 4 bits on the LCD that
I'm not using, (ie.lcd bits 0-3).
The reasoning here is that if these pins float, you're likely to get
something other than what you want during initialization because you have to
put the unit in 4 bit mode during initialization.   Also, make sure you're
actually putting it in 4 bit mode.  On your code below, the 4 bit mode and
the 8 bit mode commands are the same.  Although the 8 bit commands are
commented out, make sure it's correct for 4 bit mode.     I would check, but
I don't have the command sheet at hand.
Let us know what you find out what the problem was.


Regards,   Jim




{Original Message removed}

2009\03\30@132753 by Wouter van Ooijen

face picon face
> When I run an LCD in 4 bit mode, I always ground the 4 bits on the LCD that
> I'm not using, (ie.lcd bits 0-3).
> The reasoning here is that if these pins float, you're likely to get
> something other than what you want during initialization because you have to
> put the unit in 4 bit mode during initialization.

Grounding those pins directly seems unwise to me, unless you also have
the R/W pin fixed ad write.

But it is also unnecessary for two reasons. First the chip has build-in
pull-up (or pull-down, I don't recall exactly) resistors. Secondly, your
initialization routine must take care of all possible states anyway (the
one specified in the HD44780 datasheet does this).

--

Wouter van Ooijen

-- -------------------------------------------
Van Ooijen Technische Informatica: http://www.voti.nl
consultancy, development, PICmicro products
docent Hogeschool van Utrecht: http://www.voti.nl/hvu

2009\03\30@140222 by Bob Axtell

face picon face
Once you properly set the 4-bit mode, the display device ignores those
pins. The problem
he is having is that he is not properly initializing the device.

--Bob

On Mon, Mar 30, 2009 at 9:22 AM, jim <jimspamKILLspamjpes.com> wrote:
{Quote hidden}

> {Original Message removed}

2009\03\30@141335 by Rikard Bosnjakovic

picon face
On Mon, Mar 30, 2009 at 20:02, Bob Axtell <.....engineerKILLspamspam.....cotse.net> wrote:

> The problem he is having is that he is not properly initializing the device.

This is what I have come up to now as well.

Harold made a point about pull-up on RA4. When I added this some of
the problems (not all) went away.

Richard pointed out that my lcd-command was specified for 8-bit when
it should have been 4-bit. Correcting this fixed made some more errors
go away.

Jim said to ground D0-D3. My tutorial said not to ground them, because
if I did I would have to ground R/W as well. Anyway, I tried to ground
but the problems were still there.

I tried to remove the Wisp during the test, but to no avail.

I powered up the circuit and got garbage on the display. I reset the
PIC, keeping the display powered, and all text appeared nicely. At
this point I realized that the initialization is somehow wrong or
erronius, but I can't figure out what exactly is wrong.

The tutorial tells me to let the display power up for atleast 15ms
before sending commands. When the circuit powers up, the PIC pauses
for 2 seconds before sending commands, but I still get garbage.

What else than a proper delay in the initialization am I missing?


--
- Rikard - http://bos.hack.org/cv/

2009\03\30@141518 by Bob Axtell

face picon face
Agreed. That should get it going (init code 0x28 rather than 0x38).
I'd send this 0x28 twice
to ensure proper initialization.

I have 4-bit commercial code in MPASM that is almost identical to what
you have written
in C, except that I have an interrupt-driven system that allows the
display to be updated
in the background. I use bank3 as a display buffer. No problems
whatever (PIC16F877A).

I have used those Ebay sources, and never had a problem (purple
background). Actually
I love the color, but it washes out in sunlight...

--Bob


On Mon, Mar 30, 2009 at 8:19 AM, Richard Seriani <EraseMErseriani48spam_OUTspamTakeThisOuTcox.net> wrote:
>
> {Original Message removed}

2009\03\30@142426 by solarwind

picon face
Here's my code for Microchip C18
http://solar-blogg.blogspot.com/2009/02/pic18-hd44780-lcd-driver-interface-code.html

For 4 bit mode HD44780

2009\03\30@143832 by jim

flavicon
face
Make sure your timing for command and data are at least what the data sheet
states is a minimum.

JIM
{Original Message removed}

2009\03\30@152326 by Jinx

face picon face

> ground D0-D3. My tutorial said not to ground them, because if I did
> I would have to ground R/W as well

The data lines, on true 44780 anyway, have internal pull-ups so they
don't float. If you ground R/W, that takes away your ability to read Busy

> The tutorial tells me to let the display power up for atleast 15ms
> before sending commands

Try altering the delays within the initialisation

2009\03\30@154140 by Jinx

face picon face
> The data lines, on true 44780 anyway, have internal pull-ups so
> they don't float

BTW, that is exploited by some applications. The data lines can
double as, for example, keypad or pushbutton inputs. Basically
you can do whatever you like when EN is low. That is also the
trick to paralleled LCDs. All each needs is its own EN

2009\03\30@154306 by cdb

flavicon
face
My initialisation code.

const char initLCD[]={0x33,0x32,0x28,0x01,0x02,0x0D,0};

void disp_init(unsigned char *tmpPtr)
{
  unsigned char currentCH;
   
  rs=0;               //rs in command mode
  Wait(20);                        //Delay 20mS to enable LCD to initialise
 
#ifdef HIGH_NIB
 while(*tmpPtr)
       {
           currentCH = *tmpPtr;
           LCDPORT& = 0x0F;   //preserve anything on lower nibble of port
           LCDPORT |= (currentCH & 0xF0); //data + ignore lower nibble

           sendit(rs);

           currentCH <<= 4;  //process lower nibble of data byte
           LCDPORT &= 0x0F;
           LCDPORT |= currentCH;

           sendit(rs);
   
           Wait(1);

         tmpPtr++;

       }
--
cdb, colinspamspam_OUTbtech-online.co.uk on 31/03/2009

Web presence: http://www.btech-online.co.uk  

Hosted by:  http://www.1and1.co.uk/?k_id=7988359







2009\03\30@193717 by Philip Pemberton

face
flavicon
face
Rikard Bosnjakovic wrote:
> Richard pointed out that my lcd-command was specified for 8-bit when
> it should have been 4-bit. Correcting this fixed made some more errors
> go away.

You might want to take a look at the LCD driver I posted on the PICLIST
techref a few years ago:
<http://www.piclist.com/techref/io/lcd/unilcd.htm>

How long are your delays running for?

I'd use a spare I/O line and an oscilloscope to check -- set the I/O line high
when the PIC powers up, wait for the init delay, then set it low. As for the
"lcd_wait" delay, measure the high and low time of the E line and make sure
you're not violating the specs in the HD44780 datasheet (which is online at
<http://www.sparkfun.com/datasheets/LCD/HD44780.pdf>).

> Jim said to ground D0-D3. My tutorial said not to ground them, because
> if I did I would have to ground R/W as well. Anyway, I tried to ground
> but the problems were still there.

Seriously, leave them floating. The pullup resistors in the HD44780 will pull
them high.

> I powered up the circuit and got garbage on the display. I reset the
> PIC, keeping the display powered, and all text appeared nicely. At
> this point I realized that the initialization is somehow wrong or
> erronius, but I can't figure out what exactly is wrong.

When the LCD powers up, it's in 8-bit mode. Your lcd_cmd function assumes the
LCD is already in 4-bit mode, so it strobes /E twice -- once for the high
nibble, then again for the low nibble.

What's probably happening is that the LCD is getting out of sync with the PIC:
 1. DATA = high nibble (0x0011) ==> Init, 4-bit
 2. Strobe E
 3. DATA = low nibble (0x1000)... but the LCD thinks this is the HIGH nibble
of a new instruction, which is a "Set DDRAM address" command.

Then your code sends the byte 0x00001111 in the same way, which completes the
Set DDRAM Address command above.... and starts another one. I'm willing to
wager that the loss of sync between the PIC and the LCD is what's causing the
garbage on the LCD screen.

Your best bet is to initialise the LCD a few times in 8-bit mode, then kick it
into 4-bit mode and continue with the rest of the initialisation. Something
like this:

wait_15ms();
lcd_cmd(0b00110011);                // 8-bit reset (x2)
lcd_cmd(0b00110011);                // Two more 8-bit resets
lcd_cmd(0b00110010);                // An 8-bit reset followed by a 4-bit reset
lcd_cmd(0b00101100);                // Function set -- 4-bit, 2 lines
lcd_cmd(0b00001111);                // Display on, cursor on, blink, underline

should work. Note that the LCD is being reset 5 times in 8-bit mode, then once
in 4-bit mode. This way you don't have to write a separate lcd_cmd_8bit function.

You might be better off copying the rest of the command sequence from my 4-bit
init routine (see the link above and scroll down to "lcd_4bit.inc", look at
the __LCD_INIT routine) and porting it to C. I know for a fact that init
routine works, because I've been using that LCD library successfully on
various hardware platforms since around February 2003. It also works with a
nifty 74LS164-based shift register. Writes to the LCD are slower, but you go
from needing six PIC pins to two. Bit of an improvement, eh? :)

Credit is due to Myke Predko for the concept and hardware design -- it's
nothing more than an LS164 shift register, a 1N4148 diode and a resistor, but
it's still a pretty nifty idea.

> The tutorial tells me to let the display power up for atleast 15ms
> before sending commands. When the circuit powers up, the PIC pauses
> for 2 seconds before sending commands, but I still get garbage.

See above.. your issue is more likely a loss-of-sync than a time delay being
too short.

There are some things about 4-bit mode on the HD44780 that really should be in
the datasheet, but aren't. Good old Hitachi/Renesas. Although that said, the
datasheet for the Samsung KS0066 (a clone of the HD44780) is no better.

--
Phil.
@spam@piclistKILLspamspamphilpem.me.uk
http://www.philpem.me.uk/

2009\03\30@210331 by jim

flavicon
face
All,

Actually I meant to say make sure they are not grounded.  And to check the
timing of the commands and data to make sure they meet the minimum times on
the datasheet.

Jim
{Original Message removed}

2009\03\31@054059 by Andrew Burchill

picon face
On Mon, Mar 30, 2009 at 8:37 AM, Rikard Bosnjakovic <KILLspambosKILLspamspamgrastorpsik.se>wrote:

<snap>

{Quote hidden}

Hi, one area I've found that does not get enough attention is the data hold
time
in relation to where the E signal actually latches the data, the data hold
time actually
starts on the falling edge of E, so in 4bit mode on a somewhat suspiciously
non-spec
44780 look-alike, that spec would only need to deviate 190nS to give
unreliable op.
Add another Nop(); after the first E = 0; before the next half of the
nybble.

regards
--
...AB

2009\03\31@120705 by Rikard Bosnjakovic

picon face
On Tue, Mar 31, 2009 at 01:36, Philip Pemberton <RemoveMEpiclistTakeThisOuTspamphilpem.me.uk> wrote:

[...]
> Then your code sends the byte 0x00001111 in the same way, which completes the
> Set DDRAM Address command above.... and starts another one. I'm willing to
> wager that the loss of sync between the PIC and the LCD is what's causing the
> garbage on the LCD screen.

Philip, you are absolutely right!

I did not realize that for setting 4-bit mode it only requires one
half of a byte, I thought that you had to send the full 8-bit byte
before the module resets itself to 4-bit. Using your init sequence,
sending the resets for both 8bit and 4bit, the display is now
initialized correctly everytime.

Thank you.


--
- Rikard - http://bos.hack.org/cv/

2009\03\31@165616 by Andre

flavicon
face
part 1 1170 bytes content-type:text/plain; charset="UTF-8"
I noticed that your LCD 4 bit mode still continued.
see attachment file. this file came from microchipc.com

Andre Abelian








--- spamBeGonerikard.bosnjakovicspamBeGonespamgmail.com wrote:

From: Rikard Bosnjakovic <TakeThisOuTrikard.bosnjakovicEraseMEspamspam_OUTgmail.com>
To: "Microcontroller discussion list - Public." <RemoveMEpiclistspamTakeThisOuTmit.edu>
Subject: Re: [EE] Problems with LCD-display in 4-bit mode
Date: Tue, 31 Mar 2009 18:07:03 +0200

On Tue, Mar 31, 2009 at 01:36, Philip Pemberton <piclistEraseMEspam.....philpem.me.uk> wrote:

[...]
> Then your code sends the byte 0x00001111 in the same way, which completes the
> Set DDRAM Address command above.... and starts another one. I'm willing to
> wager that the loss of sync between the PIC and the LCD is what's causing the
> garbage on the LCD screen.

Philip, you are absolutely right!

I did not realize that for setting 4-bit mode it only requires one
half of a byte, I thought that you had to send the full 8-bit byte
before the module resets itself to 4-bit. Using your init sequence,
sending the resets for both 8bit and 4bit, the display is now
initialized correctly everytime.

Thank you.


--
- Rikard - http://bos.hack.org/cv/

More... (looser matching)
- Last day of these posts
- In 2009 , 2010 only
- Today
- New search...