Documente Academic
Documente Profesional
Documente Cultură
Contents
Using the HD44780 with the Arduino
Hitachi HD44780 4 bit mode
Connections to the HD44780 in 4 bit mode
Photo of Arduino Connections
Software Library and versions
Arduino IDE Version
Liquid Crystal Library
Example 1 : 4bit parallel mode
Common LiquidCrystal Commands
Object Instantiation and function use
LiquidCrystal Commands
Example 2 : Time since last reset
Example 3 : Analogue Bar
The Hitachi HD44780 is an LCD driving chipset usually driving a 2 line by 16 character display. You can get
many different screen sizes e.g. 16x4, 20x4, 80x1. Regardless of that, the chipset, and hence the driving
software remains the same.
These type of displays are very low cost and can display any ASCII text that you want. In addition you can also
generate your own characters. Using these it is possible to create a simple bar graph to display a graphical
representation of voltage etc.
The most common type of HD44780 display is a 2 line, 16 character LCD display.
The 4 bit mode is more appropriate for microcontrollers since you only need about 6 pins. Inside the HD44780
you still have 8 bit operation so for 4 bit mode you do two writes to get that 8 bit quantity inside the chip.
RS - register select (Selects the data or instruction register inside the HD44780).
E - enable (This loads the data into the HD44780) - on the falling edge.
D4 - Part of upper nibble used in 4 bit mode.
D5 - Part of upper nibble used in 4 bit mode.
D6 - Part of upper nibble used in 4 bit mode.
D7 - Part of upper nibble used in 4 bit mode.
There is also a 10k pot across the supply and connected to Vo of the LCD.
The backlight led has a 470R resistor connected to 5V and to pin A of the LCD.
Pin K of the LCD is connected to GND.
Add a decoupling capacitor across Vcc and GND (not shown in photos).
Connections to the Arduino are:
Arduino Connections
LCD Name Arduno pin
RS 5
E 4
D4 3
D5 2
D6 1
D7 0
5V Arduino 5V
GND Arduino GND
Warning Some HD44780 Displays have the 16 connection pins on lower edge of the pcb - so you might get it
upside down - It is probably best if to test out the display on a solderless breadboard if unsure of the display
orientation.
Note: The chip shown on the left is not used (yet)- it is a 74HC595 ready for testing serial mode. In the next
page this device is used to reduce the number of pins from the Arduino.
If you do not see the library as an entry when you click the menus:
Sketch-->Include Library
Search for and install LiquidCrystal using the "Filter Your Search" form.
#include <LiquidCrystal.h>
void setup() {
lcd.begin(16, 2); // set up the LCD's columns and rows
lcd.print("How to Drive an");
lcd.setCursor(0, 1);
lcd.print("HD44780 16x2 LCD");
}
void loop() {
begin(16,2)
Tell the software what display you have - must be called before other commands.
setCursor(x,y)
This is an overloaded function that can print any of the three number types or a string. If you use a
number char,byte,int or long) you can also choose which base it is converted into using three letter
acronyms, BIN, DEC, OCT, or HEX.
One other function that is useful is the user generated character function:
An object is created using the main class constructor (in this case LiquidCrystal) as follows (here the object
created is labeled lcd):
LiquidCrystal lcd(LCD_RS,LCD_E,LCD_D4,LCD_D5,LCD_D6,LCD_D7);
Note: This is also used to initialise internal data structures with the pins in use.
Once created, you can access the class library functions with the instantiated object (lcd) followed by a period
and then the public class function: So, to print out some text for the lcd object (above)you would type:
lcd.print("My text");
lcd.print((char)35,BIN);
public:
LiquidCrystal(uint8_t rs, uint8_t enable,
uint8_t d0, uint8_t d1, uint8_t d2, uint8_t d3,
uint8_t d4, uint8_t d5, uint8_t d6, uint8_t d7);
LiquidCrystal(uint8_t rs, uint8_t rw, uint8_t enable,
uint8_t d0, uint8_t d1, uint8_t d2, uint8_t d3,
uint8_t d4, uint8_t d5, uint8_t d6, uint8_t d7);
LiquidCrystal(uint8_t rs, uint8_t rw, uint8_t enable,
uint8_t d0, uint8_t d1, uint8_t d2, uint8_t d3);
LiquidCrystal(uint8_t rs, uint8_t enable,
uint8_t d0, uint8_t d1, uint8_t d2, uint8_t d3);
The above object creators (constructor prototypes) differ only in the number of
parameters. For example the first and second differ only in that the 1st one does
not have the rw variable, and both operate the 8 bit interface. Then next two
again only differ in the rw variable and operate the 4 bit interface.
All these constructors are guided in code to call the "init" function below (look
for a magic number in the library source code that indicates when rw is not to
be used (it is 255)).
The following function allows the underlying functions to know how big your
display is and whether a large font is in use.
void clear();
void home();
void noDisplay();
void display();
void noBlink();
void blink();
void noCursor();
void cursor();
void scrollDisplayLeft();
void scrollDisplayRight();
void leftToRight();
void rightToLeft();
void autoscroll();
void noAutoscroll();
The y position of the display is often strange for larger displays as two
HD44780's are used so the start address for each row needs to be set (in some
cases).
This one is a little different as it uses the print class. That is one good thing
about OOP. In this case the serial print class allows you to re-write the "write"
function that actually accesses the hardware. So instead of directing the serial
data to the serial port you can re-direct the data to the LCD but retain all the
number formatting code!
using Print::write;
There's nothing wrong with the code but it has to do a lot of manipulation to make the operation generic. It
shows how that to make code generalised and easy to use there is a sacrifice in performance. There are two
interesting parts to this operation
First of all the pin mode is set every time that a write is made to the LCD. This would ensure that if other code
accidentally set the pin direction wrongly then this would override it. Usually a port is dedicated to one
operation so pin modes should be set in the "setup" routine. The way it is done here is "safe" but gives a big
performance hit at each lcd write operation..
Secondly to manipulate each data bit to direct it to the output takes a few operations involving selecting the pin
and then shifting the value right. It's clever and works in all cases but again there is a performance hit. By using
the hardware in a straight forward way then you can avoid this coding i.e. use the lower 4 bits of an output port
and and you only need a few bit manipulation operations: a lower four bit and mask:
For arduino operation, performance is not as important as speed and ease of coding and it allows users to mix
and match code to get it working but you should be aware that underneath all the magic there can be a lot going
on and you could re-write it (or re-wire the hardware) for better performance.
Click in the code (for the Hitach HD44780 ) to copy it to the clipboard.
#include <LiquidCrystal.h>
void setup() {
long countTime = 0;
long oldTime = 0;
void loop() {
delay(1);
countTime += 1;
Each character is 5 pixels wide and there are 16 characters to a row so there are a total of 16x5 = 80 pixels
across the display. You can use this information to display a horizontal bar graph.
Note: You can use as many pixels as you want as the bar drawing routine uses x,y (LCD coordinates) to start
from, and then just a number representing the number of pixels to draw to the right.
Click in the code (for the Hitach HD44780 ) to copy it to the clipboard.
#include <LiquidCrystal.h>
void setup() {
createBarChars();
}
long countTime = 0;
long oldTime = 0;
void loop() {
static int idxcg = 0;
delay(1);
countTime += 1;
>>>>>>>>>>>>>>