Hướng dẫn LCD ESP32 (và cả ESP8266) trên Arduino IDE
Cùng tìm hiểu cách sử dụng LCD ESP32 để hiển thị thông tin mình cần, dựa trên nền tảng Arduino IDE. IoTZone sẽ hướng dẫn chi tiết về cách kết nối phần cứng, lập trình (giải thích chi tiết ý nghĩa từng dòng lệnh) để hiển thị các đoạn văn bản tĩnh hoặc văn bản động có thể thay đổi theo thời gian.
Dù đây là hướng dẫn với ESP32, nhưng bạn vẫn có thể sử dụng mạch ESP8266 để làm theo. Chúng hoàn toàn tương tự.
Giới thiệu màn hình LCD 16×2
Trong bài hướng dẫn LCD ESP32 này, mình sẽ sử dụng loại màn hình LCD 16×2. Tuy nhiên, nếu bạn sử dụng loại màn hình LCD khác thì vẫn ổn, không vấn đề gì nhé!
Ưu điểm nổi bật mà mình thích ở màn hình LCD là chúng có cách nối dây khá đơn giản, bạn chỉ cần nối các chân SCL và SDA.
Phía sau màn hình LCD có sẵn một chiết áp, cho phép chúng ta điều chỉnh độ tương phản giữa các ký tự và ánh sáng nền trên màn hình LCD. Nếu độ tương phản chưa cao, bạn không nhìn rõ chữ thì bạn cần phải điều chỉnh lại chiết áp này thử nhé! Với các màn hình LCD thông thường khác, bạn cần phải gắn thêm 1 chiết áp để điều chỉnh độ tương phản này.
Chuẩn bị
- Mạch ESP32 hoặc mạch ESP8266
- Màn hình LCD 16×2 (cổng I2C)
- Dây Jumper Female – Female
Kết nối phần cứng
IoTZone sẽ hướng dẫn chi tiết cách kết nối cho cả mạch ESP32 lẫn ESP8266:
ESP32
Bạn kết nối màn hình LCD với ESP32 như hình bên dưới, trong đó:
- Chân SDA nối với GPIO 21
- Chân SCL nối với GPIO 22
- Chân VCC (màn hình LCD) nối với VIN
- Chân GND nối với GND
ESP8266
Với mạch ESP8266, chân VCC cũng nối với VIN, GND cũng nối với GND như ESP32. Riêng SDA và SCL, bạn hãy đổi sang cổng GPIO 4 và GPIO 5 nhé:
Cài thư viện LiquidCrystal_I2C trên Arduino IDE
Trước khi cài thư viện, bạn nên cài các tiện ích ESP32 và ESP8266 vào trong phần mềm Arduino IDE của mình nhé!
Sau đó, hãy cài thư viện LiquidCrystal_I2C theo hướng dẫn sau:
- Click vào đây để tải thư viện .Zip về máy
- Giải nén tập tin vừa tải về để có thư mục mới
- Đổi tên thư mục thành LiquidCrystal_I2C
- Di chuyển thư mục vào thư mục thư viện / libraries trong Arduino IDE
Tìm địa chỉ của màn hình LCD ESP32
Trước khi lập trình hiển thị ký tự trên màn hình LCD ESP32, bạn cần tìm địa chỉ của nó. Sau khi kết nối LCD với ESP32, bạn hãy upload chương trình sau vào mạch:
#include <Wire.h> void setup() { Wire.begin(); Serial.begin(115200); Serial.println("\nI2C Scanner"); } void loop() { byte error, address; int nDevices; Serial.println("Scanning..."); nDevices = 0; for(address = 1; address < 127; address++ ) { Wire.beginTransmission(address); error = Wire.endTransmission(); if (error == 0) { Serial.print("I2C device found at address 0x"); if (address<16) { Serial.print("0"); } Serial.println(address,HEX); nDevices++; } else if (error==4) { Serial.print("Unknow error at address 0x"); if (address<16) { Serial.print("0"); } Serial.println(address,HEX); } } if (nDevices == 0) { Serial.println("No I2C devices found\n"); } else { Serial.println("done\n"); } delay(5000); }
Sau khi nạp code trên, bạn hãy mở Serial Monitor ở tốc độ 115200 và khởi động lại mạch ESP32. Trên màn hình sẽ hiển thị địa chỉ của màn hình LCD:
Như trong hình trên mình chụp, địa chỉ của màn hình LCD ESP32 là 0x27. Nếu bạn dùng màn hình LCD tương tự như của mình, thì địa chỉ bạn nhận được cũng sẽ tương tự.
Hiển thị văn bản tĩnh trên màn hình LCD
Đây là một dự án khá đơn giản, bạn chỉ cần chọn nơi cần hiển thị văn bản tĩnh rồi gửi tin nhắn đến màn hình LCD ESP32 là được.
Nạp chương trình hoàn chỉnh
Dưới đây, IoTZone có viết sẵn một đoạn code để hiển thị dòng chữ “Hello, World!” trên màn hình LCD:
#include <LiquidCrystal_I2C.h> // set the LCD number of columns and rows int lcdColumns = 16; int lcdRows = 2; // set LCD address, number of columns and rows // if you don't know your display address, run an I2C scanner sketch LiquidCrystal_I2C lcd(0x27, lcdColumns, lcdRows); void setup(){ // initialize LCD lcd.init(); // turn on LCD backlight lcd.backlight(); } void loop(){ // set cursor to first column, first row lcd.setCursor(0, 0); // print message lcd.print("Hello, World!"); delay(1000); // clears the display to print new message lcd.clear(); // set cursor to first column, second row lcd.setCursor(0,1); lcd.print("Hello, World!"); delay(1000); lcd.clear(); }
Sau khi nạp chương trình vào, bạn sẽ thấy dòng chữ “Hello World” được hiển thị ở hàng đầu tiên, sau đó tắt và tiếp tục hiển thị ở hàng thứ 2, và chuỗi hoạt động này lặp lại liên tục.
Dưới đây, mình sẽ giải thích chi tiết hơn về đoạn code này:
Giải thích chương trình
Khai báo thư viện cần dùng với LCD ESP32:
#include <LiquidCrystal_I2C.h>
Khai báo số cột và số hàng của màn hình LCD, mình đang dùng loại 16×2 nên code như sau:
int lcdColumns = 16; int lcdRows = 2;
Xác định địa chỉ của màn hình LCD, số cột và số hàng:
LiquidCrystal_I2C lcd(0x27, lcdColumns, lcdRows);
Trong setting(), bạn khởi tạo màn hình LCD ESP32:
lcd.init();
Bật đèn nền để chúng ta có thể đọc được ký tự trên đó:
lcd.backlight();
Để hiển thị văn bản tĩnh trên màn hình LCD, bạn cần phải di chuyển con trỏ đến nơi cần viết tin nhắn:
lcd.setCursor(0, 0);
Lưu ý số 0 tương ứng với cột đầu tiên, số 1 tương ứng với cột số 2 và cứ thế tiếp diễn.
In tin nhắn mình cần ra màn hình LCD:
lcd.print("Hello, World!");
Đợi 1 giây thì xóa màn hình:
lcd.clear();
Di chuyển con trỏ đến vị trí mới là cột đầu tiên ở hàng thứ 2:
lcd.clear();
Quá trình trên được đặt trong vòng lặp loop() nên chúng sẽ lặp đi lặp lại liên tục.
Hiển thị văn bản chạy ngang trên màn hình LCD ESP32
Đây là một tính năng hữu ích khi chúng ta cần hiển thị những đoạn văn bản dài hơn 16 ký tự. Khi đó, các văn bản sẽ tự động chạy ngang trên màn hình LCD. Tuy nhiên, nhiều bạn sẽ gặp khó khăn như:
- Việc văn bản chạy ngang sẽ chạy trên cả 2 hàng. Do đó, chúng ta không thể tạo ra một hàng văn bản tĩnh cố định và 1 hàng văn bản chạy ngang được
- Nếu bạn hiển thị tin nhắn dài hơn 16 ký tự thì nó không hoạt động ổn định
Do đó, IoTZone đã chuẩn bị sẵn đoạn code dưới đây, để bạn có thể làm các đoạn văn bản dài hơn có thể chạy ngang trên màn hình. Đoạn code bên dưới cho phép hàng đầu tiên hiển thị văn bản tĩnh, còn hàng thứ 2 hiển thị văn bản chạy ngang màn hình với độ dài lớn hơn 16 ký tự:
#include <LiquidCrystal_I2C.h> // set the LCD number of columns and rows int lcdColumns = 16; int lcdRows = 2; // set LCD address, number of columns and rows // if you don't know your display address, run an I2C scanner sketch LiquidCrystal_I2C lcd(0x27, lcdColumns, lcdRows); String messageStatic = "Static message"; String messageToScroll = "This is a scrolling message with more than 16 characters"; // Function to scroll text // The function acepts the following arguments: // row: row number where the text will be displayed // message: message to scroll // delayTime: delay between each character shifting // lcdColumns: number of columns of your LCD void scrollText(int row, String message, int delayTime, int lcdColumns) { for (int i=0; i < lcdColumns; i++) { message = " " + message; } message = message + " "; for (int pos = 0; pos < message.length(); pos++) { lcd.setCursor(0, row); lcd.print(message.substring(pos, pos + lcdColumns)); delay(delayTime); } } void setup(){ // initialize LCD lcd.init(); // turn on LCD backlight lcd.backlight(); } void loop(){ // set cursor to first column, first row lcd.setCursor(0, 0); // print static message lcd.print(messageStatic); // print scrolling message scrollText(1, messageToScroll, 250, lcdColumns); }
Chương trình này có phần đầu khá giống với hướng dẫn LCD ESP32 hiển thị văn bản tĩnh, nên mình sẽ giải thích về các phần khác biệt bên dưới – hàm scrolltext thôi nhé:
void scrollText(int row, String message, int delayTime, int lcdColumns) { for (int i=0; i < lcdColumns; i++) { message = " " + message; } message = message + " "; for (int pos = 0; pos < message.length(); pos++) { lcd.setCursor(0, row); lcd.print(message.substring(pos, pos + lcdColumns)); delay(delayTime); } }
Với tính năng này, bạn cần đưa vào các thông tin như:
- row: số hàng mà bạn muốn hiển thị văn bản trên LCD ESP32
- message: Tin nhắn mà bạn muốn chạy ngang trên màn hình
- DelayTime: Khoảng thời gian giữa mỗi lần dịch chuyển ký tự. Thời gian delay càng cao thì văn bản chạy ngang màn hình LCD ESP32 càng chậm và ngược lại
- lcdColums: số cột của màn hình LCD của bạn
Trong đoạn code trên, chúng ta sử dụng ham scrollText():
scrollText(1, messageToScroll, 250, lcdColumns);
Biến messageToScroll hiển thị ở hàng thứ 2 trên màn hình LCD ESP32 (vì số 1 tương ứng với hàng thứ 2), với thời gian delay là 250ms.
Hiển thị ký tự tùy chỉnh
Trên màn hình LCD ESP32 16×2 này có sẵn 32 khối khác nhau để chúng ta tùy chỉnh ký tự. Mỗi khối đều được tạo thành từ các pixel nhỏ (5×8).
Do đó, bạn có thể tùy chỉnh các ký tự theo ý mình bằng cách điều chỉnh từng pixel nhỏ trong từng khối. Để làm được điều đó, chúng ta cần tạo một biến byte để lưu trạng thái của từng pixel nhỏ. Có một Website hỗ trợ chúng ta tạo biến byte dễ dàng bằng hình ảnh, bạn có thể truy cập vào đây để xem thử nhé!
Ví dụ, dưới đây là biến byte để hiển thị ký tự hình trái tim:
Khi có biến byte, bạn hãy sao chép chúng vào phần setting() và gọi nó là heart (trái tim):
byte heart[8] = { 0b00000, 0b01010, 0b11111, 0b11111, 0b11111, 0b01110, 0b00100, 0b00000 };
Trong setup(), tiếp tục tạo một đối tượng tùy chỉnh bằng hàm createChar():
lcd.createChar(0, heart);
Trong loop(), di chuyển con trỏ đến nơi cần hiển thị ký tự:
lcd.setCursor(0, 0);
Hiển thị ký tự:
lcd.write(0);
Lời kết
Trên đây, IoTZone đã hướng dẫn chi tiết cho bạn cách lập trình LCD ESP32 để hiển thị các ký tự, từ văn bản tĩnh, văn bản động cho đến tùy chỉnh từng ký tự. Chúc các bạn thành công!