1
\$\begingroup\$

I have a HD44780 compatible lcd display (QC1602A). I did a lot of research and found some helpful things, but none of then seemed to really have worked. I'm not using any lcd library (C), only the wiringPi lib for turning on/off pins (RaspberryPi).

To test my lcd I wrote this program:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <wiringPi.h>


#define P0  0
#define P1  1
#define RS  2//RS Pin
#define En  3//Data Enable
#define DB4 4//Data Bus DB4-DB7 (4-bit)
#define DB5 5
#define DB6 6
#define DB7 7
#define C0 10//Yellow Led


void waitAndPrint(unsigned int sec)
{
    while(sec) {
        printf("%d", sec);
        printf(" Second(s)\r");
        delay(1000);
        sec--;
    }
}

void writeToBus(char var1, char var2)//Hex value. writeToBus(lowNybble,highNybble)
{
    int binary1[4];
    switch(var1) {
        case 0x0: binary1[0]=0; binary1[1]=0; binary1[2]=0; binary1[3]=0; break;
        case 0x1: binary1[0]=0; binary1[1]=0; binary1[2]=0; binary1[3]=1; break;
        case 0x2: binary1[0]=0; binary1[1]=0; binary1[2]=1; binary1[3]=0; break;
        case 0x3: binary1[0]=0; binary1[1]=0; binary1[2]=1; binary1[3]=1; break;
        case 0x4: binary1[0]=0; binary1[1]=1; binary1[2]=0; binary1[3]=0; break;
        case 0x5: binary1[0]=0; binary1[1]=1; binary1[2]=0; binary1[3]=1; break;
        case 0x6: binary1[0]=0; binary1[1]=1; binary1[2]=1; binary1[3]=0; break;
        case 0x7: binary1[0]=0; binary1[1]=1; binary1[2]=1; binary1[3]=1; break;
        case 0x8: binary1[0]=1; binary1[1]=0; binary1[2]=0; binary1[3]=0; break;
        case 0x9: binary1[0]=1; binary1[1]=0; binary1[2]=0; binary1[3]=1; break;
        case 0xA: binary1[0]=1; binary1[1]=0; binary1[2]=1; binary1[3]=0; break;
        case 0xB: binary1[0]=1; binary1[1]=0; binary1[2]=1; binary1[3]=1; break;
        case 0xC: binary1[0]=1; binary1[1]=1; binary1[2]=0; binary1[3]=0; break;
        case 0xD: binary1[0]=1; binary1[1]=1; binary1[2]=0; binary1[3]=1; break;
        case 0xE: binary1[0]=1; binary1[1]=1; binary1[2]=1; binary1[3]=0; break;
        case 0xF: binary1[0]=1; binary1[1]=1; binary1[2]=1; binary1[3]=1; break;
    }
    int binary2[4];
    switch(var2) {
        case 0x0: binary2[0]=0; binary2[1]=0; binary2[2]=0; binary2[3]=0; break;
        case 0x1: binary2[0]=0; binary2[1]=0; binary2[2]=0; binary2[3]=1; break;
        case 0x2: binary2[0]=0; binary2[1]=0; binary2[2]=1; binary2[3]=0; break;
        case 0x3: binary2[0]=0; binary2[1]=0; binary2[2]=1; binary2[3]=1; break;
        case 0x4: binary2[0]=0; binary2[1]=1; binary2[2]=0; binary2[3]=0; break;
        case 0x5: binary2[0]=0; binary2[1]=1; binary2[2]=0; binary2[3]=1; break;
        case 0x6: binary2[0]=0; binary2[1]=1; binary2[2]=1; binary2[3]=0; break;
        case 0x7: binary2[0]=0; binary2[1]=1; binary2[2]=1; binary2[3]=1; break;
        case 0x8: binary2[0]=1; binary2[1]=0; binary2[2]=0; binary2[3]=0; break;
        case 0x9: binary2[0]=1; binary2[1]=0; binary2[2]=0; binary2[3]=1; break;
        case 0xA: binary2[0]=1; binary2[1]=0; binary2[2]=1; binary2[3]=0; break;
        case 0xB: binary2[0]=1; binary2[1]=0; binary2[2]=1; binary2[3]=1; break;
        case 0xC: binary2[0]=1; binary2[1]=1; binary2[2]=0; binary2[3]=0; break;
        case 0xD: binary2[0]=1; binary2[1]=1; binary2[2]=0; binary2[3]=1; break;
        case 0xE: binary2[0]=1; binary2[1]=1; binary2[2]=1; binary2[3]=0; break;
        case 0xF: binary2[0]=1; binary2[1]=1; binary2[2]=1; binary2[3]=1; break;
    }

    digitalWrite(DB4, binary2[0]);
    digitalWrite(DB5, binary2[1]);
    digitalWrite(DB6, binary2[2]);
    digitalWrite(DB7, binary2[3]);
    digitalWrite(En, 1);
    delay(20);
    digitalWrite(En, 0);
    digitalWrite(DB4, binary1[0]);
    digitalWrite(DB5, binary1[1]);
    digitalWrite(DB6, binary1[2]);
    digitalWrite(DB7, binary1[3]);
    digitalWrite(En, 1);
    delay(20);
    digitalWrite(En, 0);
    digitalWrite(DB4, 0);
    digitalWrite(DB5, 0);
    digitalWrite(DB6, 0);
    digitalWrite(DB7, 0);
    delay(20);
}

// suggested wrapper method for Mattia_98's writeToBus function -- MarkU
void sendHD44780command(char data)
{
    digitalWrite(RS, 0);//Turn RS Mode off
    writeToBus(
            ((data >> 0) & 0x0F),    // low nybble is send second
            ((data >> 4) & 0x0F)     // high nybble is sent first
        );
}
// suggested wrapper method for Mattia_98's writeToBus function -- MarkU
void sendHD44780data(char data)
{
    digitalWrite(RS, 1);//Turn RS Mode on
    writeToBus(
            ((data >> 0) & 0x0F),    // low nybble is send second
            ((data >> 4) & 0x0F)     // high nybble is sent first
        );
}

void initHD44780_4bit(void)
{
    // D7-D4 connected, D3-D0 no connect. High nybble is sent first. Function set DL=0.

    // HD44780 command 0x30-0x33 = Function set: DL=1_8 bit interface, N=0_1 line,  F=0_5x7 font
    sendHD44780command(0x30); 

    // HD44780 command 0x20-0x23 = Function set: DL=0_4 bit interface, N=0_1 line,  F=0_5x7 font
    sendHD44780command(0x20); 

    // HD44780 command 0x28-0x2B = Function set: DL=0_4 bit interface, N=1_2 lines, F=0_5x7 font
    sendHD44780command(0x28); //4-bit, 2 line, 5x7 dots

    // HD44780 command 0x0C = Display On/Off Control: D=1_display enabled, C=0_hide cursor, B=0_unblinking cursor
    sendHD44780command(0x0C); // Display ON cursor OFF

    // HD44780 command  0x06 = Entry mode set: I/D=1_increment, S=0_noShift no display shift
    sendHD44780command(0x06); // Set entry mode (Auto increment)

    // HD44780 command  0x80-0xBF = display line 1
    sendHD44780command(0x80); // Bring cursor to line 1
}

int main(void)
{
    printf("|------------------------|\n");
    printf("|-----LCD HelloWorld-----|\n");
    printf("|------By Mattia_98------|\n");
    printf("|--------GPL 2015--------|\n");
    printf("|------------------------|\n");

    printf("Initializing... ");
    setbuf(stdout, NULL);//No buffer
    wiringPiSetup();//WPi Setup-Method
    pinMode(P0, OUTPUT);//Set Input or Output
    pinMode(P1, OUTPUT);
    pinMode(RS, OUTPUT);
    pinMode(En, OUTPUT);
    pinMode(DB4, OUTPUT);
    pinMode(DB5, OUTPUT);
    pinMode(DB6, OUTPUT);
    pinMode(DB7, OUTPUT);
    pinMode(C0, OUTPUT);
    digitalWrite(P0, 0);//Put everything to Off
    digitalWrite(P1, 0);
    digitalWrite(RS, 0);
    digitalWrite(En, 0);
    digitalWrite(DB4, 0);
    digitalWrite(DB5, 0);
    digitalWrite(DB6, 0);
    digitalWrite(DB7, 0);
    digitalWrite(C0, 0);
    initHD44780_4bit();//LCD Init-Method
    printf("Done!\n");


    //Send 'Hello world!' to the lcd
    sendHD44780data('H');
   sendHD44780data('e');
   sendHD44780data('l');
   sendHD44780data('l');
   sendHD44780data('o');
   sendHD44780data(' ');
   sendHD44780data('w');
   sendHD44780data('o');
   sendHD44780data('r');
   sendHD44780data('l');
   sendHD44780data('d');
   sendHD44780data('!');

    waitAndPrint(10);

    return 0 ;
}

It doesn't give any errors but it doesn't do anything. Of course I'll answer every question you do to me ;)

The datasheets I found say, its a 5V lcd.

When turned on, the first row fills with squares. After running the code above, both rows fill with squares.

The code above now displays some random characters. LCD displaying random characters

\$\endgroup\$
  • \$\begingroup\$ Do you have either a 3.3V LCD module or a RPi with 5V GPIOs? Because if not... \$\endgroup\$ – Ignacio Vazquez-Abrams Feb 7 '15 at 20:16
  • \$\begingroup\$ The datasheets i found say, its a 5v lcd. In the meantime i managed to get the first row with squares by connecting the contrast to a potentiometer (Yes, I forgot to connect the contrast). The C code is now able to fill both rows with squares. \$\endgroup\$ – Mattia_98 Feb 7 '15 at 20:44
  • 1
    \$\begingroup\$ Have you connected the RW pin to gnd? RS has the wrong polarity for data. You don't fill the LCD with squares, it just comes out of reset and the contrast is turned up all the way... \$\endgroup\$ – FRob Feb 8 '15 at 0:52
  • \$\begingroup\$ I don't see where you write any data to the HD44780 or send the complete initialization sequence. Your writeToBus(lowNybble,highNybble) calls would be clearer if commented with the HD44780 commands... writeToBus(0,1) is Function set, writeToBus(15,0) is display on/cursor on/blink on, writeToBus(6,0) is entry mode set, writeToBus(1,0) is clear display, writeToBus(2,0) is the home command. Then try adding writeToBus(13,4) should display capital letter M for example. \$\endgroup\$ – MarkU Feb 8 '15 at 7:48
  • \$\begingroup\$ @FRob Yes, RW is on GND and RS is attached to the Pi as you can see from the code (is set to 0). About the squares: when turned on, the first row goes on. After running the code above, both rows go on. \$\endgroup\$ – Mattia_98 Feb 8 '15 at 12:47
1
\$\begingroup\$

Your code is missing some initialization commmands.

lcd_init from http://www.8051projects.net/lcd-interfacing/lcd-4-bit-programming.php actually sends this sequence:

void initHD44780_4bit(void)
{
    // D7-D4 connected, D3-D0 no connect. High nybble is sent first. Function set DL=0.

    // HD44780 command 0x30-0x33 = Function set: DL=1_8 bit interface, N=0_1 line,  F=0_5x7 font
    sendHD44780command(0x30); 

    // HD44780 command 0x20-0x23 = Function set: DL=0_4 bit interface, N=0_1 line,  F=0_5x7 font
    sendHD44780command(0x20); 

    // HD44780 command 0x28-0x2B = Function set: DL=0_4 bit interface, N=1_2 lines, F=0_5x7 font
    sendHD44780command(0x28); //4-bit, 2 line, 5x7 dots

    // HD44780 command 0x0C = Display On/Off Control: D=1_display enabled, C=0_hide cursor, B=0_unblinking cursor
    sendHD44780command(0x0C); // Display ON cursor OFF

    // HD44780 command  0x06 = Entry mode set: I/D=1_increment, S=0_noShift no display shift
    sendHD44780command(0x06); // Set entry mode (Auto increment)

    // HD44780 command  0x80-0xBF = display line 1
    sendHD44780command(0x80); // Bring cursor to line 1
}

Note that in "nybble mode" (4-bit interface), the most significant nybble is sent first. So I strongly suggest you swap your writeToBus arguments, putting the MSB first... that makes it easier to understand when reading the HD44780 data sheet.

// suggested wrapper method for Mattia_98's writeToBus function -- MarkU
void sendHD44780command(char data)
{
    digitalWrite(RS, 0);//Turn RS Mode off
    writeToBus(
            ((data >> 0) & 0x0F),    // low nybble is send second
            ((data >> 4) & 0x0F)     // high nybble is sent first
        );
}
// suggested wrapper method for Mattia_98's writeToBus function -- MarkU
void sendHD44780data(char data)
{
    digitalWrite(RS, 1);//Turn RS Mode on
    writeToBus(
            ((data >> 0) & 0x0F),    // low nybble is send second
            ((data >> 4) & 0x0F)     // high nybble is sent first
        );
}

Then after the initial call to initHD44780_4bit(), you should send some data, so you can see whether the display is actually working.

// send test message to HD44780
void helloWorld(void)
{
    sendHD44780data('H');
    sendHD44780data('e');
    sendHD44780data('l');
    sendHD44780data('l');
    sendHD44780data('o');
    sendHD44780data(' ');
    sendHD44780data('w');
    sendHD44780data('o');
    sendHD44780data('r');
    sendHD44780data('l');
    sendHD44780data('d');
    sendHD44780data('!');
}

This should be enough to get you started. Cheers -- Mark

\$\endgroup\$
  • \$\begingroup\$ Thank you! It now displays something on the screen. Not Hello world! but something. I'm gonna look why it displays the wrong characters but I relay appreciated your help. Sry 4 the late answer P.S.: I updated the code in the question \$\endgroup\$ – Mattia_98 Feb 13 '15 at 16:32
  • \$\begingroup\$ Check your data bit wiring; you could have two data bits swapped or otherwise have them in an incorrect order. Also make sure that D7 through D4 are pulled up with resistors (anything between 1k and 10k ohms should be fine). \$\endgroup\$ – akohlsmith Feb 13 '15 at 19:03
  • \$\begingroup\$ If D7-D4 were swapped, the display would not receive the command to switch to nybble mode, which might explain why the nonsense characters are displayed: inputs D3-D0 would still be read by the HD44780. \$\endgroup\$ – MarkU Feb 13 '15 at 19:10

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.