Hướng dẫn OLED ESP32 chi tiết bằng Arduino IDE

Bài viết sẽ hướng dẫn bạn cách dùng màn hình OLED ESP32, loại 0,96 inch bằng phần mềm Arduino IDE. Chúng ta cùng tìm hiểu cách hiển thị văn bản, chọn phông chữ khác nhau, vẽ hình hoặc hiển thị các hình ảnh dạng bitmap nhé!

Giới thiệu về màn hình OLED 0,96 inch

Loại mà mình dùng trong bài hướng dẫn này là loại SSD1306, đây là loại đơn sắc với kích cỡ là 128×64 pixel như hình dưới:

Giới thiệu màn hình OLED ESP32

Các loại màn hình OLED này thường không cần đèn nền. Trong môi trường tối thì chúng ta sẽ thấy ký tự hiển thị rất đẹp và rõ. 

Các pixel của màn hình OLED chỉ tiêu thụ năng lượng khi bật, do đó loại màn hình này tiêu tốn khá ít năng lượng so với các loại màn hình khác. 

OLED ESP32 sử dụng 4 chân giao tiếp và hỗ trợ giao tiếp I2C với bất kỳ loại vi điều khiển nào. Nhiều loại màn hình OLED đặc biệt có kèm theo chân Reset hoặc bộ phận bổ sung hỗ trợ giao tiếp SPI.

Kết nối

Như đã trình bày, màn hình OLED ESP32 sử dụng giao thức truyền thông I2C nên việc kết nối dây với vi mạch điều khiển ESP32 cũng khá đơn giản:

  • Chân VIN trên màn hình OLED -> Chân 3.3V của ESP32
  • Chân GND -> GND
  • Chân SCL -> Chân GPIO 22
  • Chân SDA -> Chân GPIO 21

Bạn có thể tham khảo sơ đồ kết nối màn hình OLED ESP32 qua hình sau:

Sơ đồ kết nối màn hình OLED EPS32
Sơ đồ kết nối màn hình OLED EPS32

Trong hướng dẫn này, IoTZone đang sử dụng chân kết nối là GPIO 22 và GPIO 21. Trong trường hợp bạn dùng màn hình OLED hỗ trợ SPI, bạn có thể kết nối theo sơ đồ sau:

  • Chân CLK -> GPIO 18
  • MISO -> GPIO 19
  • MOSI -> GPIO 23
  • CS -> GPIO 5

Cài đặt thư viện OLED SSD1306

Hiện nay có nhiều thư viện khác nhau để điều khiển màn hình OLED. Trong bài này, mình sẽ sử dụng thư viện Adafbean_SSD1306 và Adafbean_GFX.

Bạn có thể mở Arduino IDE, truy cập vào Sketch > Include Library > Manage Libraries để tải các thư viện này nhé! Sau khi cài xong, bạn hãy khởi động lại Arduino IDE để sử dụng.

Dùng code mẫu có sẵn trong thư viện điều khiển OLED ESP32

Sau khi cài xong thư viện, trong thư viện sẽ có sẵn một số đoạn code để bạn dùng thử với màn hình OLED, kiểm tra xem chúng có hoạt động ổn định không.

Để sử dụng, bạn truy cập vào File > Examples > Adafruit SSD1306 và chọn loại màn hình bạn đang dùng, ví dụ:

Cách mở code có sẵn điều khiển màn hình OLED ESP32
Cách mở code có sẵn điều khiển màn hình OLED ESP32

Đoạn code sau sẽ hiện ra:

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

#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels

// Declaration for an SSD1306 display connected to I2C (SDA, SCL pins)
#define OLED_RESET     -1 // Reset pin # (or -1 if sharing Arduino reset pin)
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);

#define NUMFLAKES     10 // Number of snowflakes in the animation example

