20. Chapter I2C LCD1602
In the previous chapter, we have used the LED matrix to display images and characters. Now, let us use a screen module LCD1602 with a higher resolution to display more content.
There are multiple versions of LCD1602. Your purchase may be one of the following:
I2C LCD1602 |
I2C LCD1602 |
|
|
There is a conversion module on the back of the I2C LCD1602 module. Convert parallel interface to I2C serial interface. Although they have different interfaces, their functions are the same.
20.1. Project Display the String on I2C LCD1602
In this chapter, we will learn about the LCD1602 Display Screen.Firstly, use I2C LCD1602 to display some strings.
20.1.1. Component List
Control board x1
|
||
Breadboard x1
|
GPIO Extension Board x1
|
|
USB cable x1
|
Jumper M/M x3
|
|
I2C LCD1602 Module x1
|
||
20.1.2. Component Knowledge
20.1.2.1. I2C LCD1602
LCD1602 can display 2 lines of characters in 16 columns. It can display numbers, letters, symbols, ASCII code and so on.
I2C LCD1602 Display Screen integrates a I2C interface, which connects the serial-input & parallel-output module to the LCD1602 Display Screen. This allows us to only use 4 lines to the operate the LCD1602.
I2C (Inter-Integrated Circuit) is a two-wire serial communication, which is used to connect micro controller with its peripheral equipments. Device that use I2C communication are all connected to the serial data (SDA) line and a serial clock (SCL) line (called I2C bus). Each device among them has a unique address and can be a transmitter or receiver. Additionally, they can communicate with devices connected to the Bus.
Next, let’s try to use the LCD1602 I2C module to display characters.
20.1.3. Circuit
The connection of control board and I2C LCD1602 is shown below.
Schematic diagram |
|
Hardware connection If you need any support, please feel free to contact us via: support@freenove.com |
|
20.1.4. Sketch
20.1.4.1. Sketch Display_the_string_on_LCD1602
This code uses a library named “LiquidCrystal_I2C”, if you have not installed it, please do so first.
Library is an important feature of the open source world, and we know that Arduino is an open source platform
that everyone can contribute to.
20.1.4.2. How to install the library
There are two ways to add libraries.
you can search “LiquidCrystal_I2C” in library manager to install.
The second way, Click “Add .ZIP Library…” and then find LiquidCrystal_I2C.zip in libraries folder (this folder is in the folder unzipped form the ZIP file we provided). This library can facilitate our operation of I2C LCD1602.
Now let’s start to write code to use LCD1602 to display static characters and dynamic variables.
1/**********************************************************************
2 Filename : Sketch_20.1.1_Display_the_string_on_LCD1602
3 Description : Display the string on LCD1602
4 Auther : www.freenove.com
5 Modification: 2024/08/05
6**********************************************************************/
7
8#include <LiquidCrystal_I2C.h>
9
10// initialize the library with the numbers of the interface pins
11LiquidCrystal_I2C lcd(0x27, 16, 2);
12
13void setup() {
14 if (!i2CAddrTest(0x27)) {
15 lcd = LiquidCrystal_I2C(0x3F, 16, 2);
16 }
17 lcd.init(); // initialize the lcd
18 lcd.backlight(); // Turn on backlight
19 lcd.print("hello, world!");// Print a message to the LCD
20}
21
22void loop() {
23 // (note: line 1 is the second row, since counting begins with 0):
24 lcd.setCursor(0, 1);// set the cursor to column 0, line 1
25 // print the number of seconds since reset:
26 lcd.print("Counter:");
27 lcd.print(millis() / 1000);
28}
29
30bool i2CAddrTest(uint8_t addr) {
31 Wire.begin();
32 Wire.beginTransmission(addr);
33 if (Wire.endTransmission() == 0) {
34 return true;
35 }
36 return false;
37}
Following are the LiquidCrystal_I2C library used for controlling LCD:
1#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C library provides LiquidCrystal_I2C class that controls LCD1602. When we instantiate a LiquidCrystal_I2C object, we can input some parameters. And these parameters are the row/column numbers of the I2C addresses and screen that connect to LCD1602:
1LiquidCrystal_I2C lcd(0x27, 16, 2); // set the LCD address to 0x27 for a 16 chars and 2 line display
First, initialize the LCD and turn on LCD backlight.
1lcd.init(); // initialize the lcd
2lcd.backlight(); // Turn on backlight
And then print a string:
1lcd.print("hello, world!");// Print a message to the LCD
Print a changing number in the loop () function:
1void loop() {
2 // (note: line 1 is the second row, since counting begins with 0):
3 lcd.setCursor(0, 1);// set the cursor to column 0, line 1
4 // print the number of seconds since reset:
5 lcd.print("Counter:");
6 lcd.print(millis() / 1000);
7}
Before printing characters, we need to set the coordinate of the printed character, that is, in which line and which column:
1lcd.setCursor(0, 1);// set the cursor to column 0, line 1
- LiquidCrystal_I2C Class
LiquidCrystal_I2C class can control common LCD screen. First, we need instantiate an object of LiquidCrystal_I2C type, for example:
LiquidCrystal_I2C lcd(0x27, 16, 2);
When an object is instantiated, a constructed function of the class is called a constructor. In the constructor function, we need to fill in the I2C address of the LCD module, as well as the number of columns and rows of the LCD module. The number of columns and rows can also be set in the lcd.begin ().
The functions used in the LiquidCrystal_I2C class are as follows:
lcd.setCursor (col, row): set the coordinates of the to-be-printed character. The parameters are the numbers of columns and rows of the characters (start from 0, the number 0 represents first row or first line).
lcd.print (data): print characters. Characters will be printed on the coordinates set before. If you do not set the coordinates, the string will be printed behind the last printed character.
Verify and upload the code, then observe the LCD screen. If the display is not clear or there is no display, adjust the potentiometer on the back of I2C module to adjust the screen contrast until the character is clearly displayed on the LCD.
You can use the I2C LCD1602 to replace the serial port as a mobile screen when you print the data latter.
20.2. Project I2C LCD1602 Clock
In the previous chapter, we have used I2C LCD1602 to display some strings, and now let us use I2C LCD1602 to display the temperature sensor value.
20.2.1. Component List
Control board x1
|
||||
Breadboard x1
|
GPIO Extension Board x1
|
|||
USB cable x1
|
Jumper M/M x3
|
|||
I2C LCD1602 Module x1
|
Thermistor x1
|
Resistor 10kΩ x1 |
||
20.2.2. Code Knowledge
20.2.2.1. Timer
A Timer can be set to produce an interrupt after a period of time. When a timer interrupt occurs, the processor will jump to the interrupt function to process the interrupt event. And after completion the processing, execution will return to the interrupted location to go on. If you don’t close the timer, interrupt will occur at the intervals you set.
20.2.3. Circuit
The connection is shown below. Pin A0 is used to detect the voltage of thermistor.
Schematic diagram |
|
Hardware connection If you need any support, please feel free to contact us via: support@freenove.com |
|
20.2.4. Sketch
This code uses a library named “CallbackTimerR4 “, if you have not installed it, please do so first.
Library is an important feature of the open source world, and we know that Arduino is an open source platform
that everyone can contribute to.
20.2.4.1. How to install the library
open Arduino IDE, click Sketch -> Include Library -> Add .ZIP Library, In the pop-up window, find the file named “./Libraries/ CallbackTimerR4-main.zip” which locates in this directory, and click OPEN.
20.2.4.2. Sketch LCD1602_Clock
The CBTimer library is used here to manipulate timers.
Now write code to make LCD1602 display the time and temperature, and the time can be modified through the serial port.
1/**********************************************************************
2 Filename : Sketch_20.2.1_LCD1602_Clock
3 Description : LCD1602 Clock
4 Auther : www.freenove.com
5 Modification: 2024/08/05
6 CallbackTimerR4 is provided by Kingsman
7 Urls : https://github.com/embedded-kiddie/CallbackTimerR4
8**********************************************************************/
9
10#include <LiquidCrystal_I2C.h>
11#include "CBTimer.h"
12
13// initialize the library with the numbers of the interface pins
14LiquidCrystal_I2C lcd(0x27, 16, 2);
15int tempPin = 0; // define the pin of temperature sensor
16float tempVal; // define a variable to store temperature value
17int hour, minute, second; // define variables stored record time
18
19void setup() {
20 if (!i2CAddrTest(0x27)) {
21 lcd = LiquidCrystal_I2C(0x3F, 16, 2);
22 }
23 lcd.init(); // initialize the lcd
24 lcd.backlight(); // Turn on backlight
25 startingAnimation(); // display a dynamic start screen
26 Serial.begin(115200); // initialize serial port with baud rate 9600
27 Serial.println("Input hour,minute,second to set time.");
28 static CBTimer timer;
29 timer.begin(1000, timerInt);
30}
31
32void loop() {
33 // Get temperature
34 tempVal = getTemp();
35 if (second >= 60) { // when seconds is equal to 60, minutes plus 1
36 second = 0;
37 minute++;
38 if (minute >= 60) { // when minutes is equal to 60, hours plus 1
39 minute = 0;
40 hour++;
41 if (hour >= 24) { // when hours is equal to 24, hours turn to zero
42 hour = 0;
43 }
44 }
45 }
46 lcdDisplay(); // display temperature and time information on LCD
47 delay(200);
48 serialEvent();
49}
50
51void startingAnimation() {
52 for (int i = 0; i < 16; i++) {
53 lcd.scrollDisplayRight();
54 }
55 lcd.print("starting...");
56 for (int i = 0; i < 16; i++) {
57 lcd.scrollDisplayLeft();
58 delay(300);
59 }
60 lcd.clear();
61}
62// the timer interrupt function of FlexiTimer2 is executed every 1s
63void timerInt() {
64 second++; // second plus 1
65}
66// serial port interrupt function
67void serial_Event() {
68 int inInt[3]; // define an array to save the received serial data
69 while (Serial.available()) {
70 for (int i = 0; i < 3; i++) {
71 inInt[i] = Serial.parseInt(); // receive 3 integer data
72 }
73 // print the received data for confirmation
74 Serial.print("Your input is: ");
75 Serial.print(inInt[0]);
76 Serial.print(", ");
77 Serial.print(inInt[1]);
78 Serial.print(", ");
79 Serial.println(inInt[2]);
80 // use received data to adjust time
81 hour = inInt[0];
82 minute = inInt[1];
83 second = inInt[2];
84 // print the modified time
85 Serial.print("Time now is: ");
86 Serial.print(hour / 10);
87 Serial.print(hour % 10);
88 Serial.print(':');
89 Serial.print(minute / 10);
90 Serial.print(minute % 10);
91 Serial.print(':');
92 Serial.print(second / 10);
93 Serial.println(second % 10);
94 }
95}
96// function used by LCD1602 to display time and temperature
97void lcdDisplay() {
98 lcd.setCursor(0, 0); // set the cursor to (0,0) (first column,first row).
99 lcd.print("TEMP: "); // display temperature information
100 lcd.print(tempVal);
101 lcd.print("C");
102 lcd.setCursor(0, 1); // set the cursor to (0,1) (first column,second row)
103 lcd.print("TIME: "); // display time information
104 lcd.print(hour / 10);
105 lcd.print(hour % 10);
106 lcd.print(':');
107 lcd.print(minute / 10);
108 lcd.print(minute % 10);
109 lcd.print(':');
110 lcd.print(second / 10);
111 lcd.print(second % 10);
112}
113// function used to get temperature
114float getTemp() {
115 // Convert analog value of tempPin into digital value
116 int adcVal = analogRead(tempPin);
117 // Calculate voltage
118 float v = adcVal * 5.0 / 1024;
119 // Calculate resistance value of thermistor
120 float Rt = 10 * v / (5 - v);
121 // Calculate temperature (Kelvin)
122 float tempK = 1 / (log(Rt / 10) / 3950 + 1 / (273.15 + 25));
123 // Calculate temperature (Celsius)
124 return tempK - 273.15;
125}
126
127bool i2CAddrTest(uint8_t addr) {
128 Wire.begin();
129 Wire.beginTransmission(addr);
130 if (Wire.endTransmission() == 0) {
131 return true;
132 }
133 return false;
134}
In the code, we define 3 variables to represent time: second, minute, hour.
1static CBTimer timer;
2timer.begin(1000, timerInt);
After every interrupt, the second plus 1.
1void timerInt() {
2 second++; // second plus 1
3}
In the loop () function, the information on the LCD display will be refreshed at set intervals.
1void loop() {
2 ...
3 lcdDisplay(); // display temperature and time information on LCD
4 delay(200);
5 serial_Event();
6}
In the loop function, we need to control the second, minute, hour. When the second increases to 60, the minute adds 1, and the second is reset to zero; when the minute increases to 60, the hour adds 1, and the minute is reset to zero; when the hour increases to 24, reset it to zero.
1if (second >= 60) { // when seconds is equal to 60, minutes plus 1
2 second = 0;
3 minute++;
4 if (minute >= 60) { // when minutes is equal to 60, hours plus 1
5 minute = 0;
6 hour++;
7 if (hour >= 24) { // when hours is equal to 24, hours turn to zero
8 hour = 0;
9 }
10 }
11}
We define a function lcdDisplay () to refresh the information on LCD display. In this function, use two bit to display the hour, minute, second on the LCD. For example, hour/ 10 is the unit, hour% 10 is the tens.
1void lcdDisplay() {
2 lcd.setCursor(0, 0); // set the cursor to (0,0) (first column,first row).
3 lcd.print("TEMP: "); // display temperature information
4 lcd.print(tempVal);
5 lcd.print("C");
6 lcd.setCursor(0, 1); // set the cursor to (0,1) (first column,second row)
7 lcd.print("TIME: "); // display time information
8 lcd.print(hour / 10);
9 lcd.print(hour % 10);
10 lcd.print(':');
11 lcd.print(minute / 10);
12 lcd.print(minute % 10);
13 lcd.print(':');
14 lcd.print(second / 10);
15 lcd.print(second % 10);
16}
The serial_Event function is used to receive the data sent by the computer to adjust the time and return the data for confirmation.
1void serial_Event() {
2 int inInt[3]; // define an array to save the received serial data
3 while (Serial.available()) {
4 for (int i = 0; i < 3; i++) {
5 inInt[i] = Serial.parseInt(); // receive 3 integer data
6 }
7 // print the received data for confirmation
8 Serial.print("Your input is: ");
9 Serial.print(inInt[0]);
10 Serial.print(", ");
11 Serial.print(inInt[1]);
12 Serial.print(", ");
13 Serial.println(inInt[2]);
14 // use received data to adjust time
15 hour = inInt[0];
16 minute = inInt[1];
17 second = inInt[2];
18 // print the modified time
19 Serial.print("Time now is: ");
20 Serial.print(hour / 10);
21 Serial.print(hour % 10);
22 Serial.print(':');
23 Serial.print(minute / 10);
24 Serial.print(minute % 10);
25 Serial.print(':');
26 Serial.print(second / 10);
27 Serial.println(second % 10);
28 }
29}
We also define a function that displays a scrolling string when the control board has been just started.
1void startingAnimation() {
2 for (int i = 0; i < 16; i++) {
3 lcd.scrollDisplayRight();
4 }
5 lcd.print("starting...");
6 for (int i = 0; i < 16; i++) {
7 lcd.scrollDisplayLeft();
8 delay(300);
9 }
10 lcd.clear();
11}
Verify and upload the code. The LCD screen will display a scrolling string first, and then displays the temperature and time. We can open Serial Monitor and enter time in the sending area, then click the Send button to set the time.













