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.
Chuẩn bị phần cứng
- Màn hình OLED 0.96 inch
- Mạch lập trình ESP32 hoặc ESP8266
- Cảm biến nhiệt độ độ ẩm DHT11 hoặc DHT22
- Đ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:
Nếu bạn dùng mạch ESP8266, bạn kết nối sơ đồ phần cứng như sau:
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
- Thư viện Adafruit_SSD1306
- Thư viện Adafruit_GFX
Để 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
- Đi theo đường dẫn Sketch > Include Library > Manage Libraries
- Tìm kiếm từ khóa “DHT” và cài thư viện từ Adafruit
- 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:
>> 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:
- Arduino điều khiển động cơ bước 28BYJ-48 – Sử dụng ESP32 và ULN2003
- ESP32 điều khiển Relay qua Web Server – Điều khiển thiết bị AC
- Hướng dẫn LCD ESP32 (và cả ESP8266) trên Arduino IDE
IoTZone – Chuyên cung cấp thiết bị điện tử & tài liệu cho Makers
- Website: https://www.iotzone.vn/
- Fanpage: https://www.facebook.com/Iotzonemaker
- SDT: 0364174499
- Zalo: https://zalo.me/0364174499