Liquid Crystal Displays for the Arduino
Ben Kuo, KK6FUT
Pete Juliano, N6QW
We have been gently urged by the QQ Editors to include LCD displays in our Arduino projects , as there is a certain allure, charm and magic to a “visually changing scene”. Seemingly it is a It would seem like a reasonable request , and one would think which would be easy to implement which of course . However, in reality may be reasonable but , it is not easy to implement an LCD display, like the one included in CW Sender Part II. The CW Sender Part III has an LCD Display in addition to the Computer display.
We'll detail some of those issues here in this article.
N6QW owned a small computer manufacturing business and was amazed at how much behind the scenes coordination took place when building a computer from parts and pieces. Video cards , while differing in capabilities , all used a standard interface. The same applies to motherboards, hard disk drives and on and on. There were some exceptions but for most situations any board, any card , any power supply was the rule. Thus was the basis of the terms “plug and play”.
Unfortunately such universal plug and play does not exist with the Arduino and the various available LCD’s, LCD interfaces and LCD Libraries. Thus t This short piece is an attempt to clarify what may be involved in implementing an LCD into an Arduino project.
The basic element needed for LCD implementation is to understand the three legs of the stool: 1) the hardware, 2) the software environment and 3) programming the software
The Hardware:
- There are many different kinds of LCDs, offering up different sizes and options. LCD selection offers many opportunities, to varying degrees, for displaying various data in small areas of the front panel. Common LCD types range from a 16 X 1 which means there are sixteen characters on a single line which of course i --which is somewhat s self- limiting . At the other end of the spectrum is the --to 20 X 4 , which means there are 20 characters per line with a total of four lines. In between are the 8X2 and the 12X2 displays. These are further subdivided into non-backlit and backlit devices. The non-backlit LCDs are marginal in that the screen can only be seen when the light hitting the front face is “just right” and certainly not good under low light conditions. With the backlit LCDs, there are optional background colors and as well as character colors. A blue background with white lettering , for example, sure looks cool. The green background with black lettering is a step up from a red background with black lettering , which can be fatiguing after long viewing periods! There of course is a price spread, with the 16X1 non-backlit (NBL) being less expensive as compared to than the 20X4 backlit (BL) units , which are the higher end devices. Typically the 16X1 NBL are less than $5 and the 20X4 BL ones are in the $15 range. Our personal bent is We prefer the 16X4 or 20X4 BL type, the reason being is that because it is better to have more than adequate display area versus having not enough. That said more lines you have, the more complex!
- Check which o n board controller in used in the LCD . There is however a magic decoder ring when evaluating what type of LCD to purchase and that is , which is the type of on board controller that is built into the LCD electronics. The LCD’s with the HD44780 controller are the most common and any other type may not work with the libraries that are available. Thus l Look carefully at what is the display controller before flashing the plastic! I n summary we view t The best option is either the 16X4 or the 20X4 Back Lit with the HD44780 controller chip. [There is another reason we are suggesting this type of LCD is that in the future a joint KK6FUT/N6QW SSB transceiver project will have an Arduino driven DDS and the 4 line display is required for that radio.] Units manufactured by Seiko, Samsung, Hitachi, Hantronix have the HD44780 controller and will work with the libraries.
- Parallel or Serial I2C connections? LCD interconnections to the Arduino are either of the Parallel type or the Serial I2C. Most of the inexpensive LCD’s, regardless if they are 16X1 or 20X4, out of the box, are the parallel interface type and that would which require s at least 6 of the Arduino digital pins to implement. This of course really gobbles up a substantial part of the digital I/O capability. Not to worry However, you don't have to worry, as many of the Arduinos, such as the UNO R3, have what is called an I2C Serial interface . that can be ported out The I2C interfaces uses of A analog p Pins A4 and A5 or as in the case of the (or, if you are using the Arduino Leonardo , are brought out as separate pins ). These two pins are Clock (SCL) and Data (SDA). A Using a separate small interface board generically called a “back pack” which is either is connected to the back of the LCD display or permanently soldered to the LCD , converts converting the two wire I2C Serial Data to the 6 pin Parallel Data needed to drive the display. Figure 1 shows one of the typical backpacks that enable the two wire interface (actually 4 wires if you also count the +5 VDC and GND.) Thus This preserves the precious digital pins on the Arduino are preserved for other uses. This seems like a no-brainer BUT for the fact that the backpacks are not all standard and require different I2C addresses and different libraries.
- I2C Library and Hardware Complexity. This being the case it undoubtedly Due to the different I2C addresses and libraries, it will require some experimentation to get your LCD to play. Remember not easy? Later in this piece in the article, we've provided a matrix , Figure 2, is provided to to help decode some of the I2C addresses and libraries . which are two the biggest players. Virtually most any parallel LCD (with the HD 44780) can be plugged into the back pack and will function, once the library and I2C address are resolved. Backpacks sold by Jameco, ADA Fruit, Marlin P. Jones, Sparkfun as well as many listed on the major auction sites will work FB. Caveat Emptor: Make sure they are + 5 Volts DC, have 16 pins for the LCD and 4 pins that connect to the Arduino, and that the I2C address is documented. N6QW purchased a bargain backpack on an auction site and the documentation stated any of eight I2C addresses would work. He had to test all eight before he found that the last one actually worked. Remember the not easy comment at the beginning! It's not as easy as one might think! Note so Some backpacks have programming solder pads where whatever is specified as the I2C address such as A0, A1 or A2 must have th ose at same corresponding pads solder bridged to work in the circuit. Definitely not plug and play!
The Software Environment:
- Libraries are not standard! Stating the exact library that will be used for the project is critical; but since there are many libraries, it will drive you nuts trying to figure which is which. In order for the display to work the hex include file in the library must be initially stated as: #include<LiquidCrystal.h> or #include<LiquidCrystal_I2C.h>. These are the two most common we have seen and used. Another statement needed for the Arduino to “wire in” the I2C and LCD is: In order to support the I2C interface, another library also needs to be included, using the #include <Wire.h> statement.
- Important: the libraries are hardware specific , and will conflict . These libraries Just a note these three library items must be downloaded from various manufacturers and loaded into your Arduino library directory. websites with Arduino Site yielding the Wire and LiquidCrystal.h libraries and LiquidCrystal_I2C.h library can be found at the Ada Fruit site. All three must be present in the Arduino library on your computer. Simply inserting these statements in the sketch will cause the compiling to fail. The library must be present on your computer for everything to work! Even more important, the libraries in many cases conflict -- you can only include one library for one particular piece of hardware at any one time, and may have to move the proper set of files into the Arduino library directory when needed.
- Check the I2C address. Designating the LCD I2C address in the setup and initiation is a critical step. Some backpacks only require that you provide the address which may range from 0x20 to 0x27 depending on who manufactured the backpack. Others may have an address such as A0, A1 or A2. You need to check which address your particular hardware is "hard coded" to accept. While other still at the same time you give When you set up the I2C address that , you must also specify the LCD type (character width and lines) where an entry might be (0x27, 16,4);. . For example, a A formal subsequent s Sketch statement to set up an LCD with an address of 0x27, with 16 characters wide display and four lines, might read like LiquidCrystal_I2C lcd(0x27,16,4);
Programming the Software
In order to display characters on the LCD, you need to write code to properly position the characters for display. To display "Hello World", we first need to write at position 0 on line 0. Some "tribal knowledge" from the software world: the first line or position is not 1, but is 0. So, for example, positioning at line 4 you would need to write to line 3, position 0. Understanding how data is actually displayed requires more than plug and play. It is not enough to simply connect an Arduino and hope that “Hello World” is displayed. Code has to be written that says start writing at position 0 on line 0. Yes the first line is line 0 and line four would be 3. The first character is printed at position 0 and the last at position 15.
To actually center the “Hello World” you must count the number of characters and spaces which would be 11 and then one has to add “filler” so that the wording is more or less centered. Translated that That means , in addition to the two words and a space , that leaves 5 spaces for filler which are blanks so we would be required to tell the computer to . This results in the command lcd.print(“ Hello World “); assuming the first position of the first line was designated as the starting point. Thus there are two blank spaces, the word Hello, a space, the word World and three blank spaces.
In the case where you might have a changing display with a fixed display like Code Speed = XX. The “Code Speed =” would be addressed in the set up and essentially always be done at power on and remain the same. By the way that would only leave four spaces to enter the actual code speed which means a blank, the XX and a blank. The XX part of the display would be constantly changing and thus the sketch must define what is fixed and where is that displayed as well as the location on the display of the variable that is changing.
- To
- Programming the Software
-
- Note we will provide specific code example that can be put into the software but first want to cover some basics of things that must be in place for the LCD to have allure, charm and magic. get the LCD software to work, you must have the following:
- At the initiation state the You must #include <LiquidCrystal_I2C.h> and the #include<Wire.h> at the beginning of the sketch.
- You need to indicate the I2C address and LCD type with the following code: The appropriate I2C address [LiquidCrystal_I2C lcd(0x27,16,2); ]
- In setup [lcd.init();] Start the lcd
- In setup [lcd.backlight();] Turn on the backlight
- In setup [lcd.setCursor(0,0);] Start at the 1 st Character 1 st Line
- In setup [lcd.print(" KK6FUT & N6QW ");]
- In setup [lcd.setCursor(1,0);] Start at the 1 st Character 2 nd Line
- In setup [lcd.print(“CODE SPEED = “);] This leaves 4 spaces
- In void [lcd.setCursor(1,12);] Places cursor for the value
- In void [lcd.print(val);] Prints the code speed in wpm
The LCD will now display, more or less centered, on the first line reads KK6FUT & N6QW and the second line reads CODE SPEED and the Value. You will have to experiment with the LCD, the backpack and the code – our experience has definitely shown that when you pick and choose “bargain” displays, boards and other hardware it is not a simple plug in.
Figure 2 (above).
Model |
|
Library |
Entries |
|
|
|
|
SainSmart 20X4 with integral backpack |
|
<LiquidCrystal_I2C.h> |
At instantiation: LiquidCrystal_I2C lcd(0x3F, 20, 4); |
|
|
|
In void setup: lcd.init(); |
|
|
|
|
Ada Fruit Back Pack |
|
<LiquidCrystal.h> |
At instantiation: LiquidCrystal lcd(0); |
|
|
|
In void setup; lcd.begin(16,4); |
|
|
|
|
Generic Back Pack |
|
<LiquidCrystal_I2C.h> |
At instantiation: LiquidCrystal_I2C lcd(0x27,16,4); or |
|
|
|
LiquidCrystal_I2C lcd(0x27,16,2); [two line versus 4 line] |
|
|
|
In void setup: lcd.init(); |
|
|
|
|
Notes: Notice the difference in the Libraries for these three examples and the I2C Address. The Ada Fruit uses lcd.begin(16,4); to designate the
type of display and the others lcd.init(); as the type is designated elsewhere. So depending on the model and make different entries are required. |