Mục tiêu bài học
Sau bài này, bạn có thể:
- Kết nối đúng – an toàn – ổn định các loại màn hình phổ biến:
- OLED 0.96 inch (I2C)
- TFT 0.96 inch (SPI)
- TFT 1.3 inch (SPI)
- TFT 1.44 inch (SPI)
- TFT 1.54 inch (SPI – ST7789)
- Dùng mapping GPIO không xung đột với Camera / microSD / Boot
- Tái sử dụng code theo module:
oled096Setup(),oled096Loop()tft13Setup(),tft13Loop()
- Hiển thị:
- Thông tin IoTLabs
- Thời gian uptime dạng hh:mm:ss
- Áp dụng debug, hiển thị trạng thái, demo camera, Xiaozhi AI, thiết bị IoT .
Mapping GPIO chuẩn dùng trong bài (khuyến nghị)
| Chức năng | GPIO |
|---|---|
| I2C SDA | GPIO8 |
| I2C SCL | GPIO9 |
| SPI SCK | GPIO12 |
| SPI MOSI | GPIO11 |
| SPI MISO | GPIO13 (không bắt buộc với TFT) |
| TFT CS | GPIO10 |
| TFT DC | GPIO14 |
| TFT RST | GPIO15 |
| Backlight | 3V3 hoặc GPIO16 |
✅ Các GPIO trên không đụng camera / SD / USB / boot strap
Ví dụ 1 — Demo OLED 0.96 inch (I2C – SSD1306)
? Sơ đồ nối chân
| OLED | ESP32-S3 |
|---|---|
| VCC | 3V3 |
| GND | GND |
| SDA | GPIO8 |
| SCL | GPIO9 |
Thư viện cần dùng
Adafruit_GFX
Adafruit_SSD1306
Code: OLED 0.96 inch
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#define OLED_SDA 8
#define OLED_SCL 9
Adafruit_SSD1306 oled(128, 64, &Wire, -1);
unsigned long bootMillis;
void oled096Setup() {
Wire.begin(OLED_SDA, OLED_SCL);
if (!oled.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
Serial.println("OLED not found");
while (1);
}
oled.clearDisplay();
oled.setTextColor(SSD1306_WHITE);
oled.setTextSize(1);
bootMillis = millis();
}
void oled096WriteLine(int y, const String &text) {
oled.setCursor(0, y);
oled.print(text);
}
String formatUptime() {
unsigned long sec = (millis() - bootMillis) / 1000;
int h = sec / 3600;
int m = (sec % 3600) / 60;
int s = sec % 60;
char buf[12];
sprintf(buf, "%02d:%02d:%02d", h, m, s);
return String(buf);
}
void oled096Loop() {
oled.clearDisplay();
oled096WriteLine(0, "IoTLabs");
oled096WriteLine(12, "Nghien cuu - Sang tao");
oled096WriteLine(24, "Thu nghiem");
oled096WriteLine(36, "iotlabs.vn");
oled096WriteLine(52, formatUptime());
oled.display();
}
void setup() {
Serial.begin(115200);
oled096Setup();
}
void loop() {
oled096Loop();
delay(500);
}
Ví dụ 2 — TFT 0.96 / 1.3 / 1.44 inch (SPI – ST7735)
Áp dụng cho TFT 0.96 / 1.3 / 1.44 inch dùng ST7735
Sơ đồ nối chân
| TFT | ESP32-S3 |
|---|---|
| VCC | 3V3 |
| GND | GND |
| SCK | GPIO12 |
| MOSI | GPIO11 |
| CS | GPIO10 |
| DC | GPIO14 |
| RST | GPIO15 |
Thư viện
Adafruit_GFX
Adafruit_ST7735
Code: TFT 1.3 inch
#include <SPI.h>
#include <Adafruit_GFX.h>
#include <Adafruit_ST7735.h>
#define TFT_CS 10
#define TFT_DC 14
#define TFT_RST 15
Adafruit_ST7735 tft = Adafruit_ST7735(TFT_CS, TFT_DC, TFT_RST);
unsigned long tftBootMillis;
void tft13Setup() {
SPI.begin(12, -1, 11, TFT_CS);
tft.initR(INITR_BLACKTAB);
tft.setRotation(1);
tft.fillScreen(ST77XX_BLACK);
tftBootMillis = millis();
}
void tft13WriteLine(int y, const String &text, uint16_t color) {
tft.setCursor(0, y);
tft.setTextColor(color);
tft.setTextSize(1);
tft.print(text);
}
String tftUptime() {
unsigned long sec = (millis() - tftBootMillis) / 1000;
int h = sec / 3600;
int m = (sec % 3600) / 60;
int s = sec % 60;
char buf[12];
sprintf(buf, "%02d:%02d:%02d", h, m, s);
return String(buf);
}
void tft13Loop() {
tft.fillScreen(ST77XX_BLACK);
// Màu chủ đạo IoTLabs: #0e8578
uint16_t iotlabsGreen = tft.color565(14, 133, 120);
tft13WriteLine(0, "IoTLabs", iotlabsGreen);
tft13WriteLine(14, "Nghien cuu - Sang tao", ST77XX_WHITE);
tft13WriteLine(26, "Thu nghiem", ST77XX_WHITE);
tft13WriteLine(38, "iotlabs.vn", ST77XX_YELLOW);
tft13WriteLine(52, tftUptime(), ST77XX_CYAN);
}
void setup() {
Serial.begin(115200);
tft13Setup();
}
void loop() {
tft13Loop();
delay(500);
}
Ví dụ 3 — TFT 1.54 inch (ST7789 – rất phổ biến)
Thường dùng cho ESP32-S3, hiển thị đẹp, không cần MISO
Thư viện
Adafruit_ST7789
Mapping giống TFT SPI ở trên
Code: TFT 1.54 inch (ST7789)
#include <Adafruit_ST7789.h>
Adafruit_ST7789 tft154 = Adafruit_ST7789(TFT_CS, TFT_DC, TFT_RST);
void tft154Setup() {
SPI.begin(12, -1, 11, TFT_CS);
tft154.init(240, 240);
tft154.setRotation(2);
}
void tft154Display() {
tft154.fillScreen(ST77XX_BLACK);
tft154.setTextSize(1);
tft154.setTextColor(ST77XX_GREEN);
tft154.setCursor(20, 40);
tft154.println("IoTLabs");
tft154.setCursor(20, 60);
tft154.println("Nghien cuu - Sang tao");
tft154.setCursor(20, 80);
tft154.println("Thu nghiem");
tft154.setCursor(20, 100);
tft154.println("iotlabs.vn");
tft154.setCursor(20, 140);
tft154.println(formatUptime());
}
void setup() {
Serial.begin(115200);
tft154Setup();
}
void loop() {
tft154Loop();
delay(500);
}
⚠️ Lưu ý quan trọng
- ⚡ Nguồn yếu → màn hình chớp / reset
- ❌ Không dùng GPIO 0 / 19 / 20 / 21 cho SPI/I2C
- ❌ Không cấp 5V trực tiếp cho OLED/TFT
- ✅ Nếu dùng camera + TFT → ưu tiên OLED I2C
? Bài viết liên quan
- ← Bài 07 — Mapping UART/I2C/SPI an toàn
- → Bài 08 — MicroSD pinout & test đọc/ghi


