Blog

2026-07-04 · 7 min read

IoT: LCD I2C và Morse Code

Ghi chú cách nối LCD 16x2 I2C, các hàm thường dùng và bài thực hành nhập Morse bằng nút bấm.

LCD 16x2 I2C connected to a button for Morse input

LCD I2C giúp mạch IoT dễ quan sát hơn

Serial Monitor rất hữu ích khi debug, nhưng không phải lúc nào thiết bị IoT cũng cắm với máy tính. Một màn hình LCD 16x2 giúp hiển thị trạng thái ngay trên mạch: giá trị cảm biến, chế độ hoạt động, lỗi kết nối hoặc dữ liệu người dùng nhập.

Bài này giới thiệu LCD 16x2 dùng module I2C và một bài thực hành nhỏ: nhập Morse code bằng nút bấm rồi hiển thị lên LCD.

LCD 16x2 hiển thị chuỗi Morse nhập từ nút bấm

LCD 16x2 nghĩa là gì?

LCD 16x2 có 16 cột và 2 hàng. Mỗi ô hiển thị một ký tự.

ABCDEFGHIJKLMNOP
1234567890123456

LCD song song truyền thống có nhiều chân dữ liệu và chân điều khiển. Khi gắn thêm module I2C, việc nối dây đơn giản hơn nhiều vì chỉ cần bốn chân.

ChânVai trò
GNDCực âm, nối về mass
VCCNguồn cấp, thường là 5V
SDAĐường dữ liệu I2C
SCLĐường clock I2C

Cách nối dây

Với Arduino Uno:

LCD  -> Arduino Uno
GND  -> GND
VCC  -> 5V
SDA  -> A4
SCL  -> A5

Với ESP32 phổ biến:

SDA -> GPIO21
SCL -> GPIO22

Với ESP32-C3 Super Mini, nhiều board dùng:

SDA -> GPIO8
SCL -> GPIO9

Nếu LCD không hiển thị, đừng sửa code ngay. Hãy kiểm tra nguồn, dây SDA/SCL, địa chỉ I2C và biến trở chỉnh tương phản trên module trước.

Sơ đồ nối dây LCD I2C với Arduino Uno

Các hàm LCD thường dùng

HàmCông dụng
lcd.init()Khởi tạo LCD
lcd.backlight()Bật đèn nền
lcd.noBacklight()Tắt đèn nền
lcd.clear()Xóa toàn bộ màn hình
lcd.home()Đưa con trỏ về góc trái dòng đầu
lcd.setCursor(column, row)Đặt vị trí in ký tự
lcd.cursor() / lcd.noCursor()Hiện hoặc ẩn con trỏ
lcd.blink() / lcd.noBlink()Bật hoặc tắt nháy con trỏ
lcd.scrollDisplayLeft()Cuộn nội dung sang trái
lcd.scrollDisplayRight()Cuộn nội dung sang phải

Ví dụ đặt con trỏ ở cột đầu tiên, hàng thứ hai:

lcd.setCursor(0, 1);
lcd.print("Hello IoT");

Bài thực hành: Morse code với LCD và nút bấm

Mục tiêu là dùng một nút bấm để nhập tín hiệu Morse:

  • Nhấn ngắn tạo dấu chấm .
  • Nhấn dài tạo dấu gạch -
  • LCD hiển thị chuỗi Morse đã nhập

Sơ đồ tư duy:

Nut bam -> Do thoi gian nhan -> Phan loai . hoac - -> Hien thi LCD

Luồng đo thời gian nhấn nút để phân loại dấu chấm hoặc dấu gạch

Code mẫu:

#include <Wire.h>
#include <LiquidCrystal_I2C.h>

LiquidCrystal_I2C lcd(0x27, 16, 2);

const int btn = 3;
const unsigned long dotThreshold = 300;

String morse = "";
unsigned long pressStart = 0;
bool lastState = HIGH;

void setup() {
  pinMode(btn, INPUT_PULLUP);

  lcd.init();
  lcd.backlight();
  lcd.setCursor(0, 0);
  lcd.print("Morse Input");
  lcd.setCursor(0, 1);
  lcd.print("Press button");
}

void loop() {
  bool currentState = digitalRead(btn);

  if (lastState == HIGH && currentState == LOW) {
    pressStart = millis();
  }

  if (lastState == LOW && currentState == HIGH) {
    unsigned long duration = millis() - pressStart;

    if (duration < dotThreshold) {
      morse += ".";
    } else {
      morse += "-";
    }

    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print("Morse:");
    lcd.setCursor(0, 1);
    lcd.print(morse);
  }

  lastState = currentState;
}

Vì dùng INPUT_PULLUP, nút đang nhấn sẽ đọc là LOW. Hàm millis() giúp đo thời gian nhấn mà không làm chương trình bị đứng như khi dùng delay().

Lỗi thường gặp

Hiện tượngNguyên nhân có thể
Chỉ sáng nền xanhChưa gọi lcd.init() hoặc lcd.backlight(), sai địa chỉ I2C, tương phản chỉnh chưa đúng
Không hiện gìSai dây SDA/SCL, chưa cấp nguồn, sai địa chỉ I2C
Ô vuông đenLCD có nguồn nhưng chưa giao tiếp được với board
Chữ loạnSai thư viện, nhiễu nguồn, dây lỏng hoặc tốc độ I2C không ổn định
Không upload đượcChọn sai board, sai cổng COM hoặc board chưa vào chế độ nạp

Hướng phát triển

Sau khi hiển thị được dấu chấm và dấu gạch, có thể nâng cấp bài này theo nhiều hướng:

  • Thêm nút xóa ký tự cuối.
  • Thêm nút xác nhận để dịch Morse sang chữ cái.
  • Tự xuống dòng hoặc cuộn khi chuỗi dài hơn 16 ký tự.
  • Hiển thị thời gian nhấn để tinh chỉnh ngưỡng dotThreshold.

Đây là một bài nhỏ nhưng gom được nhiều kỹ năng quan trọng: đọc input, đo thời gian, xử lý trạng thái và hiển thị output.

IoT: LCD I2C và Morse Code | Bui Thuy Ngoc