- How to Adjust X and Y Axis Scale in Arduino Serial Plotter (No Extra Software Needed)Posted 2 months ago
- Elettronici Entusiasti: Inspiring Makers at Maker Faire Rome 2024Posted 2 months ago
- makeITcircular 2024 content launched – Part of Maker Faire Rome 2024Posted 5 months ago
- Application For Maker Faire Rome 2024: Deadline June 20thPosted 6 months ago
- Building a 3D Digital Clock with ArduinoPosted 11 months ago
- Creating a controller for Minecraft with realistic body movements using ArduinoPosted 12 months ago
- Snowflake with ArduinoPosted 12 months ago
- Holographic Christmas TreePosted 12 months ago
- Segstick: Build Your Own Self-Balancing Vehicle in Just 2 Days with ArduinoPosted 1 year ago
- ZSWatch: An Open-Source Smartwatch Project Based on the Zephyr Operating SystemPosted 1 year ago
An ultra customizable LCD Shield for Arduino
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.
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.
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.
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.
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.
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.
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() { }