Code ESP32 OLED (cả ESP8266) – Hiển thị thông tin lên màn hình OLED

Trong tài liệu này, chúng ta sẽ cùng làm quen với ESP32 OLED – Hiển thị thông tin nhiệt độ, độ ẩm đọc được từ cảm biến DHT11 / DHT22 và hiển thị lên màn hình OLED, thông qua mạch lập trình ESP32 / ESP8266 và Arduino IDE.

Code ESP32 OLED (cả ESP8266) - Hiển thị thông tin lên màn hình OLED

Chuẩn bị phần cứng

  • Màn hình OLED 0.96 inch
Chuẩn bị DOLED cho dự án ESP32 OLED
  • Mạch lập trình ESP32 hoặc ESP8266
  • Cảm biến nhiệt độ độ ẩm DHT11 hoặc DHT22
Chuẩn bị DHT11 / DHT22 cho dự án ESP32 OLED
  • Điện trở 10k Ohm
  • Dây Jumper
  • Breadboard

Kết nối phần cứng

Màn hình OLED sẽ dùng giao tiếp I2C để gửi và nhận dữ liệu tới mạch ESP32 / ESP8266.

Nếu dùng ESP32, bạn có thể kết nối với chân I2C mặc định sau:

  • GPIO 22: SCL
  • GPIO 21: SDA

Nếu dùng ESP8266, chân I2C mặc định là:

  • GPIO 5 (D1): SCL
  • GPIO 4 (D2): SDA

Dưới đây là sơ đồ kết nối ESP32 OLED và DHT:

Kết nối phần cứng ESP32 OLED và DHT
Kết nối phần cứng ESP32 OLED và DHT

Nếu bạn dùng mạch ESP8266, bạn kết nối sơ đồ phần cứng như sau:

Kết nối phần cứng ESP8266 OLED và DHT
Kết nối phần cứng ESP8266 OLED và DHT

Cài đặt thư viện

Trước khi upload code mẫu về ESP32 OLED bên dưới, bạn cần cài đặt các thư viện để hệ thống có thể đọc giá trị từ cảm biến DHT và làm việc với màn hình OLED.

Thư viện làm việc với màn hình OLED

Để cài thư viện, bạn đi theo đường dẫn sau: Sketch Include Library > Manage Libraries, sau đó nhập tên thư viện cần cài đặt.

Sau đó, bạn tiến hành cài thư viện bình thường và khởi động lại Arduino IDE.

Thư viện làm việc với cảm biến DHT

  1. Đi theo đường dẫn Sketch Include Library > Manage Libraries
  2. Tìm kiếm từ khóa “DHT” và cài thư viện từ Adafruit
  3. Sau khi cài thư viện DHT, bạn gõ từ khóa “Adafruit Unified Sensor” và cài thư viện này.

Cài tiện ích ESP32 / ESP8266 trong Arduino IDE

Bạn cần cài sẵn tiện ích ESP32 / ESP8266 để Arduino IDE có thể làm việc được với các mạch này.

Code mẫu ESP32 OLED

Code mẫu dưới đây có thể được upload vào ESP32 hoặc cả ESP8266:

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

#define SCREEN_WIDTH 128 // Chiều rộng màn hình OLED theo pixel
#define SCREEN_HEIGHT 64 // Chiều cao màn hình OLED theo pixel

// Khai báo màn hình SSD1306 kết nối với I2C (chân SDA, SCL)
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);

#define DHTPIN 14     // Chân Digital kết nối với cảm biến DHT

// Khai báo loại cảm biến đang dùng
//#define DHTTYPE    DHT11     // DHT 11
#define DHTTYPE    DHT22     // DHT 22 (AM2302)
//#define DHTTYPE    DHT21     // DHT 21 (AM2301)

DHT dht(DHTPIN, DHTTYPE);