#define LOGO_HEIGHT   16
#define LOGO_WIDTH    16
static const unsigned char PROGMEM logo_bmp[] =
{ B00000000, B11000000,
  B00000001, B11000000,
  B00000001, B11000000,
  B00000011, B11100000,
  B11110011, B11100000,
  B11111110, B11111000,
  B01111110, B11111111,
  B00110011, B10011111,
  B00011111, B11111100,
  B00001101, B01110000,
  B00011011, B10100000,
  B00111111, B11100000,
  B00111111, B11110000,
  B01111100, B11110000,
  B01110000, B01110000,
  B00000000, B00110000 };

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

  // SSD1306_SWITCHCAPVCC = generate display voltage from 3.3V internally
  if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { 
    Serial.println(F("SSD1306 allocation failed"));
    for(;;); // Don't proceed, loop forever
  }

  // Show initial display buffer contents on the screen --
  // the library initializes this with an Adafruit splash screen.
  display.display();
  delay(2000); // Pause for 2 seconds

  // Clear the buffer
  display.clearDisplay();

  // Draw a single pixel in white
  display.drawPixel(10, 10, WHITE);

  // Show the display buffer on the screen. You MUST call display() after
  // drawing commands to make them visible on screen!
  display.display();
  delay(2000);
  // display.display() is NOT necessary after every single drawing command,
  // unless that's what you want...rather, you can batch up a bunch of
  // drawing operations and then update the screen all at once by calling
  // display.display(). These examples demonstrate both approaches...

  testdrawline();      // Draw many lines

  testdrawrect();      // Draw rectangles (outlines)

  testfillrect();      // Draw rectangles (filled)

  testdrawcircle();    // Draw circles (outlines)

  testfillcircle();    // Draw circles (filled)

  testdrawroundrect(); // Draw rounded rectangles (outlines)

  testfillroundrect(); // Draw rounded rectangles (filled)

  testdrawtriangle();  // Draw triangles (outlines)

  testfilltriangle();  // Draw triangles (filled)

  testdrawchar();      // Draw characters of the default font

  testdrawstyles();    // Draw 'stylized' characters

  testscrolltext();    // Draw scrolling text

  testdrawbitmap();    // Draw a small bitmap image

  // Invert and restore display, pausing in-between
  display.invertDisplay(true);
  delay(1000);
  display.invertDisplay(false);
  delay(1000);

  testanimate(logo_bmp, LOGO_WIDTH, LOGO_HEIGHT); // Animate bitmaps
}

void loop() {
}

void testdrawline() {
  int16_t i;

  display.clearDisplay(); // Clear display buffer

  for(i=0; i<display.width(); i+=4) {
    display.drawLine(0, 0, i, display.height()-1, WHITE);
    display.display(); // Update screen with each newly-drawn line
    delay(1);
  }
  for(i=0; i<display.height(); i+=4) {
    display.drawLine(0, 0, display.width()-1, i, WHITE);
    display.display();
    delay(1);
  }
  delay(250);

  display.clearDisplay();

  for(i=0; i<display.width(); i+=4) {
    display.drawLine(0, display.height()-1, i, 0, WHITE);
    display.display();
    delay(1);
  }
  for(i=display.height()-1; i>=0; i-=4) {
    display.drawLine(0, display.height()-1, display.width()-1, i, WHITE);
    display.display();
    delay(1);
  }
  delay(250);

  display.clearDisplay();

  for(i=display.width()-1; i>=0; i-=4) {
    display.drawLine(display.width()-1, display.height()-1, i, 0, WHITE);
    display.display();
    delay(1);
  }
  for(i=display.height()-1; i>=0; i-=4) {
    display.drawLine(display.width()-1, display.height()-1, 0, i, WHITE);
    display.display();
    delay(1);
  }
  delay(250);

  display.clearDisplay();

  for(i=0; i<display.height(); i+=4) {
    display.drawLine(display.width()-1, 0, 0, i, WHITE);
    display.display();
    delay(1);
  }
  for(i=0; i<display.width(); i+=4) {
    display.drawLine(display.width()-1, 0, i, display.height()-1, WHITE);
    display.display();
    delay(1);
  }

  delay(2000); // Pause for 2 seconds
}

void testdrawrect(void) {
  display.clearDisplay();

  for(int16_t i=0; i<display.height()/2; i+=2) {
    display.drawRect(i, i, display.width()-2*i, display.height()-2*i, WHITE);
    display.display(); // Update screen with each newly-drawn rectangle
    delay(1);
  }

  delay(2000);
}

