본문 바로가기

ESP32

ESP32 SSD1306 OLED 디스플레이

반응형

 

Arduino IDE를 사용한 ESP32 OLED 디스플레이 이 가이드에서는 Arduino IDE를 사용하여 ESP32와 함께 0.96인치 SSD1306 OLED 디스플레이를 사용하는 방법을 보여줍니다. 텍스트를 쓰고, 다양한 글꼴을 설정하고, 모양을 그리고, 비트맵 이미지를 표시하는 방법을 보여드리겠습니다.

 

ESP32 Arduino OLED 디스플레이 이미지 회로

 

DHT 센서와 ESP32를 사용하여 온도와 습도 판독값을 표시하는 방법을 보여주는 전담 가이드도 있습니다.

 

0.96인치 OLED 디스플레이 소개

 

이 튜토리얼에서 사용할 OLED 디스플레이는 SSD1306 모델입니다. 다음 그림과 같이 128×64픽셀의 단색 0.96인치 디스플레이입니다.

 

 

ESP32 ESP8266 Arduino를 사용한 0.96인치 OLED 디스플레이

 

OLED 디스플레이는 백라이트가 필요 없어 어두운 환경에서도 대비가 매우 좋습니다. 또한 픽셀은 켜져 있을 때만 에너지를 소모하므로 OLED 디스플레이는 다른 디스플레이에 비해 전력 소모가 적습니다.

 

우리가 사용하는 모델은 4개의 핀을 가지고 있으며 I2C 통신 프로토콜을 사용하여 모든 마이크로컨트롤러와 통신합니다. 여분의 RESET 핀이 있는 모델이나 SPI 통신 프로토콜을 사용하여 통신하는 모델이 있습니다.

 

OLED 디스플레이 SSD1306 핀 배선

 

OLED 디스플레이는 I2C 통신 프로토콜을 사용하므로 배선이 매우 간단합니다. 다음 표를 참조로 사용할 수 있습니다.

 

Pin ESP32
Vin 3.3V
GND GND
SCL GPIO 22
SDA GPIO 21

 

 

또는 다음 회로도를 따라 ESP32를 OLED 디스플레이에 연결할 수 있습니다.

 

 

이 예에서는 I2C 통신 프로토콜을 사용합니다. ESP32에서 I2C 통신에 가장 적합한 핀은 GPIO 22(SCL)와 GPIO 21(SDA)입니다.

 

SPI 통신 프로토콜을 사용하는 OLED 디스플레이를 사용하는 경우 다음 GPIO를 사용하세요.

 

  • GPIO 18: CLK
  • GPIO 19: MISO
  • GPIO 23: MOSI
  • GPIO 5: CS

ESP32 GPIO에 대해 자세히 알아보려면 ESP32 핀아웃 참조 가이드를 읽어보세요.

 

SSD1306 OLED 라이브러리 설치 - ESP32

 

ESP32로 OLED 디스플레이를 제어하는데 사용할 수 있는 라이브러리가 여러 개 있습니다. 이 튜토리얼에서는 Adafruit_SSD1306 라이브러리Adafruit_GFX 라이브러리라는 두 가지 Adafruit 라이브러리를 사용합니다.

 

다음 단계에 따라 해당 라이브러리를 설치합니다.

 

1. Arduino IDE를 열고 Sketch > Include Library > Manage Libraries로 이동합니다. Library Manager가 열립니다.

 

2. 검색 상자에 "SSD1306"을 입력하고 Adafruit에서 SSD1306 라이브러리를 설치합니다.

 

 

3. Adafruit에서 SSD1306 라이브러리를 설치한 후 검색 상자에 "GFX"를 입력하고 라이브러리를 설치합니다.

 

GFX 라이브러리 ESP8266 ESP32 Arduino 설치

 

4. 라이브러리를 설치한 후 Arduino IDE를 다시 시작합니다.

 

Arduino IDE를 사용하여 ESP32를 프로그래밍하므로 Arduino IDE에 ESP32 애드온이 설치되어 있어야 합니다. 설치되어 있지 않은 경우 먼저 다음 튜토리얼을 따르세요.

 

Arduino IDE에 ESP32 보드 설치(Windows 지침)

Arduino IDE에 ESP32 보드 설치(Mac OS X 및 Linux 지침)

 

ESP32로 OLED 디스플레이 테스트

 

OLED 디스플레이를 ESP32에 연결하고 필요한 모든 라이브러리를 설치한 후 라이브러리에서 하나의 예제를 사용하여 모든 것이 제대로 작동하는지 확인할 수 있습니다.

 

Arduino IDE에서 파일 > 예제 > Adafruit SSD1306으로 이동하여 사용 중인 디스플레이에 대한 예제를 선택합니다.

 

Adafruit SSD1306 라이브러리 예제 테스트

 

다음 코드가 로드되어야 합니다.

 

/*********
  Complete project details at https://randomnerdtutorials.com
  
  This is an example for our Monochrome OLEDs based on SSD1306 drivers. Pick one up today in the adafruit shop! ------> http://www.adafruit.com/category/63_98
  This example is for a 128x32 pixel display using I2C to communicate 3 pins are required to interface (two I2C and one reset).
  Adafruit invests time and resources providing this open source code, please support Adafruit and open-source hardware by purchasing products from Adafruit!
  Written by Limor Fried/Ladyada for Adafruit Industries, with contributions from the open source community. BSD license, check license.txt for more information All text above, and the splash screen below must be included in any redistribution. 
*********/

#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);
      }
    }
  }
}

 

OLED에 RESET 핀이 없으면 아래와 같이 OLED_RESET 변수를 -1로 설정해야 합니다.

 

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

 

 

 

 

ESP32 보드에 코드를 업로드합니다. 도구 메뉴에서 올바른 보드와 COM 포트를 선택하는 것을 잊지 마세요.

 

다음 짧은 비디오와 같이 OLED에서 다양한 애니메이션이 표시되어야 합니다.

 

OLED 디스플레이에 아무것도 표시되지 않는 경우:

 

  • OLED 디스플레이가 ESP32에 제대로 연결되었는지 확인합니다.
  • OLED 디스플레이 I2C 주소를 다시 확인합니다. OLED를 ESP32에 연결한 상태에서 아래 i2c scan 코드를 업로드하고 직렬 모니터에서 I2C 주소를 확인합니다.
/*********
  Rui Santos
  Complete project details at https://randomnerdtutorials.com  
*********/

#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);          
}

 

 

필요한 경우 다음 줄에서 OLED 주소를 변경해야 합니다. 우리의 경우 주소는 0x3C입니다.

 

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

 

텍스트 쓰기 - OLED 디스플레이

 

OLED 디스플레이용 Adafruit 라이브러리에는 텍스트를 쓰는 여러 함수가 있습니다. 이 섹션에서는 라이브러리 함수를 사용하여 텍스트를 쓰고 스크롤하는 방법을 알아봅니다.

 

"Hello, world!" OLED 디스플레이: 다음 스케치는 OLED 디스플레이에 Hello, world! 메시지를 표시합니다.

 

/*********
  Rui Santos
  Complete project details at https://randomnerdtutorials.com  
*********/

#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() {
  
}

 

코드를 업로드하면 OLED에 다음과 같은 내용이 표시됩니다.

 

 

ESP32 ESP8266 Arduino OLED 디스플레이 글꼴 유형

 

코드가 작동하는 방식을 간단히 살펴보겠습니다.

 

라이브러리 가져오기

 

먼저 필요한 라이브러리를 가져와야 합니다. I2C를 사용하는 Wire 라이브러리와 디스플레이에 쓰는 Adafruit 라이브러리: Adafruit_GFX 및 Adafruit_SSD1306.

 

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

 

 

OLED 디스플레이 초기화

 

그런 다음 OLED 너비와 높이를 정의합니다. 이 예에서는 128×64 OLED 디스플레이를 사용합니다. 다른 크기를 사용하는 경우 SCREEN_WIDTH 및 SCREEN_HEIGHT 변수에서 변경할 수 있습니다.

 

#define SCREEN_WIDTH 128 // OLED 디스플레이 너비(픽셀)
#define SCREEN_HEIGHT 64 // OLED 디스플레이 높이(픽셀)

 

그런 다음 I2C 통신 프로토콜(&Wire)을 사용하여 이전에 정의한 너비와 높이로 디스플레이 객체를 초기화합니다.

 

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

 

(-1) 매개변수는 OLED 디스플레이에 RESET 핀이 없음을 의미합니다. OLED 디스플레이에 RESET 핀이 있는 경우 GPIO에 연결해야 합니다. 이 경우 GPIO 번호를 매개변수로 전달해야 합니다.

 

setup()에서 디버깅 목적으로 직렬 모니터를 115200의 보드 레이트로 초기화합니다.

 

Serial.begin(115200);

 

다음과 같이 begin() 메서드로 OLED 디스플레이를 초기화합니다.

 

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

 

 

이 스니펫은 디스플레이에 연결할 수 없는 경우 직렬 모니터에 메시지를 인쇄합니다.

 

Serial.println("SSD1306 allocation failed");

 

다른 OLED 디스플레이를 사용하는 경우 OLED 주소를 변경해야 할 수 있습니다. 이 경우 주소는 0x3C입니다.

 

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

 

이 주소가 작동하지 않으면 I2C 스캐너 스케치를 실행하여 OLED 주소를 찾을 수 있습니다. I2C 스캐너 스케치 코드는 위에 있습니다.

 

디스플레이를 초기화한 후 OLED가 텍스트를 쓰기 전에 초기화할 충분한 시간을 갖도록 2초 지연을 추가합니다.

 

delay(2000);

 

디스플레이 지우기, 글꼴 크기, 색상 설정 및 텍스트 쓰기

 

디스플레이를 초기화한 후 clearDisplay() 메서드로 디스플레이 버퍼를 지웁니다.

 

display.clearDisplay();

 

텍스트를 쓰기 전에 텍스트 크기, 색상 및 OLED에 텍스트가 표시될 위치를 설정해야 합니다.

 

setTextSize() 메서드를 사용하여 글꼴 크기를 설정합니다.

 

display.setTextSize(1);

 

setTextColor() 메서드로 글꼴 색상을 설정합니다.

 

display.setTextColor(WHITE);

 

WHITE는 흰색 글꼴과 검은색 배경을 설정합니다.

 

setCursor(x,y) 메서드를 사용하여 텍스트가 시작되는 위치를 정의합니다. 이 경우, 텍스트를 (0,0) 좌표, 즉 왼쪽 상단 모서리에서 시작하도록 설정합니다.

 

display.setCursor(0,0);

 

마지막으로, 다음과 같이 println() 메서드를 사용하여 텍스트를 디스플레이로 보낼 수 있습니다.

 

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

 

그런 다음, display() 메서드를 호출하여 실제로 텍스트를 화면에 표시해야 합니다.

 

display.display();

 

텍스트 스크롤

 

Adafruit OLED 라이브러리는 텍스트를 쉽게 스크롤하는 데 유용한 메서드를 제공합니다.

 

  • startscrollright(0x00, 0x0F): 왼쪽에서 오른쪽으로 텍스트 스크롤
  • startscrollleft(0x00, 0x0F): 오른쪽에서 왼쪽으로 텍스트 스크롤
  • startscrolldiagright(0x00, 0x07): 왼쪽 아래 모서리에서 오른쪽 위 모서리로 텍스트 스크롤
  • startscrolldiagleft(0x00, 0x07): 오른쪽 아래 모서리에서 왼쪽 위 모서리로 텍스트 스크롤

 

다음 스케치는 이러한 메서드를 구현합니다.

 

/*********
  Rui Santos
  Complete project details at https://randomnerdtutorials.com  
*********/

#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);
}

 

다음 짧은 비디오에서 보이는 대로 텍스트가 스크롤됩니다.

 

다른 글꼴 사용 - OLED 디스플레이

 

Adafruit GFX 라이브러리를 사용하면 기본 제공 글꼴 외에도 일부 대체 글꼴을 사용할 수 있습니다. Serif, Sans, Mono 중에서 선택할 수 있습니다. 각 글꼴은 굵게, 기울임꼴 및 다양한 크기로 제공됩니다.

 

크기는 실제 글꼴에 의해 설정됩니다. 따라서 setTextSize() 메서드는 이러한 글꼴에서 작동하지 않습니다. 글꼴은 9, 12, 18, 24포인트 크기로 제공되며 7비트 문자(ASCII 코드)도 포함합니다(글꼴 이름에 7b로 설명됨).

 

다음 글꼴 중에서 선택할 수 있습니다.

 

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

 

 

OLED 디스플레이에 더 잘 어울리는 글꼴은 9포인트와 12포인트 크기입니다. 이러한 글꼴 중 하나를 사용하려면 먼저 스케치에 포함해야 합니다. 예:

 

#include <Fonts/FreeSerif12pt7b.h>

 

다음으로 setFont() 메서드를 사용하고 지정된 글꼴을 인수로 전달하기만 하면 됩니다.

 

display.setFont(&FreeSerif12pt7b);

 

글꼴을 지정한 후에는 텍스트를 쓰는 모든 메서드에서 해당 글꼴을 사용합니다. 원래 글꼴을 다시 사용하려면 인수 없이 setFont() 메서드를 호출하기만 하면 됩니다.

 

display.setFont();

 

다음 스케치를 보드에 업로드합니다.

 

/*********
  Rui Santos
  Complete project details at https://randomnerdtutorials.com  
*********/

#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() {
  
}

 

이제 디스플레이에서 FreeSerif 글꼴로 "Hello, world!" 메시지를 인쇄합니다.

 

ESP32 ESP8266 Arduino OLED 디스플레이 글꼴 유형

 

OLED 디스플레이에 모양 그리기

 

Adafruit OLED 라이브러리는 픽셀, 선 및 모양을 그리는 데 유용한 메서드를 제공합니다. 이러한 방법을 간단히 살펴보겠습니다.

 

픽셀 그리기

 

ESP32 ESP8266 Arduino OLED 디스플레이 픽셀 도트 - 가운데 흰 점

 

OLED 디스플레이에 픽셀을 그리려면 drawPixel(x, y, color) 메서드를 사용할 수 있습니다. 이 메서드는 픽셀이 나타나는 x 및 y 좌표와 색상을 인수로 받습니다. 예:

 

display.drawPixel(64, 32, WHITE);

 

선 그리기

 

ESP32 ESP8266 Arduino OLED 디스플레이 선

 

drawLine(x1, y1, x2, y2, color) 메서드를 사용하여 선을 만듭니다. (x1, y1) 좌표는 선의 시작을 나타내고 (x2, y2) 좌표는 선이 끝나는 위치를 나타냅니다. 예:

 

display.drawLine(0, 0, 127, 20, WHITE);

 

사각형 그리기

 

ESP32 ESP8266 Arduino OLED 디스플레이 사각형

 

drawRect(x, y, width, height, color)는 사각형을 그리는 간편한 방법을 제공합니다. (x, y) 좌표는 사각형의 왼쪽 상단 모서리를 나타냅니다. 그런 다음 너비, 높이 및 색상을 지정해야 합니다.

 

display.drawRect(10, 10, 50, 30, WHITE);

 

fillRect(x, y, width, height, color)를 사용하여 채워진 사각형을 그릴 수 있습니다. 이 메서드는 drawRect()와 동일한 인수를 허용합니다.

 

ESP32 ESP8266 Arduino OLED 디스플레이 채워진

 

라이브러리는 또한 모서리가 둥근 사각형을 표시하는 메서드인 drawRoundRect() 및 fillRoundRect()를 제공합니다. 이러한 메서드는 이전 메서드와 동일한 인수와 모서리의 반경을 허용합니다. 예:

 

display.drawRoundRect(10, 10, 30, 50, 2, WHITE);

 

ESP32 ESP8266 Arduino OLED 디스플레이 사각형 세로

 

또는 채워진 둥근 사각형:

 

display.fillRoundRect(10, 10, 30, 50, 2, WHITE);

 

ESP32 ESP8266 Arduino OLED 디스플레이 사각형 세로 채워진

 

원 그리기

 

ESP32 ESP8266 Arduino OLED 디스플레이 원

 

원을 그리려면 drawCircle(x, y, radius, color) 메서드를 사용합니다. (x,y) 좌표는 원의 중심을 나타냅니다. 반경도 인수로 전달해야 합니다. 예:

 

display.drawCircle(64, 32, 10, WHITE);

 

같은 방식으로 채워진 원을 만들려면 동일한 인수를 사용하여 fillCircle() 메서드를 사용합니다.

 

display.fillCircle(64, 32, 10, WHITE);

 

ESP32 ESP8266 Arduino OLED 디스플레이 원 채우기

 

삼각형 그리기

 

ESP32 ESP8266 Arduino OLED 디스플레이 삼각형

 

drawTriangle(x1, y1, x2, y2, x3, y3, color) 메서드를 사용하여 삼각형을 만듭니다. 이 메서드는 각 모서리의 좌표와 색상을 인수로 받습니다.

 

display.drawTriangle(10, 10, 55, 20, 5, 40, WHITE);

 

fillTriangle() 메서드를 사용하여 채워진 삼각형을 그립니다.

 

display.fillTriangle(10, 10, 55, 20, 5, 40, WHITE);

 

ESP32 ESP8266 Arduino OLED 디스플레이 삼각형 채우기

 

Invert

 

라이브러리는 모양이나 텍스트와 함께 사용할 수 있는 추가 메서드인 invertDisplay() 메서드를 제공합니다. 인수로 true를 전달하면 화면의 색상이 반전되고 false를 전달하면 원래 색상으로 돌아갑니다.

 

삼각형을 정의한 후 다음 명령을 호출하는 경우:

 

display.invertDisplay(true);

 

다음과 같이 역삼각형이 생성됩니다.

 

ESP32 ESP8266 Arduino OLED 디스플레이 삼각형 배경 채우기

 

코드 - 도형 그리기

 

이전에 다룬 각 코드 조각을 구현하고 모든 도형을 살펴보는 다음 스케치를 업로드합니다.

/*********
  Rui Santos
  Complete project details at https://randomnerdtutorials.com  
*********/

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

#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64

// 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(F("SSD1306 allocation failed"));
    for(;;);
  }
  delay(2000); // Pause for 2 seconds

  // Clear the buffer
  display.clearDisplay();

  // Draw a single pixel in white
  display.drawPixel(64, 32, WHITE);
  display.display();
  delay(3000);

  // Draw line
  display.clearDisplay();
  display.drawLine(0, 0, 127, 20, WHITE);
  display.display();
  delay(3000);
  
  // Draw rectangle
  display.clearDisplay();
  display.drawRect(30, 10, 50, 30, WHITE);
  display.display();
  delay(3000);
  // Fill rectangle
  display.fillRect(30, 10, 50, 30, WHITE);
  display.display();
  delay(3000);

  // Draw round rectangle
  display.clearDisplay();
  display.drawRoundRect(10, 10, 30, 50, 2, WHITE);
  display.display();
  delay(3000);
  // Fill round rectangle
  display.clearDisplay();
  display.fillRoundRect(10, 10, 30, 50, 2, WHITE);
  display.display();
  delay(3000);
  
  // Draw circle
  display.clearDisplay();
  display.drawCircle(64, 32, 10, WHITE);
  display.display();
  delay(3000);
  // Fill circle
  display.fillCircle(64, 32, 10, WHITE);
  display.display();
  delay(3000);
  
  // Draw triangle
  display.clearDisplay();
  display.drawTriangle(10, 10, 55, 20, 5, 40, WHITE);
  display.display();
  delay(3000);
  // Fill triangle
  display.fillTriangle(10, 10, 55, 20, 5, 40, WHITE);
  display.display();
  delay(3000);

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

void loop() {
  
}

 

 

OLED에 비트맵 이미지 표시

 

OLED 디스플레이에 128×64 비트맵 단색 이미지를 표시할 수 있습니다.

 

먼저 이미징 프로그램을 사용하여 사진이나 그림의 크기를 조정하고 단색 비트맵으로 저장합니다. Windows PC를 사용하는 경우 Paint를 사용할 수 있습니다.

 

비트맵 이미지 표시 OLED 이미지 변환

 

그런 다음 Image to C Array 변환기를 사용하여 이미지를 배열로 변환합니다. 저는 LCD Image Converter를 사용했습니다.

 

프로그램을 실행하고 새 이미지로 시작합니다. 이미지 > 가져오기로 이동하여 이전에 만든 비트맵 이미지를 선택합니다.

 

비트맵 이미지 OLED 표시

 

옵션 > 변환으로 이동하여 준비 탭에서 다음 옵션을 선택합니다.

 

  • 유형: 단색, 임계값 디더
  • 주 스캔 방향: 위에서 아래로
  • 라인 스캔 방향: 앞으로

 

 

이미지 탭으로 이동하여 다음 옵션을 선택합니다.

 

  • 행으로 분할
  • 블록 크기: 8비트
  • 바이트 순서: 리틀 엔디언

 

비트맵 이미지 표시 OLED 변환 이미지 내보내기

 

그런 다음 확인을 클릭합니다. 마지막으로 주 메뉴에서 파일 > 변환으로 이동합니다. 확장자가 .c인 새 파일을 저장해야 합니다. 해당 파일에는 이미지의 C 배열이 포함되어 있습니다. 텍스트 편집기로 해당 파일을 열고 배열을 복사합니다.

 

우리의 경우, 이것이 우리가 얻는 배열입니다.

