OLED 0.96 hay 1.3 inch, SSD1306 hay SH1106: chọn màn hình nào và dùng thư viện nào cho đúng
- 1. OLED 0,96 inch và 1,3 inch khác nhau thế nào?
- 2. Nên chọn màn nào?
- 3. SSD1306 và SH1106 khác nhau ở đâu?
- 4. Chương trình kiểm tra màn dùng chip nào
- 4.1. Nối dây
- 4.2. Cài thư viện
- 4.3. Chạy bản SSD1306 trước
- 4.4. Nếu màn nhiễu hoặc không sáng, chạy bản SH1106
- 5. Đổi chương trình từ SSD1306 sang SH1106
- 6. Lỗi thường gặp
- 7. Xem thêm
So sánh OLED 0,96 inch và 1,3 inch, SSD1306 khác SH1106 ở đâu, chương trình kiểm tra màn dùng chip nào, hiện tượng khi chọn nhầm thư viện và cách đổi chương trình từ SSD1306 sang SH1106.
Màn hình OLED I2C 128 × 64 điểm ảnh có hai cỡ thông dụng: 0,96 inch và 1,3 inch. Nhìn bên ngoài gần giống nhau, cùng bốn chân, nhưng thường dùng hai chip điều khiển khác nhau là SSD1306 và SH1106. Chọn nhầm thư viện thì màn đầy chấm nhiễu hoặc không sáng. Bài viết so sánh hai cỡ màn hình để chọn mua cho đúng nhu cầu, giải thích SSD1306 khác SH1106 ở đâu, và đưa chương trình kiểm tra giúp biết ngay màn đang có dùng chip nào.
1. OLED 0,96 inch và 1,3 inch khác nhau thế nào?

| Đặc điểm | OLED 0,96 inch | OLED 1,3 inch |
|---|---|---|
| Độ phân giải | 128 × 64 | 128 × 64 |
| Vùng hiển thị | Khoảng 21,7 × 10,9 mm | Khoảng 29,4 × 14,7 mm |
| Kích thước một điểm ảnh | Khoảng 0,17 mm | Khoảng 0,23 mm |
| Chữ cỡ nhỏ nhất (cao 7 điểm ảnh) | Khoảng 1,2 mm | Khoảng 1,6 mm |
| Chip điều khiển thường gặp | SSD1306 | SH1106 (có lô dùng SSD1306) |
| Màu | Trắng, xanh dương, hoặc hai màu (16 hàng trên vàng, còn lại xanh) | Trắng, xanh dương |
| Giao tiếp | I2C, 4 chân | I2C, 4 chân |
| Điện áp cấp | 3,3–5 V | 3,3–5 V |
| Địa chỉ I2C | 0x3C (in trên mạch có thể là 0x78) | 0x3C (in trên mạch có thể là 0x78) |
Hai màn có cùng số điểm ảnh nên vẽ được đúng những nội dung như nhau. Màn 1,3 inch chỉ có điểm ảnh to hơn khoảng 35 %, chữ dễ đọc hơn từ xa. Số 0x78 in trên một số module chính là địa chỉ 0x3C viết dạng 8 bit; trong chương trình Arduino luôn dùng 0x3C.
2. Nên chọn màn nào?
- OLED 0,96 inch SSD1306: nhỏ gọn, rẻ, có nhiều bài hướng dẫn nhất. Hợp với đồng hồ, máy đo cầm tay, hiển thị trạng thái thiết bị. Bản hai màu có dải vàng ở trên để làm thanh tiêu đề. Shop có bản kèm 4 nút nhấn để làm menu.
- OLED 1,3 inch: chữ to, dễ đọc hơn khi gắn lên mặt hộp, tủ điện, thiết bị cho người lớn tuổi dùng. Cần nhớ chọn đúng thư viện SH1106.
- Cần hiển thị nhiều chữ hơn, đọc được ngoài nắng: cân nhắc màn LCD 1602, 2004 có đèn nền.
- Muốn đỡ nối dây: mạch ESP32 có OLED 0,96 inch hàn sẵn.
3. SSD1306 và SH1106 khác nhau ở đâu?

Cả hai chip lưu hình trong bộ nhớ chia 8 trang, mỗi trang 8 hàng điểm ảnh. Khác biệt nằm ở ba điểm:
- Số cột bộ nhớ: SSD1306 có đúng 128 cột. SH1106 có 132 cột, tấm màn 128 cột chỉ hiện từ cột 2 đến cột 129. Thư viện cho SH1106 phải ghi lệch đi 2 cột.
- Cách ghi: SSD1306 nhận lệnh đặt vùng ghi theo chiều ngang, nên thư viện gửi cả khung hình 1024 byte một lần. SH1106 không có lệnh này, chỉ ghi được từng trang.
- Nguồn cho tấm màn: SSD1306 cần lệnh bật bơm điện áp bên trong chip mới sáng. SH1106 dùng lệnh khác để bật bộ đổi điện áp.
Vì vậy mỗi chip cần thư viện riêng: Adafruit SSD1306 cho SSD1306 và Adafruit SH110X (lớp Adafruit_SH1106G) cho SH1106. Cả hai đều dùng chung Adafruit GFX nên các lệnh vẽ chữ, vẽ hình giống hệt nhau, chỉ khác dòng khai báo và dòng khởi tạo.
4. Chương trình kiểm tra màn dùng chip nào
Mô tả bán hàng đôi khi ghi chung chung "SSD1306 hoặc tương đương". Cách chắc nhất là chạy thử cả hai thư viện: thư viện đúng sẽ vẽ được khung bao sát đủ 4 cạnh và chữ rõ nét.
4.1. Nối dây

