# LCD module not initializing

I've got a project where I need to use an LCD module, so I started pondering around with one (1602A).
So far I've wired it up with my microcontroller which is an Atmega168PA and written an initialization code for it based on the instructions found here.
I think I've done exactly as said in that instruction (I'm trying to use a 4-bit interface), but still haven't gotten the thing to work correctly.

To me it seems that for some reason the LCD module is not initialized correctly as after the MCU and LCD have both been powered up I only see one (first) line full of full-dotted characters (0xFF) and second line is blank although the screen should be cleared during initialization and cursor should be visible.

I've included my code below:

#ifndef F_CPU
#define F_CPU 8000000UL
#endif

#include <avr/io.h>
#include <util/delay.h>

void lcdLatchEnable (void)
{
PORTC |= (1<<4);  // enable latch pin

_delay_us(2);  // wait specified time

PORTC &= ~(1<<4);  //disable latch pin
}

void lcdWriteNibble (uint8_t byte)  // set data line according to upper nibble in function parameter 'data'
{

if (byte & 0x10)     // copy fourth bit value on the output pin
PORTC |= (1<<0);
else
PORTC &=~(1<<0);

if (byte & 0x20)     // copy fifth bit value on the output pin
PORTC |= (1<<1);
else
PORTC &=~(1<<1);

if (byte & 0x40)     // copy sixth bit value on the output pin
PORTC |= (1<<2);
else
PORTC &=~(1<<2);

if (byte & 0x80)     // copy seventh bit value on the output pin
PORTC |= (1<<3);
else
PORTC &=~(1<<3);

}

void lcdSendByte(uint8_t byte)
{
lcdWriteNibble(byte);  // send upper nibble
lcdLatchEnable();  // latch the upper nibble
byte <<= 4;  // shift bits in byte left 4 positions so lower nibble would be sent next
lcdWriteNibble(byte);  // send lower nibble
lcdLatchEnable();  // latch the upper nibble
}

void lcdSendNibble(uint8_t byte)
{
lcdWriteNibble(byte);  // write nibble to output pins
lcdLatchEnable(); // latch the values into LCD module
}

void lcdInit (void)
{
PORTC &= ~(1<<5); // configure LCD module into instruction mode (R/S line = 0)
_delay_ms(150);  // wait more than 100ms after power on

lcdWriteNibble(0x30);  // special case function set
lcdLatchEnable();   // latch in the values
_delay_ms(5);       // wait more than 4.1ms
lcdWriteNibble(0x30);  // special case function set
lcdLatchEnable();   // latch in the values
_delay_ms(1);       // wait more than 100us
lcdWriteNibble(0x30); // special case function set
lcdLatchEnable();   // latch in the values
_delay_ms(1);    // wait more than 100us

lcdWriteNibble(0x20);  // initial function set to change interface
lcdLatchEnable();   // latch in the values
_delay_ms(1);   // wait more than 100us

lcdSendByte(0x28); // send function set
_delay_ms(1);  // wait more than 53us

lcdSendByte(0x08); // display off, cursor off, blinking off
_delay_ms(1); // wait more than 53us

lcdSendByte(0x01); // clear display;
_delay_ms(5); // wait more than 3ms

lcdSendByte(0x06); // Entry mode set to increment and shift off
_delay_ms(10); // wait more than 53us

lcdSendByte(0x0C); // display on, cursor on

}

int main(void)
{
DDRC |= (1<<0)|(1<<1)|(1<<2)|(1<<3)|(1<<4)|(1<<5);  // configure pins as output for LCD module communication
PORTC = 0x00; // make sure that all the pins are configured as low

_delay_ms(150);

lcdInit();

_delay_ms(100);
lcdSendChar(0x30);

while(1)
{
}
}


And a picture of the display after it should be initialized and printing character 48:

UPDATE:

• I'm assuming that you don't get any errors when you compile your program? (By the way, if you think we would be able to figure out whether or not you plugged everything properly, there would be no way to tell. But it would still be nice if you provided a schematic of what you wired everything up to.) – KingDuken Oct 1 '18 at 14:49
• Realistically you should pull out all the wiring and start over with neatly routed cut-to-length pieces, as this will pay for itself many times over in reduced confusion and durability. Also do something (like monitor serial output) to verify that the AVR is running the program as intended. Check that the contrast control is not to blame. If this is original code, try finding someone else's to try as a cross check on the wiring, potentially even (temporarily) an "arduino" project. – Chris Stratton Oct 1 '18 at 14:49
• Do you have your LCD's reset line tied to one of your micro's pins? If you do, then giving the LED a reset at startup would be a good idea. – brhans Oct 1 '18 at 15:37
• Nope, no compile errors. I'm using Atmel Studio 6. I've added a schematic of my wiring. @KingDuken – rongard Oct 1 '18 at 15:45
• Yeah, I agree that the wiring isn't pretty, but I'm just trying out the LCD display and haven't got around to writing any real project code. So I don't think that I should waste that much time on perfecting the layout on a breadboard as there isn't that much wiring. I'm sure that the AVR gets programmed as it's supposed to as I added a blinking LED mode in the end of the code which indicates if it got progammed. Can't be the contrast error as I can see the full-dotted characters, can't I? ALso, I tried another header and source file from ElectroSome, but the result was the same. @ChrisStratton – rongard Oct 1 '18 at 15:52

PORTC pins 0 to 3 are powered by AVCC so parts of your AVR are unpowered and do not work.

• Yeap, that was the case, works perfectly now. Many thanks! @Justme – rongard Oct 1 '18 at 17:07