void setup() {
  Serial.begin(115200);

  dht.begin();

  if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
    Serial.println(F("SSD1306 allocation failed"));
    for(;;);
  }
  delay(2000);
  display.clearDisplay();
  display.setTextColor(WHITE);
}

void loop() {
  delay(5000);

  //Đọc giá trị nhiệt độ và độ ẩm
  float t = dht.readTemperature();
  float h = dht.readHumidity();
  if (isnan(h) || isnan(t)) {
    Serial.println("Failed to read from DHT sensor!");
  }
  // clear display
  display.clearDisplay();
  
  // hiển thị nhiệt độ
  display.setTextSize(1);
  display.setCursor(0,0);
  display.print("Temperature: ");
  display.setTextSize(2);
  display.setCursor(0,10);
  display.print(t);
  display.print(" ");
  display.setTextSize(1);
  display.cp437(true);
  display.write(167);
  display.setTextSize(2);
  display.print("C");
  
  // hiển thị độ ẩm
  display.setTextSize(1);
  display.setCursor(0, 35);
  display.print("Humidity: ");
  display.setTextSize(2);
  display.setCursor(0, 45);
  display.print(h);
  display.print(" %"); 
  
  display.display(); 
}

Giải thích code

Khai báo thư viện cần dùng trong chương trình:

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

Tạo đối tượng hiển thị, trong trường hợp này là hiển thị trên màn hình 128×64 pixel:

#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64

Khởi tạo đối tượng hiển thị với chiều rộng và chiều cao đã xác định, thông qua giao thức truyền thông I2C:

Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);

Tham số -1 ở đây có nghĩa là màn hình OLED đang dùng không có chân RESET. Nếu màn hình OLED của bạn có chân này, chúng phải được kết nối với GPIO. Khi đó, số chân GPIO sẽ thay thế cho số -1 trong code trên.

Tiếp theo, bạn xác định loại cảm biến DHT đang dùng:

  • Nếu bạn dùng DHT22, bạn không cần thay đổi gì trong code
  • Nếu bạn dùng cảm biến khác, bạn hãy thay thế chúng vào đoạn code dưới:
//#define DHTTYPE    DHT11     // DHT 11
#define DHTTYPE    DHT22     // DHT 22 (AM2302)
//#define DHTTYPE    DHT21     // DHT 21 (AM2301)

Khởi tạo đối tượng DHT với chân và loại hình được cấu hình trước đó:

DHT dht(DHTPIN, DHTTYPE);

Setup()

Tạo màn hình Serial Monitor để quan sát và gỡ lỗi khi cần:

Serial.begin(115200);

Khởi tạo cảm biến DHT:

dht.begin();

Khởi tạo OLED:

if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { // Address 0x3D for 128x64
  Serial.println(F("SSD1306 allocation failed"));
  for(;;);
}

Trong trường hợp này, địa chỉ của màn hình OLED mà IoTZone đang dùng là 0x3C. Nếu địa chỉ này không hoạt động với bạn, bạn có thể thử nhập lại địa chỉ khác để thử.

Thêm thời gian delay để hệ thống có thời gian tạo màn hình, xóa màn hình và setup màu văn bản thành màu trắng:

delay(2000);
display.clearDisplay();
display.setTextColor(WHITE)

Loop()

Đây là nơi chúng ta đọc giá trị nhiệt độ, độ ẩm từ cảm biến và cập nhật lền màn hình ESP32 OLED định kỳ.

Tạo các biến t và h để lưu giá trị nhiệt độ, độ ẩm:

float t = dht.readTemperature();
float h = dht.readHumidity();

Nếu không đọc được giá trị, hiển thị thông báo lỗi lên màn hình Serial:

if (isnan(h) || isnan(t)) {
  Serial.println("Failed to read from DHT sensor!");
}

Hiển thị nhiệt độ lên màn hình OLED ở vị trí nhất định:

 display.setTextSize(1);
  display.setCursor(0,0);
  display.print("Temperature: ");
  display.setTextSize(2);
  display.setCursor(0,10);
  display.print(t);
  display.print(" ");
  display.setTextSize(1);
  display.cp437(true);
  display.write(167);
  display.setTextSize(2);
  display.print("C");

