[SOLVED] 16x2 LCD : HD44780 - Beginners Question - LCD initialization

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 ?

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

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

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.

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

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

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

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

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

everything's working perfectly fine now :smiley: