An ultra customizable LCD Shield for Arduino

By on April 23, 2013

 

Often, during your first experiences with Arduino, you use the Serial Monitor, a feature available in the IDE, which allows you to display values ​​on the screen. However, if we you want to display values ​​or strings locally on the board, it would be very convenient to have a small display and a few buttons (useful if you want to set values). That’s why we proposed an LCD shield, created to mount an LCD Display plus three useful buttons for general use.

lcd shield4162

For maximum compatibility we have sought to provide a shield on which you can install different models of LCD displays, so as not to force you to use a given model.

 

This is compatibile with virtually all displays made ​​with the Hitachi HD44780 chip (or compatible) that are the overwhelming majority. Their communication takes place via a bus of eight lines but if properly configured they can communicate with only four lines of data plus the Register Select (RS) and Enable (E) commands, for a total six digital lines.

lcd shield8x2

 

As for us, we tested the shield with the following displays:

 

- LMB0820 (alphanumeric 8×2)

- ADM1602K (alphanumeric 16×2)

- DISPLAYTECH162B (alphanumeric 16×2)

- ACM1602B (alphanumeric 16×2)

- TM162AD ( alphanumeric 16×2).

 

The shied is purchased on open-electronics store with a 16×2 display.

lcd shield8x2_2

 

Regardless of the type of connector adopted by the manufacturer and regardless of how they arranged pins, all displays based on HD44780 have the same interface, consisting of eight bits of data, three control lines, the power supply and GND plus a line for adjusting the contrast.

The arrangement of the lines changes from model to model: before using a display you shall check the data-sheet. Some models sports a LED backlight, powered via two connectors.

 

Pindisplay

function

PinArduino

VDD

+5 V Power supply

+5 V

Vss

GND Power supply

GND

Vo

contrast voltage

Trimmer

RS

Selection: write data or commands

8

R / W

Enables the reading or writing in the display

GND

Enable

Enable Line

9

DB0

Data line 0

Not used

DB1

Data line 1

Not used

DB2

Data line 2

Not used

DB3

Data line 3

Not used

DB4

Data line  4

4

DB5

Data Line  5

5

DB6

Data line  6

6

DB7

Data Line  7

7

BL +

LED Backlight +

+5 V

BL-

LED Backlight -

GND

Table shows the connections between a generic display based on HD44780 and the  Arduino chip.

lcd shield

 

Pin Button

Arduino’s PIN

(digital mode)

Arduino’s PIN

(analog mode)

S1

10

AN3

S2

11

AN3

S3

12

AN3

Pin of the shield assigned to the buttons

The shield has three different types of connectors according to the type of display that you may want to connect. The connectors are positioned so as to leave room for three generic buttons and the reset, the contacts of Arduino are always available from the power supply side, while the availability of digital contacts (0 to 13) is granted only for smaller displays.

 

To work properly, each LCD display requires a small voltage for adjusting the contrast, which is normally obtained through a trimmer whose ends are powered by the 5 volt main power supply.

 

Remember that, while the display absorbs just a few milliamps, its backlight can have a power consumption of 50 to 100 mA, which is defintely too much where thereìs battery power. That’s why we planned a switch that gives you the ability to activate or deactivate the back light, that consists of parallel/series connected LEDs that lit at the maximum intensity by feeding to 5 volts.

lcd shield schematics

To avoid that the LEDs of the backlight broke up, it is necessary to limit the current; a resistance (R4) of 22 ohms is provided and is suitable for most of the displays. If you power Arduino with a power supply which delivers more than 8 volts, we recommend bringing R4 to 47 ohms, so to avoid the internal 5 volt  voltage regulator to overheat.

 

In case you also need to input data, we provided three buttons.  Since our aim is to offer you a flexible shield, we provided two ways of buttons connection: the first is the classic one which makes use of the three digital lines of Arduino (specifically pins 10, 11, 12) thanks to the SPI port, leaving free pin 13, which corresponds to the LED system; in this way the only digital lines available are the 0, 1, 2, 3 and 13. To activate this mode, you have to shortcut the JP2, JP4, JP6, JP7 jumpers.

lcd shield silk

We haven’t considered the usual pull-UP resistors as already implemented in the Arduino board: they can be easily activated via the software using pinMode (buttonPin, INPUT_PULLUP). Buttons actually work in negative logic: pressing the value means zero.

A second mode involves the use of a single analog line, the 3, which allows you to leave up to 8 digital lines available plus two analog lines 4 and 5, those used by the I ² C bus. To activate this mode, you have to shortcut the JP1, JP3, JP5, JP7 jumper, as shown in Fig7.With this mode on, all lines may be used as analog, except line 3: if necessary you can use the 4 and 5 for connecting I ² C peripherals.

 

To understand how it is possible to use a single analog line to handle the three buttons you shall check the circuit diagram and the network formed by R5, R6 and R7. These resistors, in series, form voltage divider. When no button is pressed, the AN3 line is at 5 volts because no current flows to ground; if we press the S1, AN3 is shorted to ground and its voltage is zeroed. If we press S2 the node between the R6 and R7 is grounded, so that line AN3 reaches the voltage 5 · R6 / (R5 · R6) = 1.6 volts . If, instead, we press S3, the R7 is shorted to ground and AN3 goes to 5 · (R6 + R7) / (R5 + R6 + R7) = 3.3 V.

This means that for each button pressed in the line, AN3 gets to a different voltage corresponding to different values of the Arduino ADC converter. The analogRead (A3) function will provide a different numerical value depending on which button is pressed, which will be approximately those shown in Table3.

 

button pressed

AN3 voltage

ADC value

None

5v

1024

P1

0v

0

P2

1.6 v

328

P3

3.3v

676

Analog mode of reading of the buttons

This clever system allows you to read the status of three buttons using one analog line.

While choosing the pins to be used by the shield we took into account the compatibility with other shields, in particular, you can release the pins relative to the SPI bus (used for example by the Wi-Fi or SD shield) and the I²C bus pins (AN4 and AN5) used by many sensors such as accelerometers and gyroscopes.

 

Programming

Programming via Arduino IDE it’s straightforward; it does not require any additional library as the system library (LiquidCrystal), already includes all necessary functions. Let’s look at the following, statement by statement.

 

- LiquidCrystal lcd(rs, enable, d4, d5, d6, d7) – initializes the display and will declare it as an object named lcd later used for calling library functions. The Arduino pins used for controlling the display must be specified: four data lines and two control lines.

 

- lcd.begin (cols, rows); – Set the number of columns (cols) and the number of rows (rows). For the LMB0820 display we should specify the ​​8 and 2 while, for all the others, the values ​​are 16 and 2.

 

- lcd.clear (); Clears the display.

 

- Lcd.home ();Positions the cursor at the beginning of the first line and the first column.

 

- lcd.setCursor (thisRow, thisCol) Places the cursor in the thisRow (0 is the first row) row and in thisCol (0 is the first column) column. For example, to place the cursor in the middle of the second row, in a 16×2 display, you would write lcd.setCursor(1.8)

 

- lcd.write (data) Writes a character on the display providing the ASCII code.

 

- lcd. print (“text”); writes a text on the screen from the current cursor position.

 

- lcd.print (var) Writes the value of the ‘var’ variable in the display at the current cursor position. If the variable is a float, it’s integer part will be displayed plus only two in the decimal digits.

 

- lcd.cursor (); Enables the display of the cursor on the current position.

 

- lcd.noCursor (); Disables the display of the cursor current position.

 

- lcd.blink (); Activates cursor flashing (if displayed.)

 

- lcd.noBlink (); Disables cursor blinking (if displayed.)

 

- lcd.display (); Enables the display.

 

- lcd . nodisplay (); Disables the display.

 

- lcd.scrollDisplayRight (); Translates text one place to the right.

 

- lcd.scrollDisplayLeft (); easy to guess :)

 

- lcd.autoscroll () Enables the automatic movement of the cursor after the introduction of a new character.

 

- lcd.noAutoscroll (); Disables the automatic movement of the cursor after the introduction of a new character.

 

- lcd.leftToRight (); Sets the direction in which will be added to the next character. By default, the character will be added to the right of the last character entered.

 

- Lcd.rightToLeft (); easy to guess :)

 

