Hướng dẫn dùng màn hình OLED SSD1306 với ESP8266

Hướng dẫn nối OLED SSD1306 với ESP8266, quét địa chỉ I2C, cài thư viện và hiển thị thời gian bằng mã Arduino mẫu.

Màn hình OLED 0,96 inch giao tiếp I2C thường dùng bộ điều khiển SSD1306 và độ phân giải 128 × 64 pixel. Bài viết sử dụng ESP8266 NodeMCU, thư viện Adafruit SSD1306 và địa chỉ I2C được xác nhận bằng chương trình quét trước khi chạy ví dụ.

Màn hình OLED SSD1306 128x64 kết nối với ESP8266
Màn hình OLED I2C 0,96 inch dùng với ESP8266.

1. Phần cứng và đấu nối

Đấu nối OLED I2C với ESP8266 NodeMCU
OLED I2C ESP8266 NodeMCU Ghi chú
GND GND Nối mass chung.
VCC 3V3 Dùng 3,3 V nếu module cho phép; kiểm tra thông số module trước khi cấp nguồn.
SDA D2 / GPIO4 D2 là nhãn trên bo NodeMCU, GPIO4 là số dùng trong code.
SCL D1 / GPIO5 D1 là nhãn trên bo NodeMCU, GPIO5 là số dùng trong code.

Không suy ra điện áp cấp chỉ từ hình dáng module. Một số board có mạch hỗ trợ 5 V, nhưng GPIO của ESP8266 làm việc ở mức 3,3 V. Nếu màn hình hoặc điện trở kéo lên I2C dùng 5 V, cần giải pháp chuyển mức phù hợp.

2. Quét địa chỉ I2C

Địa chỉ thường gặp là 0x3C hoặc 0x3D. Chạy đoạn quét dưới đây trước để dùng đúng địa chỉ:

#include <Wire.h>

void setup() {
  Serial.begin(115200);
  Wire.begin(4, 5);  // SDA = GPIO4, SCL = GPIO5
  for (uint8_t address = 1; address < 127; ++address) {
    Wire.beginTransmission(address);
    if (Wire.endTransmission() == 0) {
      Serial.printf("Found I2C device: 0x%02X
", static_cast<unsigned>(address));
    }
  }
}

void loop() {}

Nếu không tìm thấy thiết bị, kiểm tra nguồn, GND, SDA/SCL và dây nối. Nếu địa chỉ đúng nhưng hình ảnh sai hoặc không hiển thị, xác nhận controller thực tế là SSD1306 hay SH1106 để chọn đúng thư viện.

3. Cài thư viện và chọn bo

  1. Trong Arduino IDE, cài Adafruit SSD1306 và Adafruit GFX Library bằng Library Manager.
  2. Chọn đúng bo đang dùng, ví dụ NodeMCU 1.0 (ESP-12E Module) hoặc profile Wemos D1 mini tương ứng.
  3. Chọn đúng cổng COM và kiểm tra Serial Monitor ở 115200 baud.

4. Chương trình hiển thị thời gian hoạt động

#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

constexpr uint8_t SDA_PIN = 4;
constexpr uint8_t SCL_PIN = 5;
constexpr uint8_t OLED_ADDRESS = 0x3C;  // Đổi theo địa chỉ vừa quét
constexpr int SCREEN_WIDTH = 128;
constexpr int SCREEN_HEIGHT = 64;

Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);
uint32_t previousMs = 0;
uint64_t uptimeMs = 0;
uint64_t lastShownSecond = UINT64_MAX;

void setup() {
  Serial.begin(115200);
  Wire.begin(SDA_PIN, SCL_PIN);

  if (!display.begin(SSD1306_SWITCHCAPVCC, OLED_ADDRESS)) {
    Serial.println("Khong khoi tao duoc OLED");
    while (true) { delay(1000); }
  }

  display.clearDisplay();
  display.setTextColor(SSD1306_WHITE);
  display.setTextSize(1);
  previousMs = millis();
}