static const uint8_t image_data_Saraarray[1024] = {
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x07, 0xff, 0xff, 0xff, 0xff, 0xff, 
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x07, 0xff, 0xff, 0xff, 0xff, 0xff, 
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xff, 0xff, 
    0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, 
    0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, 
    0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 
    0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 
    0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 
    0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x14, 0x9e, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 
    0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x36, 0x3f, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 
    0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x6d, 0xff, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 
    0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0xfb, 0xff, 0x80, 0x1f, 0xff, 0xff, 0xff, 0xff, 
    0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x03, 0xd7, 0xff, 0x80, 0x0f, 0xff, 0xff, 0xff, 0xff, 
    0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x07, 0xef, 0xff, 0x80, 0x07, 0xff, 0xff, 0xff, 0xff, 
    0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x0f, 0xdf, 0xff, 0x90, 0x07, 0xff, 0xff, 0xff, 0xff, 
    0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x0f, 0xbf, 0xff, 0xd0, 0x07, 0xff, 0xff, 0xff, 0xff, 
    0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x1d, 0x7f, 0xff, 0xd0, 0x07, 0xff, 0xff, 0xff, 0xff, 
    0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x01, 0x1b, 0xff, 0xff, 0xc0, 0x07, 0xff, 0xff, 0xff, 0xff, 
    0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x02, 0xa7, 0xff, 0xff, 0xc0, 0x07, 0xff, 0xff, 0xff, 0xff, 
    0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x03, 0xff, 0xc0, 0x00, 0x07, 0xff, 0xff, 0xff, 0xff, 
    0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0xff, 0x80, 0x00, 0x0b, 0xff, 0xff, 0xff, 0xff, 
    0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x03, 0xff, 0xff, 0xff, 0xf0, 0x0f, 0xff, 0xff, 0xff, 0xff, 
    0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x07, 0xff, 0xff, 0xff, 0xf0, 0x0f, 0xff, 0xff, 0xff, 0xff, 
    0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x0f, 0x07, 0xff, 0xf8, 0xf8, 0x03, 0xff, 0xff, 0xff, 0xff, 
    0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x0e, 0x01, 0xff, 0xc0, 0x38, 0x07, 0xff, 0xff, 0xff, 0xff, 
    0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x1c, 0x46, 0xff, 0xb1, 0x18, 0x07, 0xff, 0xff, 0xff, 0xff, 
    0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x3f, 0x97, 0xff, 0xc0, 0x7a, 0x07, 0xff, 0xff, 0xff, 0xff, 
    0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xfe, 0x03, 0xff, 0xff, 0xff, 0xff, 
    0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xfe, 0x03, 0xff, 0xff, 0xff, 0xff, 
    0xff, 0xff, 0xff, 0xff, 0xfe, 0x01, 0x3f, 0xff, 0xff, 0xff, 0xfe, 0x01, 0xff, 0xff, 0xff, 0xff, 
    0xff, 0xff, 0xff, 0xff, 0xfe, 0x01, 0xbf, 0xff, 0xff, 0xff, 0xfe, 0x81, 0xff, 0xff, 0xff, 0xff, 
    0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0xbf, 0xff, 0xff, 0xff, 0xfc, 0x81, 0xff, 0xff, 0xff, 0xff, 
    0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0xff, 0xff, 0xfe, 0xff, 0xfd, 0x83, 0xff, 0xff, 0xff, 0xff, 
    0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0xbf, 0xff, 0xfe, 0xff, 0xfd, 0x01, 0xff, 0xff, 0xff, 0xff, 
    0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x01, 0xff, 0xff, 0xff, 0xff, 
    0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x7f, 0xff, 0xff, 0xff, 0xfb, 0x03, 0xff, 0xff, 0xff, 0xff, 
    0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x3f, 0xff, 0xdc, 0xff, 0xfa, 0x03, 0xff, 0xff, 0xff, 0xff, 
    0xff, 0xff, 0xff, 0xff, 0xd8, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xf8, 0x03, 0xff, 0xff, 0xff, 0xff, 
    0xff, 0xff, 0xff, 0xff, 0xd0, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xf8, 0x01, 0xff, 0xff, 0xff, 0xff, 
    0xff, 0xff, 0xff, 0xff, 0x90, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xf8, 0x02, 0xff, 0xff, 0xff, 0xff, 
    0xff, 0xff, 0xff, 0xff, 0xb0, 0x00, 0x0f, 0xf5, 0xff, 0xd7, 0xf8, 0x01, 0xff, 0xff, 0xff, 0xff, 
    0xff, 0xff, 0xff, 0xff, 0xb0, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x5f, 0xff, 0xff, 0xff, 
    0xff, 0xff, 0xff, 0xff, 0xa0, 0x00, 0x0f, 0xfb, 0xff, 0xff, 0xf0, 0x00, 0x3f, 0xff, 0xff, 0xff, 
    0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x0f, 0xfd, 0xff, 0xdf, 0xf0, 0x00, 0x3f, 0xff, 0xff, 0xff, 
    0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x07, 0xff, 0xff, 0xbf, 0xf0, 0x00, 0x0f, 0xff, 0xff, 0xff, 
    0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x07, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x87, 0xff, 0xff, 0xff, 
    0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x03, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x43, 0xff, 0xff, 0xff, 
    0xff, 0xff, 0xff, 0xff, 0x60, 0x00, 0x01, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x73, 0xff, 0xff, 0xff, 
    0xff, 0xff, 0xff, 0xfe, 0xe0, 0x00, 0x00, 0xff, 0xff, 0xff, 0x80, 0x00, 0x7b, 0xff, 0xff, 0xff, 
    0xff, 0xff, 0xff, 0xfd, 0xe0, 0x00, 0x00, 0x7f, 0xff, 0xfe, 0x00, 0x00, 0x33, 0xff, 0xff, 0xff, 
    0xff, 0xff, 0xff, 0xfd, 0xe0, 0x00, 0x00, 0x3f, 0xff, 0xf8, 0x00, 0x00, 0x27, 0xff, 0xff, 0xff, 
    0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x0f, 0xff, 0xf0, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xff, 
    0xff, 0xff, 0xff, 0xff, 0x60, 0x00, 0x00, 0x67, 0xff, 0xe0, 0x00, 0x00, 0x1b, 0xff, 0xff, 0xff, 
    0xff, 0xff, 0xff, 0xfd, 0x40, 0x00, 0x00, 0xf3, 0xff, 0xc4, 0x00, 0x00, 0x0b, 0xff, 0xff, 0xff, 
    0xff, 0xff, 0xff, 0xfe, 0x80, 0x00, 0x00, 0xfc, 0xff, 0x8c, 0x00, 0x00, 0x03, 0xff, 0xff, 0xff, 
    0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x7f, 0x3c, 0x3c, 0x00, 0x00, 0x07, 0xff, 0xff, 0xff, 
    0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x3f, 0xc0, 0x7c, 0x00, 0x00, 0x03, 0xff, 0xff, 0xff, 
    0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xfc, 0x00, 0x00, 0x03, 0xff, 0xff, 0xff
};

 

배열을 스케치에 복사합니다. 그런 다음 배열을 표시하려면 다음 인수(x, y, 이미지 배열, 이미지 너비, 이미지 높이, 회전)를 허용하는 drawBitmap() 메서드를 사용합니다. (x, y) 좌표는 이미지가 표시되기 시작하는 위치를 정의합니다.

 

