Netduino Day 2: Interfacing a Character LCD



Liquid Crystal Displays (LCD) are a great choice of output device for displaying alphanumeric characters in real time. They are also very useful if your project requires an interactive user interface for data input. Besides, they are inexpensive, consume less power than LED displays, and give a more professional look to your project. Today we will explore how to interface an HD44780 based character LCD to Netduino to display alphanumeric characters. For technical details of the HD44780 driver, please read its datasheet as well as its interfacing example with chipKit.

Information displayed on Character LCD

Circuit Setup and Theory

Connection wise it’s really simple. The LCD is operated in 4-bit mode, and therefore pins 7 through 10 (D0-D3) of the LCD are unused. The four most significant data bits, D4-D7 (pins 12 through 14), receives LCD data/command through Netduino I/O pins 7, 5, 3, and 1, respectively. Similarly, the Register Select (R/S) and Enable (E) signal lines of the LCD are driven by Netduino I/O pins 11 and 9, respectively. LCD pins 1, 2, 3, 4, 15 and 16 are related to power supply, contrast adjustment and backlight LED display, and are connected appropriately as shown below. To understand how LCD works, I have to point you to a different document as it is explained better over there. In Interfacing a Character LCD,Raj explains about the communication in 4 bit mode and he also talks about the basics of HD44780 LCD driver. For more technical details, see Hitachi HD44780U (LCD-II) datasheet.

Interfacing a HD44780 character LCD with Netduino

Connection With Netduino / Netduino Plus

Breadboard Connection: Character LCD and Netduino

C#.NET Program

There are two ways we can look at the program, one in a very simple way and other, obviously, harder way. In simpler way we don’t worry about what’s inside the LCD class (or a library) rather use some of the exposed methods or properties. Let’s take a look at the simpler things first.

LCD lcd = new LCD(
    Pins.GPIO_PIN_D11, // RS
    Pins.GPIO_PIN_D9,  // Enable
    Pins.GPIO_PIN_D7,  // D4
    Pins.GPIO_PIN_D5,  // D5
    Pins.GPIO_PIN_D3,  // D6
    Pins.GPIO_PIN_D1,  // D7
    20,                // Number of Columns
    LCD.Operational.DoubleLIne, // LCD Row Format
    4,                 // Number of Rows in LCD
    LCD.Operational.Dot5x8);    // Dot Size of LCD
 
lcd.ShowCursor = true;
lcd.Show("www.Embedded-Lab.comWelcome's you to Netduino Tutorial site.  Happy Learning! :)", 200, true);
Thread.Sleep(1000); // reading time for the viewer

As you can see we created an instance of LCD class and then set some properties to what we like and simply called the Show method. There are two Show methods, one will display the given text all at once and the other Show method will display one letter at a time.

Now let’s dig into the complex part. There are several libraries out there but I wrote my own to understand what’s cooking inside. Let’s look at the constructor section,

public LCD(Cpu.Pin rs, Cpu.Pin enable,
    Cpu.Pin d4, Cpu.Pin d5, Cpu.Pin d6, Cpu.Pin d7,
    byte columns, Operational lineSize, int numberOfRows,
    Operational dotSize)
{
    RS = new OutputPort(rs, false);
    Enable = new OutputPort(enable, false);
    D4 = new OutputPort(d4, false);
    D5 = new OutputPort(d5, false);
    D6 = new OutputPort(d6, false);
    D7 = new OutputPort(d7, false);
 
    Columns = columns;
    DotSize = (byte)dotSize;
    NumberOfLines = (byte)lineSize;
    NumberOfRows = numberOfRows;
 
    Initialize();
}

In the constructor section, it basically creates some Outport, saves the LCD properties and then calls the Initialize method. In this method, we set visual properties, initialize some arrays and then prepare the LCD for 4 bit communication mode.

private void Initialize()
{
    //initialize fields
    isVisible = true;
    showCursor = false;
    isBlinking = false;
 
    rowAddress = new byte[] { 0x00, 0x40, 0x14, 0x54 };
    firstHalfAddress = new byte[] { 0x10, 0x20, 0x40, 0x80 };
    secondHalfAddress = new byte[] { 0x01, 0x02, 0x04, 0x08 };
 
    currentRow = 0;
    dirtyColumns = 0;
 
    Thread.Sleep(50); // must wait for a few milliseconds
 
    // RS to high = data transfer
    // RS to low = command/instruction transfer
    RS.Write(false);
 
    // Enable provides a clock function to synchronize data transfer
    Enable.Write(false);
 
    // Set for 4 bit model
    Write(0x03, secondHalfAddress);
    Thread.Sleep(4);
    Write(0x03, secondHalfAddress);
    Thread.Sleep(4);
    Write(0x03, secondHalfAddress);
    Thread.Sleep(150);
    Write(0x02, secondHalfAddress);
 
    // Set the LCD properties
    byte operationalValue = (byte)((byte)Operational.FourBit | (byte)NumberOfLines | (byte)DotSize);
    SendCommand((byte)((byte)Command.Operational | operationalValue));
 
    UpdateDisplayOptions();
 
    ClearDisplay();
 
    byte entranceValue = (byte)Entrance.FromLeft | (byte)Entrance.ShiftDecrement;
    SendCommand((byte)((byte)Command.Entrance | entranceValue));
 
}

Now, let’s look at the methods that are critical to show the text to the LCD. The first Show method allows us to show the given text letter by letter as you can see the loop is structured for each character in the given text.

public void Show(string text, int delay, bool newLine)
{
    if (newLine) dirtyColumns = 0;
    foreach (char textChar in text.ToCharArray())
    {
        ResetLines();
        Show(Encoding.UTF8.GetBytes(textChar.ToString()));
        dirtyColumns += 1;
        Thread.Sleep(delay);
    }
}

The second Show method basically shows the whole text at once but before that it does some formatting so that the text will appear continuously. Trust me showing given text in a continuous way is one of the difficult part that I resolved in this LCD class.

public void Show(string text)
{
    string[] splitedText = SplitText(text);
    Show(splitedText);
}

Finally, the method that writes information to the LCD is done under Write method. The first Write method calls the send Write method it passes the write value and the address where to send the information. The second Write method basically writes the information to the LCD.

private void Write(byte[] data)
{
    foreach (byte value in data)
    {
        Write(value, firstHalfAddress); // First half
        Write(value, secondHalfAddress); // Second half
    }
}
 
private void Write(byte value, byte[] halfAddress)
{
    D4.Write((value & halfAddress[0]) > 0);
    D5.Write((value & halfAddress[1]) > 0);
    D6.Write((value & halfAddress[2]) > 0);
    D7.Write((value & halfAddress[3]) > 0);
 
    Enable.Write(true);
    Enable.Write(false);
    //Debug.Print("Wrote " + value.ToString());
}

Output

After connecting a few wires, when you run your code and visualize the text that you wanted, puts smile in your face. Depending upon which Show method you are using will give you get different results, one will show letter by letter and other will show whole text at once. As in the video, when you rotate the potentiometer, the display contrast changes.

Character LCD, ready to take input

Output on Character LCD showing digits and alphabets

A small Video based on the following code:

lcd.ShowCursor = true;
lcd.Show("www.Embedded-Lab.comWelcome's you to Netduino Tutorial site.  Happy Learning! :)", 200, true);
Thread.Sleep(1000); // reading time for the viewer
 
lcd.ClearDisplay();
lcd.Show("That was cool! Let's clear the display and show all text at once", 200, true);
Thread.Sleep(1000); // reading time for the viewer
 
lcd.ClearDisplay();
lcd.ShowCursor = false;
lcd.Show("ABCDEFGHILKLMnopqrstuvwxyz0123456789                              -Thanks!");

Downloads

1)     C#.NET Code (Solution file)

2)     Flitizing file

 

What Next

In our next tutorial we will learn about interfacing seven segments LED displays to Netduino. Seven segments LEDs commonly found in many electronics equipments as front panel displays. The next tutorial will also include a Light Dependent Resistor (LDR) to sense the surrounding light intensity that will be displayed on 4 seven segment LEDs.

3 comments

Leave a Reply

Your email address will not be published. Required fields are marked *