lcd display with buttons free sample
The processors that power the Arduino development boards aren"t your granddad"s microcontrollers - they"ve got serious processing power and can be used to monitor and control many types of physical hardware and sensors simultaneously. The XOD graphical programming IDE for Arduino can simplify the task of rapid-prototyping hardware designs, but as a system grows in complexity there"s the issue of user control and information management - how to arrange information about the process being controlled for display and let the user control it in a logical manner. Dedicated buttons and switches work for simple projects but one soon runs out logical ways to arrange them (or places to put them on an enclosure.) Many designs use a display of some type to give this kind of feedback, even a microwave oven usually has a small screen that allows editing settings and entering cook times, and while too much "menu diving" to access obscure settings can compromise user experience, menu-driven interfaces are a fact of life for projects of all kinds.
Software frameworks for developing menu-based interfaces in C or C++ for microcontrollers often have a steep learning curve and can be difficult to make rapid design changes in, as often everything interacts with everything else. The goal of this project was to use the XOD graphical programming environment to provide the ability to rapidly prototype menu-driven interfaces for Arduino-compatible microcontroller projects using a drag-and-drop/WYSIWYG style of interface. The output and input parameters of the generated menu structure are modular and generic and should be able to be used with a wide variety of input sources (switches, buttons, encoders) and produces a sequence of plain text outputs which can be fed to a wide variety of XOD-supported display types, including multi-line text LCD modules as used in this example.
At the right of the patch editing screen in XOD are four nodes connected up in a descending fashion. From top to bottom there"s first an analog input-type node, which is selected to be connected to one the Arduino"s analog input ports. In my tests I"ve been using an Arduino Uno with an ATMega328 8 bit processor, with a 16x2 LCD/keypad shield connected on top of it. The keypad on the shield is connected via the shield pins to the Arduino"s "A0" analog input, and the hardware generates voltages of differing levels to signal to the Arduino which buttons on the pad are depressed.
Other than the "reset" button on the keypad which doesn"t interface to the Arduino sketch directly, this type of display shield provides four directional buttons - up, down, left, and right, a "select" button. The second node down fed by the analog input node contains code which reads the differing voltage levels and outputs pulse-type triggers depending on which button is pressed. A "timeout" input is provided so an XOD developer can adjust the debounce timeout of the LCD shield keypad to avoid false triggering, adjusted to a particular application"s button or switch type.
As currently implemented it accepts a single Number-type input which can be any parameter the user can change from an external control, say a potentiometer or dial on a control panel which represents some parameter that can be changed. When a given leaf-type menu is selected by the menu-controller receiving a pulse to its "Invoke" input, over in the menu tree to the left the node of the screen the user is currently looking at will output a pulse on its own output, and also send out a parameter change. There are also two String inputs which can be used to generate a splash screen on the display when the Arduino powers up.
Following that node is a stock 16x2 LCD controller module from the XOD environment standard library, but any type of display that a module is available for can be used to display the output text here.
At the top of the sketch screenshot is a tree-like structure which, when compiled and the final output "root" of the tree is routed to the menu-controller input that accepts it, will automatically generate a navigable menu just as pictured in the graphical designer. Currently implemented are three types of menu tree nodes, a "leaf"-type menu - a final sub menu, with no orange-colored input ports - this represents some action or parameter the user can control, a "branch"-type menu with both an input and output, where the user can select among several child sub-menus, and a "concat"-type menu where sub-menus are grouped together and fed into the input of a branch-type menu, to make a group of options. It should hopefully be somewhat self-explanatory from the diagram how to wire up this set of nodes.
Selecting "invoke" when a "branch"-type menu is displayed descends into its associated sub menu group, rather than generating an output as a leaf-type menu does. Sub-sub menus, sub-sub-sub menus, etc. are possible! Complex structures can be implemented, limited primarily by the available RAM and Flash memory resources of a particular Arduino model"s processor.
This set of nodes has been tested and should work OK with the Arduino Uno as-is, but a few issues remain that weren"t resolved by this project"s deadline. Currently there must be a branch-type menu in the tree somewhere for a sketch to compile, though most projects would probably want to have at least one. The "top" menu input to the menu-controller, intended to return all the way back to the title screen of the interface, isn"t currently implemented but should be an easy feature for the next revision.
Four-line displays are supported by the menu controller node but the leaf-type menu interface with four lines of text input hasn"t been written, yet. A good amount of effort has been put into reducing the memory overhead of this utility but the way the XOD transpiler currently stores constant strings isn"t optimal for very low RAM overhead, and menu-based interfaces tend to have a lot of text. For this project a work-around was developed and a set of flash-string type nodes added in the patch to ensure longer strings did not consume precious program RAM.
Using the flash-string type nodes isn"t too painful but does require duplicating the patch and code for each new string stored in program memory, and clicking into the C++ code contained within the node itself to edit the output string:
The "ID" input of leaf and branch nodes doesn"t have a function, yet. The thought is it would be good for each set of sub-menus to have associated ID numbers arranged in order so the user can keep track of their position in a set of displays but it will require some more thought on how to code this in C++ to happen automatically.
You may have used an electronic device with a small Liquid Crystal Display (LCD) which has a textual hierarchical menu system for setting device configuration parameters. If you have tried writing menu code for your Arduino projects, you will recognise the challenge in developing a generic menu system for an open prototyping platform. This is because there are many input and display devices available, and a generic menu system must be independent of whichever input and display devices you wish to use. With our Arduino menu library, this independence is achieved by having the menu manager code use callback methods for handling user input and rendering the menu display.
To keep things simple, all coding examples have been targeted to work with an R3 Arduino Uno/Leonardo/Mega2560, and an LCD keypad shield similar to one illustrated above. There are numerous manufacturers of LCD keypad shields that have the same or similar pin connections, and you must ensure that the sample menu code uses the pin connections that are right for your shield. If the keypad buttons of your shield give different analog readings, you’ll need to make changes to file LcdKeypad.h. Bear in mind that the analog readings are not always consistent, which can lead to the occasional misreporting of a button press. Once you become familiar with the menu library, adapting it for use with other input and display devices should be straight-forward.
With numerous menu libraries readily available, why use this Arduino menu library? We think it is easier to use thanks to our online code generator, and has better memory efficiency with its use of PROGMEM. Watch the short video clip below and see for yourself.
You can use the downloaded sample Arduino project as a starting point for your own coding requirements. You will need to write your own code in the body of method processMenuCommand(byte cmdId) to determine what must be done when a menu item is selected. The cmdId parameter is the Id you associate with a menu item in your menu Xml file. Callback method getNavAction() handles user input, and callback method refreshMenuDisplay(byte refreshMode) renders the menu. To work with other input and display devices you’ll need to re-write the code in these methods. Some LCD keypad shields are not suited for hardware PWM backlight control, and as such the coding example uses a soft PWM alternative.
The Select button on the LCD shield starts/stops a timer, with a long press resetting the timer. A long press of Up enters the menu. Up/Down/Right buttons are for navigating the menu, and Select for choosing a menu item. When an item is selected, Up/Down are used for changing values. When the Reset menu item is displayed, a long press of Select loads default configuration values. Digital pin 2 is used for activating a beeper for the alarm. Examining the source should give you good insight for using the menu system in your own projects. If you find this Arduino menu library guide useful, please share it.
All our hackatronics projects are free for personal use, and there are many more in the pipeline. If you find our projects helpful or useful, please consider making a small donation to our hackatronics fund using the donate buttons on our web pages. Thank you.
The 16x2 LCD And Keypad Shield is very simple to use because it"s fully compatible with the Arduino "LiquidCrystal" library. You can initialise the LCD and display messages on it with just a few lines of code, but it also gives you the flexibility to do more advanced projects such as display menu items and select them using the buttons.
The LCD & Keypad Shield requires a good 5V power supply to ensure the backlight fully illuminates and the display contrast is high, and if you power your Arduino from USB with the LCD Shield attached you may experience a voltage drop over the USB cable. If you have trouble with display contrast or backlight brightness, try attaching a power supply of around 7 to 9Vdc to the 2.1mm DC jack on the Arduino. A typical symptom in an undervoltage situation is that one line of the LCD will show pale rectangles in place of the characters, and the other line will show nothing at all. The Arduino may even continue running normally because it"s quite happy at just 4V or so, but the LCD & Keypad Shield won"t function.
All the hard work of interfacing with the LCD Shield is handled by the LiquidCrystal library, which is included as part of the official Arduino distribution. You can check whether you have it installed by starting up the IDE and looking under Files -> Examples -> LiquidCrystal. If it exists, you"re good to go.
The LCD Shield includes 5 buttons designed for use as navigational or control input. The buttons are arranged in a handy pattern and referred to as UP, DOWN, LEFT, RIGHT, and SELECT, but of course it"s totally up to your sketch to decide what to do when any particular button is pressed.
All the buttons are connected to a single analog input, A0, using a chain of resistors that causes a different reference voltage to be applied to A0 depending on which button is pressed. This section of the shield schematic shows the input buttons and associated resistors:
As you can see, if no button is being pressed the voltage on A0 will be pulled all the way up to 5V by the 2K resistor called R6. In that situation none of the other resistors have any effect at all, and the analog reading on A0 will be hard on the upper limit of 1023. Therefore if you perform an analogRead() call on A0 and it returns 1023 (or any value above about 1000) you know that no buttons are being pressed.
Now consider what happens if the "DOWN" button is pressed. Now A0 is being presented with a voltage that is divided between the 2K resistor that is trying to pull it up to 5V, and the 330R and 620R resistors in series (totaling 950R) that are trying to pull it down to 0V. The voltage presented to A0 in that case is about 1.61V, which means if you perform an analogRead() on A0 it will return a value of about 329. So if you read a value of about 329 from A0 you know the "DOWN" button is being pressed.
This is a neat way to provide a whole set of input buttons while only using up one of the I/O pins on your Arduino, leaving more pins free for use in your project.
The extensive example below combines a number of techniques to demonstrate how to show messages on the LCD, read from the buttons, and change the display message depending on which buttons are pressed.
In this tutorial, I’ll explain how to set up an LCD on an Arduino and show you all the different ways you can program it. I’ll show you how to print text, scroll text, make custom characters, blink text, and position text. They’re great for any project that outputs data, and they can make your project a lot more interesting and interactive.
The display I’m using is a 16×2 LCD display that I bought for about $5. You may be wondering why it’s called a 16×2 LCD. The part 16×2 means that the LCD has 2 lines, and can display 16 characters per line. Therefore, a 16×2 LCD screen can display up to 32 characters at once. It is possible to display more than 32 characters with scrolling though.
The code in this article is written for LCD’s that use the standard Hitachi HD44780 driver. If your LCD has 16 pins, then it probably has the Hitachi HD44780 driver. These displays can be wired in either 4 bit mode or 8 bit mode. Wiring the LCD in 4 bit mode is usually preferred since it uses four less wires than 8 bit mode. In practice, there isn’t a noticeable difference in performance between the two modes. In this tutorial, I’ll connect the LCD in 4 bit mode.
Here’s a diagram of the pins on the LCD I’m using. The connections from each pin to the Arduino will be the same, but your pins might be arranged differently on the LCD. Be sure to check the datasheet or look for labels on your particular LCD:
Also, you might need to solder a 16 pin header to your LCD before connecting it to a breadboard. Follow the diagram below to wire the LCD to your Arduino:
All of the code below uses the LiquidCrystal library that comes pre-installed with the Arduino IDE. A library is a set of functions that can be easily added to a program in an abbreviated format.
In order to use a library, it needs be included in the program. Line 1 in the code below does this with the command #include
There are 19 different functions in the LiquidCrystal library available for us to use. These functions do things like change the position of the text, move text across the screen, or make the display turn on or off. What follows is a short description of each function, and how to use it in a program.
TheLiquidCrystal() function sets the pins the Arduino uses to connect to the LCD. You can use any of the Arduino’s digital pins to control the LCD. Just put the Arduino pin numbers inside the parentheses in this order:
This function sets the dimensions of the LCD. It needs to be placed before any other LiquidCrystal function in the void setup() section of the program. The number of rows and columns are specified as lcd.begin(columns, rows). For a 16×2 LCD, you would use lcd.begin(16, 2), and for a 20×4 LCD you would use lcd.begin(20, 4).
This function clears any text or data already displayed on the LCD. If you use lcd.clear() with lcd.print() and the delay() function in the void loop() section, you can make a simple blinking text program:
This function places the cursor in the upper left hand corner of the screen, and prints any subsequent text from that position. For example, this code replaces the first three letters of “hello world!” with X’s:
Similar, but more useful than lcd.home() is lcd.setCursor(). This function places the cursor (and any printed text) at any position on the screen. It can be used in the void setup() or void loop() section of your program.
The cursor position is defined with lcd.setCursor(column, row). The column and row coordinates start from zero (0-15 and 0-1 respectively). For example, using lcd.setCursor(2, 1) in the void setup() section of the “hello, world!” program above prints “hello, world!” to the lower line and shifts it to the right two spaces:
You can use this function to write different types of data to the LCD, for example the reading from a temperature sensor, or the coordinates from a GPS module. You can also use it to print custom characters that you create yourself (more on this below). Use lcd.write() in the void setup() or void loop() section of your program.
The function lcd.noCursor() turns the cursor off. lcd.cursor() and lcd.noCursor() can be used together in the void loop() section to make a blinking cursor similar to what you see in many text input fields:
Cursors can be placed anywhere on the screen with the lcd.setCursor() function. This code places a blinking cursor directly below the exclamation point in “hello, world!”:
This function creates a block style cursor that blinks on and off at approximately 500 milliseconds per cycle. Use it in the void loop() section. The function lcd.noBlink() disables the blinking block cursor.
This function turns on any text or cursors that have been printed to the LCD screen. The function lcd.noDisplay() turns off any text or cursors printed to the LCD, without clearing it from the LCD’s memory.
This function takes anything printed to the LCD and moves it to the left. It should be used in the void loop() section with a delay command following it. The function will move the text 40 spaces to the left before it loops back to the first character. This code moves the “hello, world!” text to the left, at a rate of one second per character:
This function takes a string of text and scrolls it from right to left in increments of the character count of the string. For example, if you have a string of text that is 3 characters long, it will shift the text 3 spaces to the left with each step:
Like the lcd.scrollDisplay() functions, the text can be up to 40 characters in length before repeating. At first glance, this function seems less useful than the lcd.scrollDisplay() functions, but it can be very useful for creating animations with custom characters.
lcd.noAutoscroll() turns the lcd.autoscroll() function off. Use this function before or after lcd.autoscroll() in the void loop() section to create sequences of scrolling text or animations.
This function sets the direction that text is printed to the screen. The default mode is from left to right using the command lcd.leftToRight(), but you may find some cases where it’s useful to output text in the reverse direction:
This code prints the “hello, world!” text as “!dlrow ,olleh”. Unless you specify the placement of the cursor with lcd.setCursor(), the text will print from the (0, 1) position and only the first character of the string will be visible.
This command allows you to create your own custom characters. Each character of a 16×2 LCD has a 5 pixel width and an 8 pixel height. Up to 8 different custom characters can be defined in a single program. To design your own characters, you’ll need to make a binary matrix of your custom character from an LCD character generator or map it yourself. This code creates a degree symbol (°):
If you found this article useful, subscribe via email to get notified when we publish of new posts! And as always, if you are having trouble with anything, just leave a comment and I’ll try to help you out.
This article gives you a step-by-step guide to becoming a pro in using Liquid Crystal Display. We will use a free Arduino Simulator to try all the examples without leaving your PC. No hardware is needed.
There are two versions of the chip"s ROM with two different fonts: HD44780UA00, Japanese katakana characters, and HD44780UA02, which includes Western European characters.
You can see that the first eight characters are user-defined. It allows you to create custom shapes and store them. You will see how to create custom characters and load them in your following Arduino projects. Let us start with a basic example.
We will print a simple text on the LCD using Arduino UNO in this example. In this case, you control what is displayed on the Arduino readily. You only need four cables. Power, Ground, I2C data, and I2C clock.
Use the link above to run the code. You can tinker with the code to change the text displayed or the position. The best thing about the link is that it will save the project as your version. It will be automatically saved under my projects tab on the wokwi site if you are logged in.
The below line code adds the LCD library to your project. This consists of all the LCD-related functions. Since we are using the I2C version, we have included the standard LCD library made for the I2C version.#include
The following line of the code resets and initializes all the LCD registers and prepares them for project usage. This function will be called only once in thesetup()function.lcd.init();
To turn on the backlight, you can use the below code. You will be able to see the contents of the display without a backlight, too, if it is a green LCD. Backlight, nevertheless, makes the project more beautiful and reading crisper.lcd.backlight();
You can mention where the characters should be displayed. You can always use the below function to set/reset the cursor position. This function will be beneficial when you have to display time or a counter that demands the cursor to always be in the same position.
The first parameter tells the position column-wise (0indicated first place,1indicates the second place, and so on). The second parameter tells the row number. We have only two rows (0and1).lcd.setCursor(1, 0);
This completes a basic introduction to the LCD as well as an example project to start the LCD exploration. In the coming sections, we will see different projects as soon as possible