| Chân OLED | ESP32 DevKit V1 |
|---|---|
| GND | GND |
| VCC | 3V3 |
| SCL | D22 (GPIO22) |
| SDA | D21 (GPIO21) |
Module OLED có hai kiểu thứ tự chân: GND VCC SCL SDA và VCC GND SCL SDA. Luôn nối theo chữ in trên module. Đảo nhầm GND và VCC có thể làm hỏng màn.
4.2. Cài thư viện
Trong Arduino IDE, mở Tools › Manage Libraries, tìm và cài Adafruit SSD1306 và Adafruit SH110X; khi được hỏi cài thêm thư viện đi kèm (Adafruit GFX Library, Adafruit BusIO), chọn Install All. Bài dùng gói esp32 phiên bản 3.3.10, Adafruit SSD1306 2.5.17, Adafruit SH110X 2.1.14, Adafruit GFX Library 1.12.6 và Adafruit BusIO 1.17.4.
4.3. Chạy bản SSD1306 trước
// PYWORLD.VN - Kiểm tra màn hình OLED 128x64 I2C bằng thư viện Adafruit SSD1306 (thường là OLED 0.96 inch)
// PYWORLD.VN - Vẽ khung bao 4 cạnh: thấy đủ 4 cạnh, chữ rõ là màn hình dùng chip SSD1306
// PYWORLD.VN - ESP32 DevKit V1: SDA = GPIO21, SCL = GPIO22, địa chỉ I2C 0x3C
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
const int SDA_PIN = 21;
const int SCL_PIN = 22;
const uint8_t DIA_CHI_OLED = 0x3C; // một số module in 0x78: đó là cùng địa chỉ viết dạng 8 bit
Adafruit_SSD1306 manHinh(128, 64, &Wire, -1); // -1: module 4 chân không có chân reset riêng
void setup() {
Serial.begin(115200);
Wire.begin(SDA_PIN, SCL_PIN);
// Hỏi thử địa chỉ I2C trước: hàm begin() của thư viện SSD1306 không tự phát hiện màn chưa nối
Wire.beginTransmission(DIA_CHI_OLED);
if (Wire.endTransmission() != 0) {
Serial.println("Khong thay thiet bi o dia chi 0x3C: kiem tra day SDA, SCL, nguon, hoac thu 0x3D");
while (true) delay(500);
}
if (!manHinh.begin(SSD1306_SWITCHCAPVCC, DIA_CHI_OLED)) { // bật bơm điện áp trong chip để màn sáng
Serial.println("Khong du bo nho de khoi tao OLED SSD1306");
while (true) delay(500);
}
manHinh.clearDisplay();
manHinh.setTextColor(SSD1306_WHITE);
manHinh.drawRect(0, 0, 128, 64, SSD1306_WHITE); // khung bao sát 4 cạnh màn hình
manHinh.setTextSize(2);
manHinh.setCursor(4, 4);
manHinh.print("PYWORLD");
manHinh.setTextSize(1);
manHinh.setCursor(4, 26);
manHinh.print("Chip: SSD1306");
manHinh.setCursor(4, 38);
manHinh.print("Thay du 4 canh");
manHinh.setCursor(4, 50);
manHinh.print("la dung thu vien");
manHinh.display();
Serial.println("Da ve khung kiem tra bang thu vien SSD1306");
}
void loop() {
}
4.4. Nếu màn nhiễu hoặc không sáng, chạy bản SH1106
// PYWORLD.VN - Kiểm tra màn hình OLED 128x64 I2C bằng thư viện Adafruit SH110X (thường là OLED 1.3 inch)
// PYWORLD.VN - Cùng hình vẽ với bản SSD1306: thấy đủ 4 cạnh, chữ rõ là màn hình dùng chip SH1106
// PYWORLD.VN - ESP32 DevKit V1: SDA = GPIO21, SCL = GPIO22, địa chỉ I2C 0x3C
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SH110X.h>
const int SDA_PIN = 21;
const int SCL_PIN = 22;
const uint8_t DIA_CHI_OLED = 0x3C; // một số module in 0x78: đó là cùng địa chỉ viết dạng 8 bit
Adafruit_SH1106G manHinh(128, 64, &Wire, -1); // -1: module 4 chân không có chân reset riêng
void setup() {
Serial.begin(115200);
Wire.begin(SDA_PIN, SCL_PIN);
// Hỏi thử địa chỉ I2C trước: hàm begin() của thư viện SSD1306 không tự phát hiện màn chưa nối
Wire.beginTransmission(DIA_CHI_OLED);
if (Wire.endTransmission() != 0) {
Serial.println("Khong thay thiet bi o dia chi 0x3C: kiem tra day SDA, SCL, nguon, hoac thu 0x3D");
while (true) delay(500);
}
if (!manHinh.begin(DIA_CHI_OLED, true)) {
Serial.println("Khong khoi tao duoc OLED SH1106");
while (true) delay(500);
}
manHinh.clearDisplay();
manHinh.setTextColor(SH110X_WHITE);
manHinh.drawRect(0, 0, 128, 64, SH110X_WHITE); // khung bao sát 4 cạnh màn hình
manHinh.setTextSize(2);
manHinh.setCursor(4, 4);
manHinh.print("PYWORLD");
manHinh.setTextSize(1);
manHinh.setCursor(4, 26);
manHinh.print("Chip: SH1106");
manHinh.setCursor(4, 38);
manHinh.print("Thay du 4 canh");
manHinh.setCursor(4, 50);
manHinh.print("la dung thu vien");
manHinh.display();
Serial.println("Da ve khung kiem tra bang thu vien SH110X");
}
void loop() {
}

| Màn hiển thị | Kết luận |
|---|---|
| Đủ khung 4 cạnh, chữ rõ | Thư viện đang dùng là đúng |
| Đầy chấm nhiễu như muối tiêu, chỉ một dải trên cùng thay đổi | Màn dùng SH1106 mà chương trình dùng thư viện SSD1306 |
| Hoàn toàn không sáng dù Serial báo đã vẽ | Màn dùng SSD1306 mà chương trình dùng thư viện SH110X (không bật bơm điện áp) |
| Sáng nhưng hình lệch 2 cột, mép phải bị đẩy sang mép trái | Màn SSD1306 có nguồn riêng chạy bằng thư viện SH110X |
| Serial báo không thấy thiết bị ở 0x3C | Sai dây, thiếu nguồn, hoặc địa chỉ là 0x3D |
Hàm begin() của thư viện SSD1306 chỉ báo lỗi khi thiếu bộ nhớ, không tự phát hiện màn chưa được nối. Vì vậy cả hai chương trình đều hỏi thử địa chỉ I2C trước bằng Wire.beginTransmission(). Muốn tìm địa chỉ của mọi thiết bị trên dây I2C, dùng chương trình quét trong bài giao tiếp I2C trên ESP32.
5. Đổi chương trình từ SSD1306 sang SH1106
Một chương trình viết cho màn 0,96 inch muốn chạy trên màn 1,3 inch SH1106 chỉ cần sửa ba chỗ:
| Chỗ cần sửa | SSD1306 | SH1106 |
|---|---|---|
| Dòng include | #include <Adafruit_SSD1306.h> | #include <Adafruit_SH110X.h> |
| Khai báo | Adafruit_SSD1306 manHinh(128, 64, &Wire, -1); | Adafruit_SH1106G manHinh(128, 64, &Wire, -1); |
| Khởi tạo | manHinh.begin(SSD1306_SWITCHCAPVCC, 0x3C) | manHinh.begin(0x3C, true) |
| Màu | SSD1306_WHITE | SH110X_WHITE |
Các lệnh vẽ như setCursor, print, drawRect, display giữ nguyên.
6. Lỗi thường gặp
| Hiện tượng | Nguyên nhân | Cách xử lý |
|---|---|---|
| Màn đầy chấm nhiễu | Màn SH1106 chạy thư viện SSD1306 | Đổi sang thư viện Adafruit SH110X |
| Màn không sáng, Serial vẫn báo đã vẽ | Màn SSD1306 chạy thư viện SH110X; quên gọi display() | Đổi sang thư viện SSD1306; gọi display() sau khi vẽ |
| Không thấy thiết bị ở 0x3C | Sai thứ tự chân, đảo SDA và SCL, địa chỉ 0x3D | Nối theo chữ in trên module, thử địa chỉ 0x3D |
| Chữ dài tự xuống dòng | Chế độ tự xuống dòng đang bật | Gọi setTextWrap(false) |
| Màn mờ dần theo thời gian | Hiển thị một hình tĩnh, độ sáng cao nhiều tháng liền | Giảm độ tương phản, tắt màn khi không dùng, đổi vị trí nội dung |
| Hình nhấp nháy khi vẽ liên tục | Xóa màn rồi vẽ lại mỗi vòng lặp quá nhanh | Chỉ gọi display() một lần sau khi vẽ xong một khung |
7. Xem thêm
- Hướng dẫn dùng màn hình OLED 1,3 inch SH1106 với ESP32.
- Hướng dẫn dùng OLED 0,96 inch SSD1306 với Arduino Nano và với ESP8266.
- Làm đồng hồ Internet với ESP32, NTP và OLED 0,96 inch.
- Các màn hình hiển thị của PYWORLD: OLED 0,96 inch, 1,3 inch, LCD 1602, 2004 I2C.
- Bài cùng loạt: sơ đồ chân ESP32 30 chân và 38 chân, chọn mạch ESP32 phù hợp.
Xem thêm