arduino counter with lcd display manufacturer
ArduinoGetStarted.com is a participant in the Amazon Services LLC Associates Program, an affiliate advertising program designed to provide a means for sites to earn advertising fees by advertising and linking to Amazon.com, Amazon.it, Amazon.fr, Amazon.co.uk, Amazon.ca, Amazon.de, Amazon.es and Amazon.co.jp
Liquid Crystal displays or LCDs have been used in electronics equipment since the late 1970s. LCD displays have the advantage of consuming very little current And they are ideal for your Arduino projects.
In this article and in the accompanying video I’ll show you how easy it is to add an LCD display to your next Arduino design. I’ll also show you a very popular Arduino Shield that has a keypad which you can use in your projects as well.
Today LCD displays are used in a variety of items from test equipment to televisions. They’re inexpensive and versatile, this makes them ideal for all sorts of designs.
LCD displays do not emit light. Instead they block the passage of light, like little windows which open and shut the let light through. The liquid crystals used inside LCD displays are sandwiched between two layers of polarized material. By changing the orientation of the liquid crystals they allow light to pass or they block the light entirely.
Because transmissive LCD displays (the type we will be using) work by blocking light they require a backlight. Several methods have been used to create back lights including electroluminescent panels and fluorescent tubes. these days the most common form of backlight is an LED, in fact so-called LED televisions are usually just LCD screens with an LED backlight system.
Another type of LCD display, the passive-matrix display, does not require a backlight, it works using reflected light. This type of display is often found in digital watches.
The principles of liquid crystals were discovered in the late 1880s but work on Modern LCD displays did not begin until the mid-1960s. a number of patents were filed in the early 1970s and in 1973 the Sharp Corporation introduced LCD displays for calculators.
The first color LCD displays were developed in the early 1980s but production units were not commonly available until the mid-1990s. By the late 1990s LCD displays were quite common.
A number of LCD displays are available for experimenters. These low-cost monochrome displays are ideal for use with microcontrollers like the Arduino and micro computers like the Raspberry Pi.
These displays are available in a number of different configurations. The part number for the display generally relates to the number of rows and columns in the display.
Common display configurations include 16 x 2, 16 x 4 and 20 x 4. All of these displays are used in a virtually identical fashion the only difference being the number of columns and rows they have.
The LCD1602 display module is a very popular and inexpensive LCD display. It is available in a number of different colors such as blue yellow and green and can easily be connected to an Arduino or Raspberry Pi.
In operation data is sent down the parallel data lines for the display. There are two types of data that can be sent to the display. The first type of data are the ASCII characters which are to be displayed on the display. The other type of data are the control characters that are used to activate the various display functions.
Brightness– This is the input for the brightness control voltage, which varies between 0 and 5 volts to control the display brightness. On some modules this pin is labeled V0.
Because the LCD module uses a parallel data input it requires 8 connections to the host microcontroller for the data alone. Add that to the other control pins and it consumes a lot of connections. On an Arduino Uno half of the I/O pins would be taken up by the display, which can be problematic if you want to use the I/O pins for other input or output devices.
We will begin our experiments by hooking up the LCD1602 to an Arduino Uno and running a few of the example sketches included with the Arduino IDE. This will allow you to get familiar with the display without needing to write any code.
We need to hookup our LCD display to our Arduino. The display can use any of the Arduino digital I/O pins as it has no special requirements, but if you hook it up as I’ve illustrated here you can run the example sketches without needing to make any modifications.
In addition to the LCD1602 display ands the Arduino Uno you will need a 10K trimpot ot potentiometer, this is used a s a brightness control for the display. You’ll also need a 220 ohm resistor to drop the voltage for the displays LED backlight.
The Arduino IDE includestheLiquidCrystallibraryand this library has a number of example sketches. I’ll go over three of them here but you can also try the other ones.
The sketch starts with a number of credits and a description of the required hardware hookup. You’ll note that this is the same hookup you just performed on your Arduino and LCD module.
We then initialize an object that we call “lcd” using the pinouts of the LCD display. If you decide to hook up your display to different pins then you’ll need to modify this section.
In the beginning of the loop we set our cursor to the first position in the second row. Note that the row numbers start with zero so the second row is row 1.
That ends the loop, so we start back at the top of the loop and repeat. The result will be a counter on the second line that counts seconds from the htime the Arduino was last reset.
Load the sketch up to your Arduino and observe your display. If you don’t see anything try adjusting the brightness control that you wired to the display.
The second example we will try isthe Scroll sketch. Scrolling is a useful technique when you can’t get your text to fit on one line of the LCD display.
In the loop the code demonstrates the use of thescrollDisplayLeftandscrollDisplayRightfunctions. As their names imply they move the text in a left or right direction.
Finally the last counter moves the text 16 positions to the left again, which will restore it back to the center of the display. The loop then repeats itself.
Custom characters are useful when you want to display a character that is not part of the standard 127-character ASCII character set. Thi scan be useful for creating custom displays for your project.
A character on the display is formed in a 5 x 8 matrix of blocks so you need to define your custom character within that matrix. To define the character you’ll use thecreateCharfunctionof the LiquidCrystal library. You are limited to defining a maximum of eight characters.
To usecreateCharyou first set up an array of bytes with 8 elements. Each element in the array defines one row of the character in the 5 x 8 matrix. You then use createCharto assign a number from 0 to 7 to that array.
The Custom Character demonstration requires one additional component to be wired to the Arduino, a potentiometer (10K or greater) wired up to deliver a variable voltage to analog input pin A0.
As with the previous sketches we examined this one starts by loading theLiquidCrystallibrary and defining an object calledlcdwith the connection information for the display. It then moves on to define the custom characters.
Each character is defined as an array with 8 elements, the zeros and ones in the array indicate which elements in the character should be on and which ones should be off. Five arrays are defined, although the sketch actually only used four of them.
The last two arrays,amsUpandarmsDowndefine the shape of a little “stickman”, or “stickperson” if you want to be politically correct! This is done to show how we can animate a character on the display.
Finally the setup routine ends by printing a line to the first row of the LCD display. The line makes use of two of the custom characters, the “heart” and the “smiley”.
We begin by reading the value of the voltage on pin A0 using the ArduinoanalogReadfunction. As the Arduino has a 10-bit analog to digital converter this will result in a reading ranging from 0 to 1023.
We then use an Arduinomapfunction to convert this reading into a range from 200 to 1000. This value is then assigned to an integer calleddelayTime, which as its name implies represents a time delay period.
One thing you may have noticed about using the LCD display module with the Arduino is that it consumes a lot of connections. Even in 4-wire mode there are still a total of seven connections made to the Arduino digital I/O pins. As an Arduino Uno has only 14 digital I/O pins that’s half of them used up for the display.
In other cases you would need to resort to using some of the analog pins as digital pins or even moving up to an Arduino Mega which has many more I/O pins.
But there is another solution. Use the I2C bus adapter for the LCD display and connect using I2C. This only consumes two I/O pins and they aren’t even part of the set of digital I/O pins.
The bus has evolved to be used as an ideal method of communicating between microcontrollers, integrated circuits, sensors and micro computers. You can use it to allow multiple Arduinos to talk to each other, to interface numerous sensors and output devices or to facilitate communications between a Raspberry Pi and one or more Arduinos.
In I2C communications there is the concept of Master and Slave devices. There can be multiples of each but there can only be one Master at any given moment. In most Arduino applications one Arduino is designated Master permanently while the other Arduinos and peripherals are the Slaves.
The Master transmits the clock signal which determines how fast the data on the bus is transferred. There are several clock speeds used with the I2C bus. The original design used 100 KHz and 400 KHz clocks. Faster rates of 3.4 MHz and higher are available on some I2C configurations.
Every device on the I2C bus has a unique address. When the Master wants to communicate with a Slave device it calls the Slaves address to initiate communications.
The I2C Adapter for the LCD display is a tiny circuit board with 16 male header pins soldered to it. These pins are meant to be connected directly to the 16-pin connection on the LCD1602 display (or onto other displays that use the same connection scheme).
The device also has a 4-pin connector for connection to the I2C bus. In addition there is a small trimpot on the board, this is the LCD display brightness control.
Most of these devices have three jumpers or solder pads to set the I2C address. This may need to be changed if you are using multiple devices on the same I2C bus or if the device conflicts with another I2C device.
Most Arduino Unos also have some dedicated pins for I2C, these are internally connected to A4 and A5 and are usually located above the 14 digital I/O pins. Some models of the Uno have additional I2C connectors as well.
Note how much easier it is to use the I2C connection, which does not consume any of the Arduino Unos 14 digital I/O pins. Since A4 and A5 are being used for the I2C bus they can’t be used as analog inputs in this configuration.
Nick has written a simple I2C scanner sketch that he’s put into the public domain. It scans your I2C bus and gives you back the address of every I2C device it finds. I’ve repeated Nick’s sketch here, it’s also in the ZIP file that you can download with all of the code for this article.
Load this sketch into your Arduino then open your serial monitor. You’ll see the I2C address of your I2C LCD display adapter. You can then make note of this address and use it in the sketches we’ll be looking at now.
In order to run the subsequent sketches you’ll need to install another library. This is theNewLiquidCrystallibrarywhich, as its name implies, is an improved version of the LiquidCrystal library packaged with your Arduino IDE.
The sketch starts by loading the ArduinoWirelibrary. This is the Arduino library that facilitates communications over I2C and it’s part of your Arduino IDE installation.
On the next line we define the connections to the LCD display module from the I2C Adapter,. Note that these are NOT the connections from the Arduino, they are the connections used by the chip on the adapter itself.
In setup we set the size of the display and then print “Hello world!” on the first line in the first position. After a short delay we print “How are you?” on the second line.
The next demo uses theautoscrollfunction to scroll some text. We first print the text “Scroll demo – “ and then implement a counter to count from 0 to 9 while scrolling the text.
Load the sketch and run it on your Arduino. If you can’t get it to work check out the address and connection information to be sure you have it right.
We need to make a minor wiring adjustment to the hookup with our I2C adapter, specifically we will need to add a DHT22 temperature and humidity sensor into the circuit. The wiring is shown here:
As you can see the DHT22 is connected with its output tied to pin 7 of the Arduino. The other two connections are 5 volts and ground. Note that pin 3 of the DHT22 is not used.
This sketch also makes use of theDHTlibrary from Adafruit. We used this library in a previous article, “Using the HC-SR04 Ultrasonic Distance Sensor with Arduino” so you may want to take a look at that one in order to get it installed.
The key thing to note is that this library is dependant upon another Adafruit library, theirUnified Sensorlibrary. Both can be installed using the Library Manager in your Arduino IDE.
The sketch is similar to our demo sketch in that it creates an “lcd” object with the I2C and display connection information. It also defines a couple of parameters for the DHT22 sensor, as well as some floating variables to hold the temperature and humidity values.
Note that this displays the temperature in Celsius. If you want to change this to Fahrenheit its a simple matter of using some math. The formula( temp * 1.8 ) + 32will convert the results to Fahrenheit.
So far we have used the LCD1602 display module for all of our experiments. For our final demonstration we’ll switch to a popular Arduino shield that contains a LCD1602 along with some push buttons.
The LCD Keypad Shield is available from several different manufacturers. The device fits onto an Arduino Uno or an Arduino Mega and simplifies adding an LCD display to your project.
The Reset button is simply connected to the Arduino Reset pin and works just like the Reset button on the Arduino itself. This is common on many shields as the shields physically cover the Reset button.
Instead the buttons are connected to a resistor array that acts as a voltage divider. The entire array is connected to the Arduino’s analog A0 pin. One pin for five push buttons.
Note that the LCD is being used in 4-wire mode. The LCD itself is the same one used on the LCD1602 module, so all of the code for that module will work with the LCD Keypad Shield as well.
Now that you know how the LCD Keypad module works and which Arduino pins it uses all that remains is to install it onto your Arduino and load the demo sketch.
One thing – once the shield is installed on the Arduino you won’t have easy access to the unused I/O pins to connect any sensors or output devices you may want to use (although the demo sketch doesn’t need anything else connected). There are a couple of ways to get around this:
Use a shield that exposes the pins for prototyping before you install the LCD Keypad shield. In the video associated with this article I use a “Screw Shield” that brings all of the Arduino I/O pins out to a series of screw connectors. There are other similar shields. Using one of these shields is the easiest way to work with the LCD Keypad shield, as well as other Arduino shields.
The sketch begins by including theLiquidCrystallibrary. You can use the original one or the one includes with theNewLiquidCrystallibrary. We then set up an object with the LCD connections, note that these are just hard-coded as they won’t change.
Next we define a number of constants, one for each of the push buttons. Note that nothing is defined for the Reset button as it simply mimics the Arduino Reset button, however a constant is defined for the “none” condition.
After that we define a function calledread_LCD_buttons(). This function reads the value on analog port A0 and returns an integer corresponding to the button integers we defined earlier. Note that the function adds approximately 50 to each of the manufacturers specified values to account for intolerances in the resistors in the voltage divider.
We start the loop by placing the cursor 9 spaces over on the second line. We then use themillisfunction to display a counter that counts the time since the Arduino was reset. This is to test the Reset button.
We then call ourread_LCD_buttons()function and use it to display the value of the push button, right before the counter. Then we end the loop and do it again.
Load the code onto the Arduino and run it. You should see the value of each button as you press it, along with a counter that increments each second. If you press Reset the counter should reset itself back to zero.
As you can see LCD displays are pretty simple to use thanks to the availability of some excellent libraries for the Arduino. As these displays are also very inexpensive they will make an ideal addition to many of your Arduino projects.
And finally the LCD Keypad Shield is a convenient method of adding both a display and a simple keypad to your project, no wiring or soldering required.
In electronics world today, Arduino is an open-source hardware and software company, project and user community that designs and manufactures single-board microcontrollers and microcontroller kits for building digital devices. Arduino board designs use a variety of microprocessors and controllers. The boards are equipped with sets of digital and analog input/output (I/O) pins that may be interfaced to various expansion boards (‘shields’) or breadboards (for prototyping) and other circuits.
The boards feature serial communications interfaces, including Universal Serial Bus (USB) on some models, which are also used for loading programs. The microcontrollers can be programmed using the C and C++ programming languages, using a standard API which is also known as the “Arduino language”. In addition to using traditional compiler toolchains, the Arduino project provides an integrated development environment (IDE) and a command line tool developed in Go. It aims to provide a low-cost and easy way for hobbyist and professionals to create devices that interact with their environment using sensors and actuators. Common examples of such devices intended for beginner hobbyists include simple robots, thermostats and motion detectors.
In order to follow the market tread, Orient Display engineers have developed several Arduino TFT LCD displays and Arduino OLED displays which are favored by hobbyists and professionals.
Although Orient Display provides many standard small size OLED, TN and IPS Arduino TFT displays, custom made solutions are provided with larger size displays or even with capacitive touch panel.
An LCD (Liquid Crystal Display) is a great way to display information in our Arduino Uno controller. We will be wiring and programming an alphanumeric, two rows with 16 characters on each row. The display has an LED (Light Emitting Diode) backlight with adjustable contrast.
This white and blue LCD will display “Hello World!” on the top line and temperature on the bottom line. The thermistor temperature circuit created last time will be displayed in both Celsius and Fahrenheit degrees. Let’s get started.
When you look at an LCD display, it is made up of a series of dots or pixels. Each of these pixels is a liquid crystal. If electricity flows through the liquid crystal it will change its structure and be more rigid. This rigidity will look darker than if no electricity is applied. If we use a light behind this LCD then the backlight will make the pixels more pronounced. So electricity on the pixel will block the light and no electricity will allow the light through. This contrast is what we see using an LCD display.
The LiquidCrystal.zip file came on the disk with the Arduino UNO R3 super starter kit. It can also be downloaded from the link below with the program. Select this library and then select open. This will add the library to the Arduino IDE (Integrated Development Environment).
This first part will set up the library and declare the variables for the LCD display unit. Using the Steinhart-Hart Equation we declare our variables and set the coefficients for the equation.
The LCD is set up with 16 characters and 2 lines. The cursor for the LCD display is set for the first character on the first line by default. We then print the message “ Hello, World!”.
The program will calculate the temperature in Celsius (T) and in Fahrenheit (TF). The LCD cursor is then set to the second row and column 0. We can then print our temperatures and units of measure.
You will see the ‘Hello World!’ and the current temperature in two units of measure displayed on the LCD. Hold the thermistor between your fingers to see how rapidly the temperature can be read.
Hello, I am having a problem programming a counter that can be reset to 0 to be displayed on my LCD. The counter works fine when it is still in its one"s digit, but once it reaches 2 digits and I reset the counter, there is a problem. When it reaches 2 digits, for example 10, the LCD keeps the second digit, meaning that when I restart my counter, it reads 10, 11, 12... . Elaborating on the problem, when I stop the counter at 11, it holds the 1 digit. This means that when I restart the count, it displays 11, 21, 31 and so on. This is my code as for now.
Few weeks ago,I was asked by a friend of mine if I could help him build a product counter that will count finished products after a worker has processed them. The current situation was that a worker manning a processing station had to take each product and process it, then count them and sort them into batches. And eventually he also places them in a shipping box/crate where they would be sent off to another factory. All this was done by manually noting down the amount of processed products after each process and then note down the amount of finished batches using only pen and paper.
Considering that each day several thousands of these products need to be processed by a single worker ,a product counter will save a lot of time and eliminate any counting mistakes that will require a recount of an entire batch.We are dealing with irregular sized products which come in different sizes (but all circular) and travel on different sized guide rails. So he asked if I can produce a simple counter that can be configured on site according to the size of the products and also that it can be easily moved from one station to the other without too much hassle.
This allows the product counter to be used on various sized objects (assuming that they are all round and they all travel in line one after another). Since the accuracy of the counter greatly depends on the way that the sensor is mounted and positioned it is important to remember that the smaller the counted products are the more precision, calibration and testing that needs to be applied before using this counter in a production environment.
Note that I chose to setup the sensor above the products and facing down towards the guide rail. You can position the sensor in any other way only take into consideration interference from the work environment that might trigger false counts such as people walking close by or other objects. If you choose to position the sensor on the side or the bottom you should consider adding some sort of enclosed housing or a back plate that will provide a constant distance value for when there are no products passing the sensor. If you are dealing with smaller sized products than the ones demonstrated in the video you might also need to consider adding housing to the IR LED on the sensor which will direct the light beam onto a defined area instead of just allowing it to spread in the default manner that the sensor was designed for.
Below you will find a diagram explaining about the calibration and the minimum and maximum values used in the source code; also you will find the source code itself which mainly focuses on making the device more user-friendly and can be customized on site alongside with some photos from the testing phase.
Hello friend welcome to “Techno-E-Solution” in this article we are going to learn how to connect LCD display with Arduino Uno and print "Hello World!" on LCD using Arduino Uno. The 16x2 LCD is most popular LCD in electronics projects. In upcoming project we need this display in our project so it"s the beginners level tutorial learn this tutorial with fun. So friends let"s get started..........
A PCB Design Problems Detector, An Engineering Solution Provider Import the Gerber file with one click. No need for complicated file reading steps to review easily and improve efficiency.
In this project we are going to construct a bidirectional visitor counter circuit using Arduino which registers the number of people who made entry and exit at schools, library, offices, commercial buildings etc. in a given period of time, set by an operator and automatically stores the data in a SD at the instant of closing with date and time.
The circuit detects people with the help of LDR and laser setup at entry and exit points. When a person passes through an entry / exit point the laser gets interrupted and the microcontroller registers a count. The circuit also sport automatic recovery feature where in case of power failure the counts are recovered from EEPROM memory.
The proposed project utilizes laser beam and LDR to detect the passage of a person. The LDR is mounted inside a black hollow tube with minimum of 5 cm in length and less than or equal to 1.5 cm in diameter. The tube will prevent ambient light sources hitting the LDR.
The LDR is connected to a “logic NOT gate” IC 7404 with a pull-up resistor 10K. The IC 7404 is here to output a proper digital signal to Arduino by receiving a noisy LDR input.
The Arduino pins 2 and 3 are configured as interrupts, an interrupt is generated when the voltage level turns from high to low and a count is incremented internally in the microcontroller.
The collected data during closing time is stored to a SD card, but interfacing Arduino to a SD card is not that straight forward until you use a SD card module using which you can easily interface a SD to any variant of Arduino.
A SD card module is illustrated in the above image. The SD card must be inserted in its socket in the correct direction and the pins that connect to Arduino are labeled at the backside.
The module can be supplied with 5V, however the SD card operates only at 3.3V, fortunately the module comes with an on-board 3.3V regulator to supply 3.3V to the SD card. The module also comes with a level shifter IC which takes 5V signal from Arduino or any other microcontroller and converts it to 3.3V signal which is compatible with the SD card; otherwise 5V will kill it.
The SD card utilizes SPI protocol to communicate with Arduino and generates a text file containing data of entry and exit count with date and time. An operator has to insert the SD card to his/her computer to read the data. The logged data is illustrated in the below image:
DS3231 / DS1307 utilizes I2C protocol to communicate with Arduino, it can track time and date up to year 2100 with leap year compensation and it comes with a 3V coin cell which keep the RTC running even when you disconnect the main power supply to the circuit and it can run on the coin cell for more than 2 years.
3) Once you upload the code, you will see date and time on the display. Now disconnect the power for 10 seconds and reconnect it, you should see correct date and time are displayed and running.
This project utilizes an I2C LCD adapter module which is connected to a 16 x 2 LCD display. The I2C LCD module helps the project to prototype it quickly by reducing the number of wires that connects from LCD to four; otherwise we have to connect a bunch wires from Arduino to LCD.
It utilizes I2C protocol hence its name and can be soldered on the back of the LCD or can be connected on a breadboard as illustrated in the above image. It shares the same I2C bus as RTC does. Use the on-board trim potentiometer to adjust the contrast of the display.
After you prototype the circuit in a breadboard, the main construction can be done using a well-designed PCB and use Arduino pro mini for the main construction.
1) With the completed hardware setup, including properly aligned lasers with LDR, turn on the circuit. The first step should be setting the correct time and date to RTC which is already explained in this article.
3) To set start time press the menu button and press enter. Now the LCD will ask you to set (starting) hours and use INC and DEC buttons to select an hour (0 to 23) and press enter. Now the LCD will ask you to set minutes (0 to 59), use INC and DEC buttons to select a minute and press enter, the LCD will say start time is saved.
This article includes everything you need to know about using acharacter I2C LCD with Arduino. I have included a wiring diagram and many example codes to help you get started.
In the second half, I will go into more detail on how to display custom characters and how you can use the other functions of the LiquidCrystal_I2C library.
Once you know how to display text and numbers on the LCD, I suggest you take a look at the articles below. In these tutorials, you will learn how to measure and display sensor data on the LCD.
Each rectangle is made up of a grid of 5×8 pixels. Later in this tutorial, I will show you how you can control the individual pixels to display custom characters on the LCD.
They all use the same HD44780 Hitachi LCD controller, so you can easily swap them. You will only need to change the size specifications in your Arduino code.
The 16×2 and 20×4 datasheets include the dimensions of the LCD and you can find more information about the Hitachi LCD driver in the HD44780 datasheet.
Note that an Arduino Uno with the R3 layout (1.0 pinout) also has the SDA (data line) and SCL (clock line) pin headers close to the AREF pin. Check the table below for more details.
After you have wired up the LCD, you will need to adjust the contrast of the display. On the I2C module, you will find a potentiometer that you can turn with a small screwdriver.
The LiquidCrystal_I2C library works in combination with the Wire.h library which allows you to communicate with I2C devices. This library comes pre-installed with the Arduino IDE.
To install this library, go to Tools > Manage Libraries (Ctrl + Shift + I on Windows) in the Arduino IDE. The Library Manager will open and update the list of installed libraries.
Note that counting starts at 0 and the first argument specifies the column. So lcd.setCursor(2,1) sets the cursor on the third column and the second row.
Next the string ‘Hello World!’ is printed with lcd.print("Hello World!"). Note that you need to place quotation marks (” “) around the text since we are printing a text string.
The example sketch above shows you the basics of displaying text on the LCD. Now we will take a look at the other functions of the LiquidCrystal_I2C library.
This function turns on automatic scrolling of the LCD. This causes each character output to the display to push previous characters over by one space.
If the current text direction is left-to-right (the default), the display scrolls to the left, if the current direction is right-to-left, the display scrolls to the right.
I would love to know what projects you plan on building (or have already built) with these LCDs. If you have any questions, suggestions or if you think that things are missing in this tutorial, please leave a comment down below.
LCDs are the easiest way to display data out of your electronics project and they are widely used in electronics. The most popular ones are alphanumeric ones, just like the one we used in this project.
What if you need to display more complex data or graphics? One of the cheapest solutions to this is to use is the well known Nokia 5110 LCD display. This LCD is as cheap as $4. It has a 84 x 84 pixels screen size. The Nokia 5110 LCD display communicates with Arduino over SPI which reduces the number of pins needed to connect the LCD.
Once you have all the components, use the schematic below to build the project. Note the VCC of the LCD must be connected to 3.3V. Connecting it to 5V might destroy it. Make sure you double check that before connecting your project to power.
One pin of the LCD is not connected. It is labeled as BL, the LED or LIGHT (this depends on the LCD manufacturer). This pin is for the backlight. If you intend to use the screen in the dark, feel free to connect it to 3.3V. In my case, the backlight LED is blue but might be different in yours.
Before uploading the code, we have to install two libraries. To download the first one, type “5110” in the libraries manager and select one from Adafruit. The second library is also made by Adafruit and it is called Adafruit_GFX. If you don’t know how to install those libraries, check out this tutorial. When those two libraries are installed, upload the code below to the Arduino.
In this lab exercise you will attach an LCD display to the Arduino Uno and write software to display characters on it. The steps required to communicate between the microcontroller and the LCD display are typical of how most devices are interfaced to a microcontroller.
The LCD display used in this exercise is a monochrome, 16 character by 2 line display that uses a parallel interface. LCD displays are designed with either a serial or parallel interface, and both types have advantages and disadvantages. A serial interface transfers data one bit at a time and requires only one or two I/O lines from the microcontroller but is slower and often more expensive. A parallel interface display transfers data multiple bits at a time and can usually transfer data faster but requires multiple I/O lines from the microcontroller in order to operate.
The LCD is called an "LCD shield" since the display module is mounted on a board that plugs directly into the sockets on the Arduino Uno so it doesn"t require any wires to be run between the Arduino and the LCD. Once mounted on the Arduino it uses seven of the Uno"s I/O lines for data and control signals (Port D, bits 4-7 and Port B, bits 0-2).
The LCD shield also has a cluster of six pushbuttons. Five of these are interfaced through a multistage voltage divider to ADC channel 0 of the Arduino. Depending on which of the five buttons is pressed, or none, one of six analog voltages appears on the ADC Channel 0 input. By using the ADC to convert the voltage to a number it"s possible to easily determine if one of the five buttons was pressed. The sixth button, marked "RST" is connected to the RESET line of the Arduino and can be used to restart the program.
The parallel interface to the LCD is used to transfer data between the microcontroller and a special integrated circuit (IC) in the LCD module that controls where the dark and light spots appear on the display. The presence of this IC allows the microcontroller to display the letter "A" by just sending the ASCII code for an "A" (0x41) rather than having to send information about the individual dots that make up the letter on the screen. The circuit used on this module (Hitachi HD44780) is one of the most commonly used for controlling LCD modules and is designed to communicate with a microcontroller using eight data lines and three control lines. However in order to save I/O lines it can also communicate in a 4-bit mode that sends an eight bit byte in two 4-bit "nibbles", first the most significant four bits, then the least significant four bits. The four bit mode is used with this LCD shield.
In addition to the four data lines, the controller IC has three control lines: RS (Register Select), RW (Read/Write) and E (Enable). On the LCD shield the designers have eliminated the the RW line so data can only be written to the shield. A third control line can be used to control the LCD backlight. The result of all this is that the shield can be used with just seven I/O lines, four for data and three for control signals.
These lines carry four bits of the command or data bytes that are sent to the LCD. Most operations require sending a full byte so transfers have to be done in two steps.
Backlight control (Arduino I/O pin D10 = PORTB, bit PB2)This control line is not used in any of our lab assignments. It"s important that the PB2 bit NOT be enabled as an output or this can cause the backlight to go off and the characters on the LCD will be impossible to read. Bit 2 in the DDRB register should never be set to a one.
Inside the controller IC on the LCD module are two 8-bit registers, the command register and the data register. The Register Select control line is used to determine which register the microcontroller transfers data to.
When the microcontroller wants the LCD to perform certain operations it writes the necessary 8-bit command code into the command register to initiate the operation. Typical commands include clearing the display, moving the cursor to some location, turning the display on or off, etc.
The data register is where the program writes the ASCII character codes for the characters that it wants to have displayed on the LCD. When a character is written to the data register it will appear on the display at the location that the cursor was at, and then cursor will move to the right one position. Writing a string of characters to the data register (one after the other) has the effect of making the string appear on a line of the display with the cursor positioned after the last character in the string.
Transferring commands and data to the LCD involves a number of steps all involving setting or clearing bits in the six I/O port bits (PORTD[7:4] (data), PORTB[1] (E) and PORTB[0] (RS)) that are connected to the six interface lines described above. The LCD shield does all its data transfer in the 4-bit interface mode. In some cases only 4 bits have to be transferred, in others a full 8-bit must be transferred.
Install the LCD shield on the top of the Arduino Uno. Make sure that you are lining up the pins and connectors properly before trying to push them together. Two of the male headers on the shield are the same size as the mating connectors on the Uno and these go into the D0-D7 and A0-A5 connectors. The other two male headers have fewer pins than the connectors they are plugged into. Take care to make sure that all the pins are going into the correct openings before applying pressure to push the two boards together. The LCD shield should be seated all the way into the sockets. There should be little or no gap between the sockets on the Arduino and the bottom of the black connectors on the LCD that the pins stick out of. If you have problems mounting the shield on the Uno ask one of the instructors for help.
Actual implementation of LCD functions. You will need to complete the lcd_init() and write the code for the lcd_writedata, lcd_writecommand and lcd_writenibble() functions.
Make the usual changes to the PROGRAMMER line at the top of the Makefile to make it works on your computer. Attach your Arduino+LCD to your computer and enter the command "make test" to download the data from the test.hex file to the Uno. Once the download is complete the LCD should show two lines of text as shown below.
If nothing shows up on the screen or it shows a lot of white boxes, try changing the display contrast by using your screwdriver to adjust the blue control in the upper left corner of the display. If you can"t get the test program to work, ask one of the instructors for help. Don"t try working on the rest of the lab assignment until the test program is working.
This lab exercise is a good example of how programs can be structured so the complexities of one part are hidden from other parts of the program. As much as possible the details of how the LCD module works should be handled by only a small portion of the code. Most of the program should not have to deal with knowing which I/O port bits are being used, setting the control bits, dealing with delays, etc., for each character it wants to display. To put a character on the display, the program just has to call a function that has the character to be displayed as its argument. All the details about how that character gets transferred to the LCD should be isolated in another part of the program. Doing this has an additional advantage that the LCD could be changed for a model with a different interface, and only the small number of routines that deal directly with the interface will have to be changed.
The low level function, lcd_writenibble will handle the changing of the bits in the I/O ports connected to LCD. Most of the "bit fiddling" will be done in this function. The primary task will be sending a 4-bit "nibble" to the LCD and creating the Enable signal transition from 0 to 1 back to 0. You will need to complete this function in this lab (in the file lcd.c).
The mid level functions lcd_writedata and lcd_writecommand deal with sending data and commands to the LCD by making use of the low level functions. These functions transfer one byte each time they are called. You will need to complete these functions in this lab (in the file lcd.c)
The top layer has a small number of simple functions (initialize LCD, position the cursor, write a string of characters) that make use of the mid level functions. The main part of the program only calls the functions in the top layer. The functions for positioning the cursor and writing strings are provided. You"ll only add lines to lcd_init() to initialize the I/O ports the LCD uses.
The low level function "lcd_writenibble" transfers a four bit value from the 8-bit (unsigned char) argument to the LCD. All transfers of data and commands depend on this function to do the actual transfer. Assume RS has already been set to 0 or 1 OUTSIDE of this function. Don"t set it inside this function.
All transfers of data and commands depend on this function to do the actual transfer. Data is only transferred to the LCD when the E (Enable) signals makes a 0→1→0 transition, and the lcd_writenibble routine is the only function that changes the state of the E line.
The argument to lcd_writenibble is an 8-bit "unsigned char" variable, but only four of these bits will be transferred to the LCD. Note that it is very important that "lcd_writenibble" and the functions that will be calling it agree as to which 4-bits of its 8-bit argument it will send to the LCD (i.e. place on PD[7:4]). It is likely easiest to copy the upper 4-bits of the lcdbits argument to PORTD[7:4] so that"s what we will using.
Once the four bits are copied to PORTD bits 4 through 7, then the E signal (PB1) has to make a 0→1→0 transition to cause the LCD to read the 4 bits. Data is only transferred to the LCD when the E (Enable) signals makes a 0→1→0 transition, and the lcd_writenibble routine is the only function that changes the state of the E line.
Important: Your lcd_writenibble routine must only change the bits in registers B and D that need to be changed in order to affect the transfer. Don"t just copy a full byte into a register if you only need to modify a few bits. Any bits that are not part of the transfer should not be changed. Reference your Unit 6 slides on Copying bits to see how to do this. You will lose points if you modify any other bits not associated with the LCD.
These routines must set the register select line to the correct state for a command (RS=0) or data (RS=1) transfer, and then make two calls to the low level "lcd_writenibble" function. Recall that we decided that lcd_writenibble would always transfer the upper 4-bits of its argument. So to transfer 8-bits we first send the upper four bits of the byte (normal call to "lcd_writenibble"), and then send the lower 4 bits. However to send the lower 4-bits we will need to move the lower 4-bits of the data we want to transfer in our current function into the upper 4-bit area of the argument we pass to "lcd_writenibble" (since "lcd_writenibble" expects the 4-bits it is supposed to transfer to be in that upper 4-bit area). An appropriate shift operator >> or << can be used to do this as you pass the argument. The picture below shows this concept:
Note: We could have written "lcd_writenibble" to use the lower 4-bits of its argument and then changed the mid-level functions appropriately. There is no real advantage to doing it one way or the other. The only important thing is that the three functions agree on which to use.
The top level routines are to initialize the LCD and to write strings of characters starting at specified locations. These routines should make use of the functions defined in the mid level (and if necessary the lower level) of the program. Task such as moving the cursor to a given location on the screen, writing a string of ASCII characters, etc. are common top-level tasks and the routines that do this lcd_moveto and lcd_stringout are provided for you.
Unfortunately you can"t just start sending character data to the LCD and have it appear. The module has to have a few initialization steps performed before it will accept data and display it. These are handled by the lcd_init and most of the code for these operations has been provided already in lcd.c file. However before any initialization commands can be sent to the LCD, the Arduino"s I/O ports must be configured properly to work with the LCD. The LCD uses Port B, bits 0 through 2 for control signals, and uses Port D, bits 4 through 7 for data signals. You will need to do the following steps.
At the top of this function, add the necessary code to configure Port B, bits 0 and 1 for output. Port B bit 2 should be left as an input so it won"t cause the LCD backlight to go off.
Important: The code you add to lcd_init should only configure the DDR bits for the Port bits being used by the LCD. Don"t modify any other DDR bits. The rest of the LCD initialization requires several data transfers to it, most followed by delays of specific lengths. The code for these steps have been provided for you already in the lcd_init function and should not be changed.
After the above steps are done the display is ready to accept data to display. If you now write data to the data register it should appear on the screen starting in the upper left position.
The templates for the following two functions for moving the cursor and writing a string of characters are also in the lcd.c file but we will not be writing these in this week"s lab assignment.
The LCD display uses the ASCII character codes to determine which characters to display. Once the LCD has been initialized as shown above, any byte written into the data register will result in the character with that ASCII code being displayed on the LCD and the cursor that indicates where the next character will go is advanced one position to the right. For example if the bytes with values 0x55, 0x53, 0x43 are written to the data register one after the other, the character ``USC"" will appear on the screen. Note: if you write more characters than will fit on a line, it doesn"t automatically wrap to the next line.
Disconnect the LCD panel from the Arduino by gently pulling it out of the sockets. Have one of the instructors help you with this if you are concerned about breaking the LCD.
Important: At the top of main() call your lcd_init() function. If you don"t call this function, your DDR bits won"t be set properly and you won"t get a proper E signal.
The source code for the Lab 4 assignment is not in just one file as with Lab 3. It"s in two files, lab4.c and lcd.c, so you must modify the OBJECTS line in the Makefile to indicate this.
Download it to the Arduino. Remember to use "make flash" to download your program. The "make test" is only used to download the test program in the test.hex file.
Using a short piece of wire, hook the probe to the Port B, bit 1 output (D9 on the Arduino). Don"t forget to also connect the probe"s ground wire to ground on the Arduino.
Adjust the scope setting to allow you to measure how long the E pulse is in the 1 state. Since the lcd_writedata has a 2ms delay after sending the data, most of the time the signal will be at the zero level. The two E pulses will be very narrow spikes that occur every 2ms. If the scope is triggering properly on the signal you should be able to adjust the horizontal timing to get a clear view of the width of the E pulse.
If the E pulse is not at least 230ns long you can extend the pulse by adding additional instructions to your lcd_writenibble function. For example the code below sets Port B, bit 1 to a one, and then sets it to a one a second time before it"s cleared to a zero.
Now that you have the LCD routines written and have confirmed that the E signals meets specifications, we want to build a circuit that does the following.
Pressing the "Up" button makes the counter count up, pressing the "Down" button makes it count down. When a button is pressed to change the count direction, it should start counting in that direction from the current count value (don"t start over at zero.)
Once a button has been pressed to set the direction, the button does not have to be held down. The counter should continue to count in that direction until the other button is pressed to reverse it.
The package of male-female jumper wires. These are needed to make connections between the LCD, which has pins poking up, and the breadboard that has holes for the wires to go into.
Install the push buttons on your breadboard and connect them as shown in the schematic below. The schematic shows both the internal ATmega328P names of the port bits (e.g. PC2) and the corresponding name marked on the Arduino board (A2). The switch inputs are on Arduino bits A2 and A4 which are connected to the microcontroller"s I/O bits PC2 and PC4.
Once the LCD is installed on top of the Arduino, you no longer have access to the black connectors on the Arduino in order to make connections to the I/O Ports. To remedy this, the available I/O port pins (those that are not used in communicating with the LCD) are bought up to the top of the LCD shield. Some are available as pins that stick up from the base of the LCD circuit board and you can make connections to these pins using the jumpers. Other are available from the black connectors on the LCD that you can stick wires into. For this lab you need to connect to two of the pins of Port C, PC2 and PC4. The Port C pins can be found on the blue pins at the lower right corner of the LCD as shown below. Please note that there is no connection for PC0 even though there is a "A0" marking on the PC board near the connector. PC0 is used internally by the LCD and as a result there is no pin available to connect to it.
While not used in this lab, for future reference, the available pins from Port B and Port D can be found on the black connector in the upper right corner of the LCD as shown below.
Before starting to make changes to the lab4.c file we need to change the Makefile. The source code for the Lab 4 assignment is not in just one file as with Lab 3. It"s in two files, lab4.c and lcd.c, so you must modify the OBJECTS line in the Makefile to indicate this.
To build our up/down counter we will implement it using the principles of a state machine. A state machine saves information about previous inputs by storing that information as the machine"s "state". The state information can then be referenced by the machine as it operates to determine what to output next, and perhaps, which state to transition to next.
The constants "UP" and "DOWN" can now be used to indicate which state the machine is in. To store this value you should define a state variable that stores the direction (UP or DOWN) that counter is counting. For example,
The LCD displays ASCII characters. If you use lcd_writedata to send it the value of your count variable (e.g. 2) you will get garbage on the screen since 2 is not the ASCII code for the digit 2. To display the count value you have to convert it to an ASCII character code.
If you look at an ASCII chart it shows that the ASCII code for the digits "0" through "9" are 0x30 through 0x39. So to display a digit, just add 0x30 to it and call lcd_writedata with this value as the argument.
If you just keep calling lcd_writedata each time the count changes, the characters will just march across the LCD: "0123456789012345". We need to move the cursor to the same location before each time lcd_writedata is called so the count values stay in the same place. The simplest way to do that is to send a command to the LCD that makes it move the cursor to the "home" postion in first column of the first row. To move the curso the "home" postion, call the lcd_writecommand function with an argument of 2.
Once the cursor has been moved to the upper left, the next character sent to it by calling lcd_writedata will simply overwrite the previous count value shown at that location.
Alternatively, you can do a "clear screen" operation that clears all the character positions on the LCD and also moves the cursor to the first position on the first row. To clear the screen, call the lcd_writecommand function with an argument of 1. After the screen has been cleared, the program can call lcd_writedata to display the count character in the first position on row 1.
Determine the next value is to be displayed based on the current count value and the direction state variable, and update your variable storing the current count value accordingly.
Display the current count value on the LCD. This will require doing a lcd_writecommand operation to clear the screen, and then writing the count value with lcd_writedata.
Once you have the counter working try an experiment. Wait until the displayed digit changes and then quickly press the button to change the counting direction but only hold it down for very short time. The counting direction probably won"t change. Now try it again but this time hold the button down until after the next count change and then let it up. Has the count direction changed? Take a look at your code and try to determine why this is happening. Why does a quick press of the button sometimes not work but a longer one does?
Think about how we could modify the software to still have the counter change every half second, but be responsive to button presses at any time in the cycle and for any length. Try to implement your ideas and see if you can make the buttons always change the counter direction regardless of when they are pressed or for how long.
One hint: Suppose we wanted to do something once a week, we can"t just do it once and then go to sleep for a week and wake up 7 days later (well, most of us can"t). We have other things to do as well. Thus we wake up at a finer granularity (once per day). If we kept a counter (starting at 0), we could increment it every day we wake up and then only when the counter reaches 7 would we know it has been a week and we can do our weekly task. Then we can set our counter back to 0 and repeat the process of incrementing the count each day we wake up. In this way I can still do weekly tasks (when the count reaches 7) but also do more frequent, daily tasks since I wake up every day.
This approach can be extended if we have several tasks that each need to be done at a different interval period (e.g. something every 100 ms, another thing every 250 ms, and a third every 400 ms) we can find a smaller granularity (say 50 ms) to increment a counter (or three separate counters) and only perform the 3 tasks when the count reaches the appropriate threshold (e.g. 2 for 100 ms, 5 for 250 ms, and 8 for 400 ms...The modulo operator can be helpful if you want to use only 1 counter).
Try to organize your code to use good style and indentation. Examine your solution for repetitive code that can be "factored" and replaced with a function, or other similar enhancements to make the code readable and modular. Points may be deducted for failure to do so. Once you have the assignment working demonstrate it to one of the instructors.
The answers to the review questions below should be edited into the Lab4_Answers.txt file. The Lab4_Answers.txt file and all source code (lab4.c, lcd.c, lcd.h and Makefile) must be uploaded to the Vocareum web site by the due date. See the Assignments page of the class web site for a link for uploading.
Billy Bruin has read that section of the ATmega328P datasheet and says that he now knows an easy way to "toggle" the E bit (flipping it to its opposite value) to generate the E pulse in the lcd_writenibble() function by using this code.
Tammy Trojan has read the same section of the datasheet, but she says that while Billy"s method may work for the lcd_writenibble() function in Lab 4, it can cause problems when used in other situations. She recommends using this code.
Study Section 14.2.2 and explain what the problem is with Billy"s method, and why Tammy"s is the correct way to do it. (Clarification: While section 14.2.2 does not explicitly say so, writing a 0 to the PINB register has NO EFFECT (nothing is changed)).
A 16x2 LCD means it can display 16 characters per line and there are 2 such lines. In this LCD each character is displayed in 5x7 pixel matrix. This LCD has two registers, namely, Command and Data. The command register stores the command instructions given to the LCD. A command is an instruction given to LCD to do a predefined task like initializing it, clearing its screen, setting the cursor position, controlling display etc. The data register stores the data to be displayed on the LCD. The data is the ASCII value of the character to be displayed on the LCD. Click to learn more about internal structure of a LCD.
In this project, we will connect an LCD screen to an Arduino and use it to display some basic text. This covers both the physical connections and the programming required to get an LCD to work. If this is your first project then we recommend that you familiarise yourself with programming an Arduino first.
This project consists of two parts, one which prints Hello World, The DIY Life and a second which prints The DIY Life and then prints a seconds since start-up counter on the second line.
The screens we are covering in this project have 16 pin parallel interfaces, meaning that the Arduino has to send data on multiple pins at the same time in order to change the screen text. Fortunately, the Arduino has a built in library for LCD screens which are compatible with the Hitachi HD44780 driver so we can make use of the built in function library and do not have to manually code functions to control the screen.
To understand the basic on how the screen is operated, there are three pins which control the registers (RS, RW and E), then 8 data transfer pins (D0-D7) and finally a set of pins to provide power, control the contrast and turn the backlight on and off. For displaying general text you only need to make use of 4 of the data transfer pins as the screen will be running in 4 bit mode.
Firstly you need to connect the screen up as shown in the diagram below. This can be done in one of two ways. You can solder a wire ribbon onto the screen and then pins on to the ends of the wires which then plug directly into the Arduino or you can solder a pin header onto the screen and plug it into a breadboard which you can then connect to the Arduino using jumpers.
The pin connections to the LCD screen are as follows: Pin 10, 11 and 12 are used to control the registers and are connected to the E, RW and RS pins respectively. Pins 2,3,4 and 5 are the data transfer pins and are connected to d7, d6, d5 and d4 respectively. Be careful when connecting the pins as the numerical sequence on the Arduino pins is the opposite to the screen pins.
Now you can begin the coding. For the first example, we will only be using the setup loop as we just need the screen to display “Hello World” and “The DIY Life” on the screen without any further changes.
Now we move on to the setup code method. We first tell the lcd object how many columns and rows or characters our screen has. In this case the screen size is 16 x 2. We then clear the screen to ensure that it is blank, set the cursor to the first row and first character, then begin sending the text “Hello World” to the screen. We then tell the cursor to move to the second row of characters and print “The DIY Life”.
If you have connected everything correctly then the screen should now display Hello World on the first line and The DIY Life on the second line. You may need to play around with the contrast adjustment on the 10K pot to make the text visible, this adjustment is shown in the video below:
When you run this code you should see The DIY Life in the first row and a counter which updates every second in the second row and runs until 100 seconds. The counter in operation is shown in the video below:
You have now covered the basics on connecting an LCD screen to the Arduino and using the built in control functions to change t