Go Down

Topic: [SOLVED] 16x2 LCD : HD44780 - Beginners Question - LCD initialization (Read 2201 times) previous topic - next topic

ankitmcgill

Feb 29, 2012, 01:12 pm Last Edit: Mar 01, 2012, 10:04 am by ankitmcgill Reason: 1
Hello All,

So i hooked up a 16x2 LCD to arduino uno using the specs of the LCD shield. to get a better understanding of how
the chars are displayed, I am not using the liquidcrystal library ..

When i run the code, the LCD powers up, I see the top row of the LCD with all blocks but no binking cursor (which
I expected to see based on my code below)

Anyone care to help ?

Code: [Select]
//using the 16x2 lcd in 8 bit mode with low level
//access(no library)

int pinRS = 2;
int pinRW = 3;
int pinEN = 4;

int pinDATA0 = 5;
int pinDATA1 = 6;
int pinDATA2 = 7;
int pinDATA3 = 8;
int pinDATA4 = 9;
int pinDATA5 = 10;
int pinDATA6 = 11;
int pinDATA7 = 12;

void setup()
{
pinMode(pinRS, OUTPUT);
pinMode(pinRW, OUTPUT);
pinMode(pinEN, OUTPUT);

initializeLCD();
}

void loop()
{
 //initializeLCD();
 digitalWrite(pinRW, LOW);
}

void initializeLCD()
{
 //set the LCD in writing mode
digitalWrite(pinRW, LOW);
digitalWrite(pinEN, HIGH);

//set the lcd select register for a command
digitalWrite(pinRS, LOW);

//issue command to display blinking cursor
digitalWrite(pinDATA0,HIGH);
digitalWrite(pinDATA1,HIGH);
digitalWrite(pinDATA2,HIGH);
digitalWrite(pinDATA3,HIGH);
digitalWrite(pinDATA4,LOW);
digitalWrite(pinDATA5,LOW);
digitalWrite(pinDATA6,LOW);
digitalWrite(pinDATA7,LOW);

//toggle the enable line to execute instruction
digitalWrite(pinEN, LOW);
delay(20);
digitalWrite(pinEN, HIGH);
}


thank you for the help.

another quick side question, if i execute a command/display a char on the lcd in the startup part of my code
do i need to repeat it in my loop or the lcd would hold its state ?

Thank you !
ankit

ankitmcgill

update ... i made a quick program using the liquidcrystal library to see if it was the code or my
connections .. that works just fine .. so it is something in my code  :smiley-roll:

floresta

#2
Feb 29, 2012, 04:00 pm Last Edit: Feb 29, 2012, 04:04 pm by floresta Reason: 1
You have a good start but there is a lot more to do.  You have chosen to use an 8-bit data interface which is a very good idea.  Since you should not try to deal with the busy flag at this point you can disconnect R/W (LCD pin 5) from the Arduino and connect it to GND.  The other choice would be to leave R/W connected, set it low at the beginning of your sketch, and forget about it.

You are getting a single row of blocks because your LCD controller is not properly initialized.  In order to initialize the LCD controller you have to send it a whole series of commands.  When you get that done correctly you will see your cursor.  Follow the LCD Initialization link at http://web.alfredstate.edu/weimandn to find out what you have to do.  

Take a stab at it, post your code, and we will go from there.


Quote
another quick side question, if i execute a command/display a char on the lcd in the startup part of my code
do i need to repeat it in my loop or the lcd would hold its state ?

The LCD display does not have to be refreshed.  Once you display a character it will remain on the screen until overwritten.  To 'erase' it you overwrite it with a 'space'.

Don

ankitmcgill

@Don, Thank you for pointing me in the right direction .. after reading up on the controller initialization i modified my code to ...

Code: [Select]
//using the 16x2 lcd in 8 bit mode with low level
//access(no library)

int pinRS = 2;
int pinEN = 4;

int pinDATA0 = 5;
int pinDATA1 = 6;
int pinDATA2 = 7;
int pinDATA3 = 8;
int pinDATA4 = 9;
int pinDATA5 = 10;
int pinDATA6 = 11;
int pinDATA7 = 12;

void setup()
{
pinMode(pinRS, OUTPUT);
pinMode(pinEN, OUTPUT);

digitalWrite(pinEN, HIGH);
digitalWrite(pinRS, LOW); //instruction mode

initializeLCD();
}

void loop()
{
  //initializeLCD();

}

void initializeLCD()
{
//step1: wait more than 100ms
delay(150);

//step2
setLCDDataPins(0x30);
toggleENLine();
delay(10);

//step3
setLCDDataPins(0x30);
toggleENLine();
delay(5);

//step4
setLCDDataPins(0x30);
toggleENLine();
delay(5);

//step5
setLCDDataPins(0x38);
toggleENLine();
delay(5);

//step6
setLCDDataPins(0x08);
toggleENLine();
delay(5);

//step7 .. clear display .. since has to write to all the
//screen memory .. takes longer to execute
setLCDDataPins(0x01);
toggleENLine();
delay(20);

//step8
setLCDDataPins(0x06);
toggleENLine();
delay(5);

//---end of lcd initialization ---

//step 9: turn on the lcd + show cursor
setLCDDataPins(0x0E);
toggleENLine();
delay(5);

}

void setLCDDataPins(int val)
{
  char pins[8] = {5, 6, 7, 8, 9, 10, 11, 12};
                     
  for(int j=7; j>=0; --j)
  {
    if(val & (1<<j)) digitalWrite(pins[j], HIGH);
    else digitalWrite(pins[j], LOW);
  }
}

void toggleENLine()
{
  digitalWrite(pinEN, LOW);
  delay(30);
  digitalWrite(pinEN, HIGH);
}


So now I get the blinking cursor ! :D. the one thing that is not working is the clearing of the screen ... i see the blinking coursor but its overlaid on top of whatever was on the screen last.

as per the link, screen clearing while initialization might take a while so instead of using a fixed amount of delay,i tried monitoring the busy flag

modified step7 in the code to

Code: [Select]
//step7 .. clear display .. since has to write to all the
//screen memory .. takes longer to execute
setLCDDataPins(0x01);
toggleENLine();
pinMode(pinDATA7, INPUT);
while(digitalRead(pinDATA7)!=HIGH) {}
pinMode(pinDATA7, OUTPUT);


however now it just seems to get stuck in an infinite loop ie. no blinking cursor also... any ideas ?

ankitmcgill

Solved ... forgot to initialize the data pins as OUTPUT in my code revision.

everything's working perfectly fine now :D

Go Up