아래 코드를 복사하여 OLED에 비트맵 이미지를 표시합니다.

 

/*********
  Rui Santos
  Complete project details at https://randomnerdtutorials.com  
*********/

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

#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64

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

static const uint8_t image_data_Saraarray[1024] = {
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x07, 0xff, 0xff, 0xff, 0xff, 0xff, 
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x07, 0xff, 0xff, 0xff, 0xff, 0xff, 
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xff, 0xff, 
    0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, 
    0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, 
    0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 
    0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 
    0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 
    0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x14, 0x9e, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 
    0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x36, 0x3f, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 
    0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x6d, 0xff, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 
    0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0xfb, 0xff, 0x80, 0x1f, 0xff, 0xff, 0xff, 0xff, 
    0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x03, 0xd7, 0xff, 0x80, 0x0f, 0xff, 0xff, 0xff, 0xff, 
    0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x07, 0xef, 0xff, 0x80, 0x07, 0xff, 0xff, 0xff, 0xff, 
    0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x0f, 0xdf, 0xff, 0x90, 0x07, 0xff, 0xff, 0xff, 0xff, 
    0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x0f, 0xbf, 0xff, 0xd0, 0x07, 0xff, 0xff, 0xff, 0xff, 
    0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x1d, 0x7f, 0xff, 0xd0, 0x07, 0xff, 0xff, 0xff, 0xff, 
    0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x01, 0x1b, 0xff, 0xff, 0xc0, 0x07, 0xff, 0xff, 0xff, 0xff, 
    0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x02, 0xa7, 0xff, 0xff, 0xc0, 0x07, 0xff, 0xff, 0xff, 0xff, 
    0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x03, 0xff, 0xc0, 0x00, 0x07, 0xff, 0xff, 0xff, 0xff, 
    0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0xff, 0x80, 0x00, 0x0b, 0xff, 0xff, 0xff, 0xff, 
    0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x03, 0xff, 0xff, 0xff, 0xf0, 0x0f, 0xff, 0xff, 0xff, 0xff, 
    0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x07, 0xff, 0xff, 0xff, 0xf0, 0x0f, 0xff, 0xff, 0xff, 0xff, 
    0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x0f, 0x07, 0xff, 0xf8, 0xf8, 0x03, 0xff, 0xff, 0xff, 0xff, 
    0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x0e, 0x01, 0xff, 0xc0, 0x38, 0x07, 0xff, 0xff, 0xff, 0xff, 
    0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x1c, 0x46, 0xff, 0xb1, 0x18, 0x07, 0xff, 0xff, 0xff, 0xff, 
    0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x3f, 0x97, 0xff, 0xc0, 0x7a, 0x07, 0xff, 0xff, 0xff, 0xff, 
    0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xfe, 0x03, 0xff, 0xff, 0xff, 0xff, 
    0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xfe, 0x03, 0xff, 0xff, 0xff, 0xff, 
    0xff, 0xff, 0xff, 0xff, 0xfe, 0x01, 0x3f, 0xff, 0xff, 0xff, 0xfe, 0x01, 0xff, 0xff, 0xff, 0xff, 
    0xff, 0xff, 0xff, 0xff, 0xfe, 0x01, 0xbf, 0xff, 0xff, 0xff, 0xfe, 0x81, 0xff, 0xff, 0xff, 0xff, 
    0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0xbf, 0xff, 0xff, 0xff, 0xfc, 0x81, 0xff, 0xff, 0xff, 0xff, 
    0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0xff, 0xff, 0xfe, 0xff, 0xfd, 0x83, 0xff, 0xff, 0xff, 0xff, 
    0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0xbf, 0xff, 0xfe, 0xff, 0xfd, 0x01, 0xff, 0xff, 0xff, 0xff, 
    0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x01, 0xff, 0xff, 0xff, 0xff, 
    0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x7f, 0xff, 0xff, 0xff, 0xfb, 0x03, 0xff, 0xff, 0xff, 0xff, 
    0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x3f, 0xff, 0xdc, 0xff, 0xfa, 0x03, 0xff, 0xff, 0xff, 0xff, 
    0xff, 0xff, 0xff, 0xff, 0xd8, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xf8, 0x03, 0xff, 0xff, 0xff, 0xff, 
    0xff, 0xff, 0xff, 0xff, 0xd0, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xf8, 0x01, 0xff, 0xff, 0xff, 0xff, 
    0xff, 0xff, 0xff, 0xff, 0x90, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xf8, 0x02, 0xff, 0xff, 0xff, 0xff, 
    0xff, 0xff, 0xff, 0xff, 0xb0, 0x00, 0x0f, 0xf5, 0xff, 0xd7, 0xf8, 0x01, 0xff, 0xff, 0xff, 0xff, 
    0xff, 0xff, 0xff, 0xff, 0xb0, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x5f, 0xff, 0xff, 0xff, 
    0xff, 0xff, 0xff, 0xff, 0xa0, 0x00, 0x0f, 0xfb, 0xff, 0xff, 0xf0, 0x00, 0x3f, 0xff, 0xff, 0xff, 
    0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x0f, 0xfd, 0xff, 0xdf, 0xf0, 0x00, 0x3f, 0xff, 0xff, 0xff, 
    0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x07, 0xff, 0xff, 0xbf, 0xf0, 0x00, 0x0f, 0xff, 0xff, 0xff, 
    0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x07, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x87, 0xff, 0xff, 0xff, 
    0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x03, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x43, 0xff, 0xff, 0xff, 
    0xff, 0xff, 0xff, 0xff, 0x60, 0x00, 0x01, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x73, 0xff, 0xff, 0xff, 
    0xff, 0xff, 0xff, 0xfe, 0xe0, 0x00, 0x00, 0xff, 0xff, 0xff, 0x80, 0x00, 0x7b, 0xff, 0xff, 0xff, 
    0xff, 0xff, 0xff, 0xfd, 0xe0, 0x00, 0x00, 0x7f, 0xff, 0xfe, 0x00, 0x00, 0x33, 0xff, 0xff, 0xff, 
    0xff, 0xff, 0xff, 0xfd, 0xe0, 0x00, 0x00, 0x3f, 0xff, 0xf8, 0x00, 0x00, 0x27, 0xff, 0xff, 0xff, 
    0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x0f, 0xff, 0xf0, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xff, 
    0xff, 0xff, 0xff, 0xff, 0x60, 0x00, 0x00, 0x67, 0xff, 0xe0, 0x00, 0x00, 0x1b, 0xff, 0xff, 0xff, 
    0xff, 0xff, 0xff, 0xfd, 0x40, 0x00, 0x00, 0xf3, 0xff, 0xc4, 0x00, 0x00, 0x0b, 0xff, 0xff, 0xff, 
    0xff, 0xff, 0xff, 0xfe, 0x80, 0x00, 0x00, 0xfc, 0xff, 0x8c, 0x00, 0x00, 0x03, 0xff, 0xff, 0xff, 
    0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x7f, 0x3c, 0x3c, 0x00, 0x00, 0x07, 0xff, 0xff, 0xff, 
    0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x3f, 0xc0, 0x7c, 0x00, 0x00, 0x03, 0xff, 0xff, 0xff, 
    0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xfc, 0x00, 0x00, 0x03, 0xff, 0xff, 0xff
};
 
void setup() {
  Serial.begin(115200);
 
  if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
    Serial.println(F("SSD1306 allocation failed"));
    for(;;);
  }
  delay(2000); // Pause for 2 seconds
 
  // Clear the buffer.
  display.clearDisplay();
  
  // Draw bitmap on the screen
  display.drawBitmap(0, 0, image_data_Saraarray, 128, 64, 1);
  display.display();
}
 
void loop() {
  
}

 

 

코드를 업로드한 후 디스플레이에 표시되는 내용입니다.

 

 

ESP32 ESP8266 Arduino OLED 디스플레이 이미지

 

 

문제 해결

 

"SSD1306 할당 실패" 오류가 발생하거나 OLED가 화면에 아무것도 표시하지 않는 경우 다음 문제 중 하나일 수 있습니다.

 

잘못된 I2C 주소

 

사용하는 OLED 디스플레이의 I2C 주소는 0x3C입니다. 그러나 사용자의 주소는 다를 수 있습니다. 따라서 아래에 다시 첨부하는  I2C 스캐너 스케치를 사용하여 디스플레이 I2C 주소를 확인하세요.

 

/*********
  Rui Santos
  Complete project details at https://randomnerdtutorials.com  
*********/

#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);          
}

 

SDA와 SCL이 제대로 연결되지 않음

 

OLED 디스플레이의 SDA 및 SCL 핀이 올바르게 연결되었는지 확인하세요. ESP32의 경우 SDA 핀을 GPIO 21에 연결하고 SCL 핀을 GPIO 22에 연결합니다.

 

마무리

 

EPS8266을 사용한 OLED 디스플레이에 대한 이 가이드가 유용했기를 바랍니다. 이제 OLED 디스플레이를 자신의 프로젝트에 통합할 수 있습니다. 다음 튜토리얼로 넘어가서 OLED 디스플레이에 센서 판독값을 표시하는 방법을 알아보세요.

 

ESP32 – 센서 판독값 OLED 디스플레이 표시

 

읽어주셔서 감사합니다. 절대 배움을 멈추지 마세요. 후회하시겠습니까? 실패하시겠습니까?

 

삶은 고통의 연속이니 즐기세요!

 

반응형

더욱 좋은 정보를 제공하겠습니다.~ ^^