void testfillrect(void) {
  display.clearDisplay();

  for(int16_t i=0; i<display.height()/2; i+=3) {
    // The INVERSE color is used so rectangles alternate white/black
    display.fillRect(i, i, display.width()-i*2, display.height()-i*2, INVERSE);
    display.display(); // Update screen with each newly-drawn rectangle
    delay(1);
  }

  delay(2000);
}

void testdrawcircle(void) {
  display.clearDisplay();

  for(int16_t i=0; i<max(display.width(),display.height())/2; i+=2) {
    display.drawCircle(display.width()/2, display.height()/2, i, WHITE);
    display.display();
    delay(1);
  }

  delay(2000);
}

void testfillcircle(void) {
  display.clearDisplay();

  for(int16_t i=max(display.width(),display.height())/2; i>0; i-=3) {
    // The INVERSE color is used so circles alternate white/black
    display.fillCircle(display.width() / 2, display.height() / 2, i, INVERSE);
    display.display(); // Update screen with each newly-drawn circle
    delay(1);
  }

  delay(2000);
}

void testdrawroundrect(void) {
  display.clearDisplay();

  for(int16_t i=0; i<display.height()/2-2; i+=2) {
    display.drawRoundRect(i, i, display.width()-2*i, display.height()-2*i,
      display.height()/4, WHITE);
    display.display();
    delay(1);
  }

  delay(2000);
}

void testfillroundrect(void) {
  display.clearDisplay();

  for(int16_t i=0; i<display.height()/2-2; i+=2) {
    // The INVERSE color is used so round-rects alternate white/black
    display.fillRoundRect(i, i, display.width()-2*i, display.height()-2*i,
      display.height()/4, INVERSE);
    display.display();
    delay(1);
  }

  delay(2000);
}

void testdrawtriangle(void) {
  display.clearDisplay();

  for(int16_t i=0; i<max(display.width(),display.height())/2; i+=5) {
    display.drawTriangle(
      display.width()/2  , display.height()/2-i,
      display.width()/2-i, display.height()/2+i,
      display.width()/2+i, display.height()/2+i, WHITE);
    display.display();
    delay(1);
  }

  delay(2000);
}

void testfilltriangle(void) {
  display.clearDisplay();

  for(int16_t i=max(display.width(),display.height())/2; i>0; i-=5) {
    // The INVERSE color is used so triangles alternate white/black
    display.fillTriangle(
      display.width()/2  , display.height()/2-i,
      display.width()/2-i, display.height()/2+i,
      display.width()/2+i, display.height()/2+i, INVERSE);
    display.display();
    delay(1);
  }

  delay(2000);
}

void testdrawchar(void) {
  display.clearDisplay();

  display.setTextSize(1);      // Normal 1:1 pixel scale
  display.setTextColor(WHITE); // Draw white text
  display.setCursor(0, 0);     // Start at top-left corner
  display.cp437(true);         // Use full 256 char 'Code Page 437' font

  // Not all the characters will fit on the display. This is normal.
  // Library will draw what it can and the rest will be clipped.
  for(int16_t i=0; i<256; i++) {
    if(i == '\n') display.write(' ');
    else          display.write(i);
  }

  display.display();
  delay(2000);
}

void testdrawstyles(void) {
  display.clearDisplay();

  display.setTextSize(1);             // Normal 1:1 pixel scale
  display.setTextColor(WHITE);        // Draw white text
  display.setCursor(0,0);             // Start at top-left corner
  display.println(F("Hello, world!"));

  display.setTextColor(BLACK, WHITE); // Draw 'inverse' text
  display.println(3.141592);

  display.setTextSize(2);             // Draw 2X-scale text
  display.setTextColor(WHITE);
  display.print(F("0x")); display.println(0xDEADBEEF, HEX);

  display.display();
  delay(2000);
}

void testscrolltext(void) {
  display.clearDisplay();

  display.setTextSize(2); // Draw 2X-scale text
  display.setTextColor(WHITE);
  display.setCursor(10, 0);
  display.println(F("scroll"));
  display.display();      // Show initial text
  delay(100);

  // Scroll in various directions, pausing in-between:
  display.startscrollright(0x00, 0x0F);
  delay(2000);
  display.stopscroll();
  delay(1000);
  display.startscrollleft(0x00, 0x0F);
  delay(2000);
  display.stopscroll();
  delay(1000);
  display.startscrolldiagright(0x00, 0x07);
  delay(2000);
  display.startscrolldiagleft(0x00, 0x07);
  delay(2000);
  display.stopscroll();
  delay(1000);
}

