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