- Lcd.createChar (); This function allows you to create a special character not included in the basic set of characters of the display. You can create up to eight special characters (0 to 7) with a 8×5 pixels resolution. The new character is specified as a byte array containing the pixels to be displayed. The write function will be used to display the customized characters (0 to 7 indexes).

 

Autoscroll

Demonstration of autoscroll () and noAutoscroll () functions.

Blink

Example in which you can enable and disable blinking

Cursor

Example in which you can enable and disable displaying the cursor

CustomCharacter

How to use custom characters

Display

Demonstration of display () and nodisplay () functions to enable or disable the visualization.

HelloWorld

Shows Hello World and a counter

Scroll

Displays “Hello World!” and uses the scrollDisplayLeft () and scrollDisplayRight () to slide.

SerialDisplay

Displays the characters sent from a PC (eg: SerialMonitor)

SetCursor

How to set the cursor position on the display

TextDirection

Demonstration of leftToRight () and rightToLeft ()functions to move the cursor .

Examples available in the liquidCristal library

All the examples included in the library are compatible with our LCD shield but you need to specify carefully the pins used when declaring the LiquidCrystal(rs, enable, d4, d5, d6, d7) object:

rs → 8

enable → 9

d4 → 4

d5 → 5

d6 → 6

d7 → 7

 

The correct syntax to create the “lcd” object is: LiquidCrystal lcd (8, 9, 4, 5, 6, 7); change this line to make the library examples compatible with our shield. You must also specify the type of display used tank to the line lcd.begin (numCaratteri,numRighe);  numCaratteri indicates the number of display characters (usually 8, 16 or 20) while numRighe the number of rows (usually 2 or 4).

/*

 LCDshieldFE_1 Example 1

 Buttons connected to digital pins

*/

// include la libreria:

#include <LiquidCrystal.h>

#define P1 10

#define P2 11

#define P3 12

// setups of the display

LiquidCrystal lcd(8, 9, 4, 5, 6, 7);

void setup() {

 // sets buttons inputs

 pinMode(P1, INPUT_PULLUP);

 pinMode(P2, INPUT_PULLUP);

 pinMode(P3, INPUT_PULLUP);

 // sets the columns and rows number

 lcd.begin(16, 2);

 // shows the message

 lcd.print("Hello!");

}

void loop() {

 // moves the cursor one row down

 lcd.setCursor(0, 1);

 // shows the pressed button

 if ( digitalRead(P1)==0 ) lcd.print("P1 ");

 if ( digitalRead(P2)==0 ) lcd.print("P2 ");

 if ( digitalRead(P3)==0 ) lcd.print("P3");

}

 

/*

 LCDshieldFE_2 Esempio2

 Buttons connected to the analog line

*/

// includes of the library

#include <LiquidCrystal.h>

#define pushPin 3

// setup of the display

LiquidCrystal lcd(8, 9, 4, 5, 6, 7);

void setup() {

 // sets the columns and rows number

 lcd.begin(16, 2);

 // shows the message

 lcd.print("Hello!");

}

void loop() {

 // moves the cursor one row down

 lcd.setCursor(0, 1);

 // shows the pressed button

 int pushValue = analogRead(pushPin);

 if ( pushValue < 164 )

   lcd.print("P1");

 else if ( pushValue < 502 )

   lcd.print("P2");

 else if ( pushValue < 850 )

   lcd.print("P3");

 else

   lcd.print("  ");

}

 

/*

 LCDshieldFE_3 Esempio3

 Visualizza carattere personale

*/

#include <LiquidCrystal.h>

LiquidCrystal lcd(8, 9, 4, 5, 6, 7);

// creates the special “smiley” char

byte smiley[8] = {

 0b00000,

 0b00000,

 0b01010,

 0b00000,

 0b00000,

 0b10001,

 0b01110,

 0b00000

};

void setup() {

 // creates the special char in the 0 position

 lcd.createChar(0, smiley);

 lcd.begin(16, 2);

 lcd.print("Hello! ");

 // shows it

 lcd.write((byte)0);

}

void loop() {

}

About Boris Landoni

Boris Landoni is the technical manager of Open-Electronics.org. Skilled in the GSM field, embraces the Open Source philosophy and its projects are available to the community.