void testdrawbitmap(void) {
  display.clearDisplay();

  display.drawBitmap(
    (display.width()  - LOGO_WIDTH ) / 2,
    (display.height() - LOGO_HEIGHT) / 2,
    logo_bmp, LOGO_WIDTH, LOGO_HEIGHT, 1);
  display.display();
  delay(1000);
}

#define XPOS   0 // Indexes into the 'icons' array in function below
#define YPOS   1
#define DELTAY 2

void testanimate(const uint8_t *bitmap, uint8_t w, uint8_t h) {
  int8_t f, icons[NUMFLAKES][3];

  // Initialize 'snowflake' positions
  for(f=0; f< NUMFLAKES; f++) {
    icons[f][XPOS]   = random(1 - LOGO_WIDTH, display.width());
    icons[f][YPOS]   = -LOGO_HEIGHT;
    icons[f][DELTAY] = random(1, 6);
    Serial.print(F("x: "));
    Serial.print(icons[f][XPOS], DEC);
    Serial.print(F(" y: "));
    Serial.print(icons[f][YPOS], DEC);
    Serial.print(F(" dy: "));
    Serial.println(icons[f][DELTAY], DEC);
  }

  for(;;) { // Loop forever...
    display.clearDisplay(); // Clear the display buffer

    // Draw each snowflake:
    for(f=0; f< NUMFLAKES; f++) {
      display.drawBitmap(icons[f][XPOS], icons[f][YPOS], bitmap, w, h, WHITE);
    }

    display.display(); // Show the display buffer on the screen
    delay(200);        // Pause for 1/10 second

    // Then update coordinates of each flake...
    for(f=0; f< NUMFLAKES; f++) {
      icons[f][YPOS] += icons[f][DELTAY];
      // If snowflake is off the bottom of the screen...
      if (icons[f][YPOS] >= display.height()) {
        // Reinitialize to a random position, just off the top
        icons[f][XPOS]   = random(1 - LOGO_WIDTH, display.width());
        icons[f][YPOS]   = -LOGO_HEIGHT;
        icons[f][DELTAY] = random(1, 6);
      }
    }
  }
}

Nếu màn hình OLED của bạn không có chân Reset, bạn có thể cấu hình biến OLED_RESET với giá trị là -1:

#define OLED_RESET -1 // Reset pin # (or -1 if sharing Arduino reset pin)

Đoạn code trên sẽ nằm ở vị trí như hình dưới:

Code điều khiển OLED ESP32 cho màn hình không có chân Reset
Code điều khiển OLED ESP32 cho màn hình không có chân Reset

Bây giờ, bạn hãy upload đoạn code trên vào mạch ESP32 và quan sát kết quả nhé! Bạn sẽ thấy màn hình OLED hiển thị hoạt ảnh khá thú vị.

Trường hợp màn hình OLED ESP32 không hiển thị bất kỳ thông tin gì, bạn cần:

  • Kiểm tra lại màn hình OLED đã kết nối đúng với các chân của ESP32 đúng như trong code chưa
  • Kiểm tra lại địa chỉ I2C của màn hình OLED

Bạn có thể đổi địa chỉ của màn hình OLED ở dòng sau nếu cần:

if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { 

Hiển thị văn bản trên màn hình OLED ESP32

Trong thư viện mình hướng dẫn bạn tải có sẵn một số chức năng để chúng ta viết và hiển thị văn bản dễ dàng. IoTZone sẽ hướng dẫn bạn cách viết và hiển thị văn bản cuộn ngang màn hình nhé!

Hiển thị “Hello, World!”

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

#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels

// Declaration for an SSD1306 display connected to I2C (SDA, SCL pins)
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);

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

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

  display.setTextSize(1);
  display.setTextColor(WHITE);
  display.setCursor(0, 10);
  // Display static text
  display.println("Hello, world!");
  display.display(); 
}

void loop() {
  
}

Sau khi nạp đoạn code trên, màn hình OLED của bạn sẽ hiển thị như hình dưới:

