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 SSD1306Adafruit 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 UnoESP32 điều khiển relay 4 kênh.


Tin tức liên quan

Hướng dẫn sử dụng màn hình LCD 1602 I2C với Arduino Uno
Hướng dẫn sử dụng màn hình LCD 1602 I2C với Arduino Uno

987 Lượt xem

Hướng dẫn nối màn hình LCD 1602 I2C với Arduino Uno, cài thư viện LiquidCrystal_I2C, chạy code hiển thị và quét địa chỉ I2C 0x27/0x3F.

Hướng dẫn ESP32 điều khiển module relay 4 kênh an toàn
Hướng dẫn ESP32 điều khiển module relay 4 kênh an toàn

3844 Lượt xem

Hướng dẫn ESP32 điều khiển relay 4 kênh: chọn GPIO an toàn, cấp nguồn 5 V phù hợp, xác định active LOW và lưu ý khi đóng cắt tải.


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