Trong đoạn code trên, chúng ta dùng:

  • SetTextSize(): Chọn cỡ chữ
  • setCursor(): Nơi bắt đầu hiển thị chữ
  • print(): Câu lệnh giúp viết một thông tin bất kỳ lên màn hình ESP32 OLED

Để in giá trị nhiệt độ và độ ẩm, chúng ta chỉ cần truyền các biến của chúng vào in() như sau:

display.print(t);

Dòng chữ nhiệt độ được hiển thị với kích cỡ chữ là 1, số giá trị thực tế đo được hiển thị với kích cỡ 2.

Dòng code dưới đây giúp hiển thị ký hiệu º:

display.cp437(true);
display.write(167);

Tương tự, ta hiển thị độ ẩm lên màn hình OLED:

 display.setTextSize(1);
  display.setCursor(0,0);
  display.print("Temperature: ");
  display.setTextSize(2);
  display.setCursor(0,10);
  display.print(t);
  display.print(" ");
  display.setTextSize(1);
  display.cp437(true);
  display.write(167);
  display.setTextSize(2);
  display.print("C");

Đừng quên dòng code này ở cuối, để màn hình ESP32 OLED có thể hiển thị thông tin nhé:

display.display(); 

Demo

Hình dưới đây minh họa kết quả của dự án ESP32 OLED này, trên màn hình hiển thị giá trị nhiệt độ và độ ẩm:

Code ESP32 OLED (cả ESP8266) - Hiển thị thông tin lên màn hình OLED

>> Bài viết liên quan: Hướng dẫn màn hình OLED Arduino – Vẽ hình ảnh, đường thẳng

Sự cố thường gặp và cách xử lý:

Nếu bạn gặp lỗi “SSD1306 allocation failed” hoặc OLED không hiển thị các thông tin gì, có thể do một số nguyên nhân sau:

Sai địa chỉ I2C

Như trong code mẫu ESP32 OLED trên, mình sử dụng chân 0x3C cho màn hình. Tuy nhiên, của bạn có thể sẽ khác. Bạn có thể kiểm tra địa chỉ này bằng dòng code sau:

#include <Wire.h>
 
void setup() {
  Wire.begin();
  Serial.begin(115200);
  Serial.println("\nI2C Scanner");
}
 
void loop() {
  byte error, address;
  int nDevices;
  Serial.println("Scanning...");
  nDevices = 0;
  for(address = 1; address < 127; address++ ) {
    Wire.beginTransmission(address);
    error = Wire.endTransmission();
    if (error == 0) {
      Serial.print("I2C device found at address 0x");
      if (address<16) {
        Serial.print("0");
      }
      Serial.println(address,HEX);
      nDevices++;
    }
    else if (error==4) {
      Serial.print("Unknow error at address 0x");
      if (address<16) {
        Serial.print("0");
      }
      Serial.println(address,HEX);
    }    
  }
  if (nDevices == 0) {
    Serial.println("No I2C devices found\n");
  }
  else {
    Serial.println("done\n");
  }
  delay(5000);          
}
1

Kết nối SDA và SCL chưa đúng

Bạn hãy kiểm tra lại sơ đồ kết nối, và đảm bảo đã nối đúng chân SDA và SCL của màn hình OLED với mạch ESP32 / ESP8266 nhé!

Lời kết

Trên đây là hướng dẫn chi tiết về dự án ESP32 OLED, chúc các bạn thành công! Bạn có thể thích một số hướng dẫn dự án khác trên Web IoTZone:

IoTZone – Chuyên cung cấp thiết bị điện tử & tài liệu cho Makers

Trả lời

Email của bạn sẽ không được hiển thị công khai. Các trường bắt buộc được đánh dấu *