Hiển thị Hello World trên màn hình OLED ESP32

Dưới đây, mình sẽ giải thích chi tiết cách code hoạt động:

Khai báo các thư viện

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

Tạo màn hình OLED, với chiều dài và chiều cao tương ứng. Màn hình OLED ESP32 của mình là 128×64, nếu bạn dùng màn hình có kích thước khác thì nhớ đổi thông số này nhé:

#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels

Tạo đổi tượng hiển thị bằng giao thức I2C:

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

-1 ở đây được dùng khi màn hình OLED không có chân Reset. Nếu màn hình của bạn có chân Reset thì chân này phải được nối với GPIO của ESP32, và chúng ta dùng số chân GPIO thay thế cho số -1.

Mở màn hình Serial Monitor ở tốc độ 115200:

Serial.begin(115200);

Khởi tạo màn hình:

if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { 
  Serial.println("SSD1306 allocation failed");
  for(;;); // Don't proceed, loop forever
}

In thông báo ra màn hình Serial Monitor để theo dõi kết quả, trong trường hợp màn hình OLED ESP32 bị lỗi gì đó không hiển thị thông tin:

Serial.println("SSD1306 allocation failed");

Trong trường hợp cần dùng màn hình OLED khác, bạn cần thay đổi địa chỉ của màn hình. Trong trường hợp mình dùng là địa chỉ 0x3C:

if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { 

Thêm độ trễ là 2 giây để màn hình OLED ESP32 có đủ thời gian để khởi tạo, trước khi hiển thị bất kỳ đoạn văn bản nào:

delay(2000);

Thay đổi cỡ chữ, font chữ và hiển thị văn bản

Xóa bộ đệm hiển thị:

display.clearDisplay();

Chọn kích thước, màu sắc cũng như vị trí cần hiển thị văn bản trên OLED ESP32:

  • Đặt kích thước:
display.setTextSize(1);    
  • Đặt màu sắc:
display.setTextColor(WHITE);     
  • Xác định vị trí hiển thị văn bản, với vị trí tọa độ (x,y). Tọa độ (0,0) bên dưới là vị trí trên cùng bên trái của màn hình OLED.
display.setCursor(0,0);       

Gửi văn bản đến màn hình:

display.println("Hello, world!");

Hiển thị văn bản trên OLED ESP32:

display.display();

Hiển thị văn bản cuộn ngang

Thư viện OLED mình hướng dẫn bạn cài ở trên có tích hợp sẵn nhiều chức năng cuộn văn bản khác nhau cho người dùng:

  • startedcrollright(0x00, 0x0F): Văn bản chạy từ trái sang phải
  • startedcrollleft(0x00, 0x0F): Phải sang trái
  • startedcrolldiagright(0x00, 0x07): Chạy từ góc dưới bên trái lên góc trên bên phải
  • startedcrolldiagleft(0x00, 0x07): Chạy từ góc dưới bên phải sang góc trên bên trái

Dưới đây là một đoạn code để hiển thị văn bản cuộn trên OLED ESP32, sử dụng các chứng năng trên:

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

#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels

// Declaration for an SSD1306 display connected to I2C (SDA, SCL pins)
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);

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

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

  display.setTextSize(1);
  display.setTextColor(WHITE);
  display.setCursor(0, 0);
  // Display static text
  display.println("Scrolling Hello");
  display.display(); 
  delay(100);
 
}

void loop() {
  // Scroll in various directions, pausing in-between:
  display.startscrollright(0x00, 0x0F);
  delay(2000);
  display.stopscroll();
  delay(1000);
  display.startscrollleft(0x00, 0x0F);
  delay(2000);
  display.stopscroll();
  delay(1000);
  display.startscrolldiagright(0x00, 0x07);
  delay(2000);
  display.startscrolldiagleft(0x00, 0x07);
  delay(2000);
  display.stopscroll();
  delay(1000);
}

Thay đổi font chữ hiển thị trên màn hình OLED ESP32

Thư viện OLED vừa cài cũng hỗ trợ chúng ta thay đổi một số font chữ khác, bên cạnh font chữ mặc định có sẵn. Bạn có thể chọn font Mono, Sans và Serif. Với từng loại font thì bạn có thể chọn in đậm, in nghiêng hoặc dạng bình thường, với các kích cỡ khác nhau.