void loop() {
  const uint32_t now = millis();
  uptimeMs += static_cast<uint32_t>(now - previousMs);
  previousMs = now;

  const uint64_t totalSeconds = uptimeMs / 1000ULL;
  if (totalSeconds == lastShownSecond) {
    delay(20);
    return;
  }
  lastShownSecond = totalSeconds;

  const uint32_t days = totalSeconds / 86400ULL;
  const uint8_t hours = (totalSeconds / 3600ULL) % 24;
  const uint8_t minutes = (totalSeconds / 60ULL) % 60;
  const uint8_t seconds = totalSeconds % 60;

  display.clearDisplay();
  display.setCursor(0, 0);
  display.println("ESP8266 uptime");
  display.printf("Day: %lu
", static_cast<unsigned long>(days));
  display.printf(
    "%02u:%02u:%02u",
    static_cast<unsigned>(hours),
    static_cast<unsigned>(minutes),
    static_cast<unsigned>(seconds)
  );
  display.display();
}

Mã cộng dồn chênh lệch của millis() bằng số học không dấu, vì vậy vẫn xử lý được thời điểm bộ đếm 32-bit quay vòng. Màn hình chỉ cập nhật khi số giây thay đổi để giảm nhấp nháy và lưu lượng I2C.

5. Xử lý sự cố

  • Màn hình đen: quét I2C và kiểm tra địa chỉ. Ví dụ dùng reset pin -1; nếu module có chân RST riêng, hãy nối chân đó và truyền GPIO thật vào constructor.
  • Ký tự hoặc hình sai: kiểm tra controller SSD1306/SH1106 và kích thước 128 × 64 hay 128 × 32.
  • ESP8266 reset: kiểm tra nguồn, dây nối và tránh vòng lặp lỗi quá chặt; ví dụ trên có delay khi khởi tạo thất bại.
  • Không biên dịch: cập nhật đồng bộ Adafruit GFX và Adafruit SSD1306, sau đó kiểm tra đúng profile bo.

Xem thêm bài LCD 1602 I2C với Arduino Uno và ESP32 điều khiển relay 4 kênh.


Tin tức liên quan

Hướng dẫn ESP-NOW trên ESP32: truyền dữ liệu giữa hai mạch không cần router Wi-Fi
Hướng dẫn ESP-NOW trên ESP32: truyền dữ liệu giữa hai mạch không cần router Wi-Fi

Hướng dẫn dùng ESP-NOW để hai mạch ESP32 truyền dữ liệu trực tiếp không cần router: xem địa chỉ MAC, chương trình gửi, chương trình nhận, đọc RSSI và xử lý lỗi thường gặp.

Hướng dẫn dùng ngắt GPIO trên ESP32: đọc nút nhấn, chống dội và đếm xung
Hướng dẫn dùng ngắt GPIO trên ESP32: đọc nút nhấn, chống dội và đếm xung

Hướng dẫn dùng ngắt GPIO trên ESP32 với Arduino IDE: attachInterrupt, các kiểu kích ngắt, chống dội nút nhấn, đếm xung đo tần số và quy tắc viết hàm ngắt an toàn.

Hướng dẫn bắt đầu MicroPython trên ESP32 Lite với Thonny
Hướng dẫn bắt đầu MicroPython trên ESP32 Lite với Thonny

Hướng dẫn cài driver, cài Thonny và nạp firmware MicroPython cho mạch ESP32 Lite, dùng REPL, nháy LED, lưu main.py, đọc nút nhấn, quét I2C và xử lý lỗi thường gặp.

ESP32 gửi cảnh báo Telegram, nhận lệnh bật tắt relay: tạo bot, lấy chat id, không cần thư viện bot
ESP32 gửi cảnh báo Telegram, nhận lệnh bật tắt relay: tạo bot, lấy chat id, không cần thư viện bot

Tạo bot Telegram, lấy token và chat id, cho ESP32 gửi cảnh báo cửa mở, báo có điện lại và nhận lệnh /bat, /tat relay bằng HTTPClient và ArduinoJson.

Hướng dẫn dùng mạch tạo trễ NE555 có relay: đấu dây và chỉnh thời gian trễ
Hướng dẫn dùng mạch tạo trễ NE555 có relay: đấu dây và chỉnh thời gian trễ

Hướng dẫn dùng mạch tạo trễ NE555 có relay bản 5 V và 12 V: nguyên lý tạo trễ, ý nghĩa các cọc VCC, GND, COM, CK, CB, cách chỉnh thời gian trễ, sơ đồ đấu dây và xử lý lỗi thường gặp.

Xe tránh vật cản với ESP32: cảm biến siêu âm HC-SR04 trên servo quét, tự chọn đường
Xe tránh vật cản với ESP32: cảm biến siêu âm HC-SR04 trên servo quét, tự chọn đường

Làm xe robot tự tránh vật cản với ESP32: cảm biến siêu âm HC-SR04 gắn trên servo quét trái phải, cầu phân áp cho chân ECHO, thuật toán chọn đường, lưu đồ và thí nghiệm STEM.

Dải LED WS2812B với ESP32: điều khiển từng bóng bằng RMT không cần thư viện, tính dòng và chọn nguồn
Dải LED WS2812B với ESP32: điều khiển từng bóng bằng RMT không cần thư viện, tính dòng và chọn nguồn

Bên trong bóng WS2812B, tín hiệu một dây 24 bit GRB, cách tính dòng để chọn nguồn, nối dải LED với ESP32 và tạo tín hiệu bằng bộ RMT không cần thư viện, kèm ba hiệu ứng.

Hướng dẫn điều khiển relay bằng điện thoại qua Bluetooth với ESP32
Hướng dẫn điều khiển relay bằng điện thoại qua Bluetooth với ESP32

Hướng dẫn dùng Bluetooth Classic của ESP32 trên Arduino IDE: ghép đôi với điện thoại Android, gửi nhận chữ bằng BluetoothSerial và điều khiển module relay bằng lệnh ON, OFF.


Bình luận
Đã thêm vào giỏ hàng