IoTLabs

Nghiên cứu, Sáng tạo và Thử nghiệm

ESP32-S3-DevKitC N16R8 CAM: Bài 7.1 – Hướng kết nối với các loại màn hình thông dụng

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ăngGPIO
I2C SDAGPIO8
I2C SCLGPIO9
SPI SCKGPIO12
SPI MOSIGPIO11
SPI MISOGPIO13 (không bắt buộc với TFT)
TFT CSGPIO10
TFT DCGPIO14
TFT RSTGPIO15
Backlight3V3 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

OLEDESP32-S3
VCC3V3
GNDGND
SDAGPIO8
SCLGPIO9

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

TFTESP32-S3
VCC3V3
GNDGND
SCKGPIO12
MOSIGPIO11
CSGPIO10
DCGPIO14
RSTGPIO15

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