Vì kích cỡ chữ sẽ phụ thuộc vào font chữ, nên chúng ta không thể sử dụng setTextSize() trong trường hợp này. Các font chữ có sẵn là 9, 12, 18, 24 point và chứa các ký tự 7 bit.

Bạn có thể lựa chọn các font chữ mình thích:

FreeMono12pt7b.h		FreeSansBoldOblique12pt7b.h
FreeMono18pt7b.h		FreeSansBoldOblique18pt7b.h
FreeMono24pt7b.h		FreeSansBoldOblique24pt7b.h
FreeMono9pt7b.h			FreeSansBoldOblique9pt7b.h
FreeMonoBold12pt7b.h		FreeSansOblique12pt7b.h
FreeMonoBold18pt7b.h		FreeSansOblique18pt7b.h
FreeMonoBold24pt7b.h		FreeSansOblique24pt7b.h
FreeMonoBold9pt7b.h		FreeSansOblique9pt7b.h
FreeMonoBoldOblique12pt7b.h	FreeSerif12pt7b.h
FreeMonoBoldOblique18pt7b.h	FreeSerif18pt7b.h
FreeMonoBoldOblique24pt7b.h	FreeSerif24pt7b.h
FreeMonoBoldOblique9pt7b.h	FreeSerif9pt7b.h
FreeMonoOblique12pt7b.h		FreeSerifBold12pt7b.h
FreeMonoOblique18pt7b.h		FreeSerifBold18pt7b.h
FreeMonoOblique24pt7b.h		FreeSerifBold24pt7b.h
FreeMonoOblique9pt7b.h		FreeSerifBold9pt7b.h
FreeSans12pt7b.h		FreeSerifBoldItalic12pt7b.h
FreeSans18pt7b.h		FreeSerifBoldItalic18pt7b.h
FreeSans24pt7b.h		FreeSerifBoldItalic24pt7b.h
FreeSans9pt7b.h			FreeSerifBoldItalic9pt7b.h
FreeSansBold12pt7b.h		FreeSerifItalic12pt7b.h
FreeSansBold18pt7b.h		FreeSerifItalic18pt7b.h
FreeSansBold24pt7b.h		FreeSerifItalic24pt7b.h
FreeSansBold9pt7b.h		FreeSerifItalic9pt7b.h

Tuy nhiên, theo mình thấy thì OLED ESP32 hiển thị kích cỡ tốt nhất là 9 và 12 point.

Để chọn một font chữ, bạn có thể dùng câu lệnh như sau:

#include <Fonts/FreeSerif12pt7b.h>

Dòng kết tiếp, bạn cần chọn kích cỡ font:

display.setFont(&FreeSerif12pt7b);

Nếu muốn quay lại font cữ gốc, bạn có thể gọi hàm setFont nhưng không điền thông tin đối số gì bên trong:

display.setFont();

Dưới đây là chương trình hoàn chỉnh để đổi phông chữ hiển thị trên OLED ESP32, bạn có thể upload tham khảo:

#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <Fonts/FreeSerif9pt7b.h>

#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels

// Declaration for an SSD1306 display connected to I2C (SDA, SCL pins)
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);

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

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

  display.setFont(&FreeSerif9pt7b);
  display.clearDisplay();
  display.setTextSize(1);             
  display.setTextColor(WHITE);        
  display.setCursor(0,20);             
  display.println("Hello, world!");
  display.display();
  delay(2000); 
}
void loop() {
  
}

Sau khi nạp vào ESP32, bạn sẽ thấy màn hình OLED hiển thị dòng văn bản với font chữ FreeSerif mà mình đã chọn:

Cách đổi font chữ hiển thị trên OLED ESP32
Cách đổi font chữ hiển thị trên OLED ESP32

Lời kết

Trên đây là các hướng dẫn chi tiết về cách hiển thị văn bản trên màn hình OLED ESP32, chúc bạn thành công! Ngoài ra, IoTZone cũng đã hướng dẫn cách làm việc với nhiều module khác nhau bằng ESP32, bạn có thể tham khảo nếu thích:

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 *