I2C OLED 모듈

아두위키 : Arduwiki


개요

아두이노 OLED 모듈은 작은 크기와 높은 해상도를 가진 디스플레이 모듈로, 다양한 프로젝트에 활용될 수 있습니다. OLED(Organic Light Emitting Diode) 기술을 기반으로 하여, 뛰어난 색감과 명암비를 제공합니다.


OLED 작동 원리

  • 유기 물질: OLED는 얇은 유기 물질 층을 포함하고 있으며, 이 층이 전류에 의해 빛을 발산합니다. 유기 화합물은 전기적 자극을 받을 때 발광하는 특성을 가지고 있습니다.
  • 전극: OLED 패널은 일반적으로 두 개의 전극(양극과 음극)으로 구성되어 있으며, 전기가 흐르면 유기 물질이 전자를 방출하고, 이 전자와 정공이 결합하여 빛을 생성합니다.


SSD1306

SSD1306은 OLED 디스플레이를 구동하기 위한 드라이버 IC(집적 회로)입니다.

1KB의 그래픽 디스플레이 전용 RAM(GDDRAM)을 내장하고 있어 이를 통해 표시할 비트 패턴을 저장합니다.

항목 설명
메모리 용량 1KB (8192비트)
페이지 수 8 페이지 (페이지 0-7)
세로 줄 수 128 세로 줄 (세로 줄 0-127)
비트 정보 각 세로 줄당 8 비트 (비트 0-7)
계산 8 페이지 x 128 세로 줄 x 8 비트 = 8192 비트 = 1024 바이트(1KB)


사양

항목 설명
화면 크기 0.91인치, 0.96인치, 1.3인치, 2.42인치 등 다양한 크기
해상도 128x64 픽셀 또는 128x32픽셀
디스플레이 타입 OLED (Organic Light Emitting Diode)
색상 흑백 (화이트 또는 블루)
인터페이스 I2C (2선)
전압 3.3V ~ 5V
전력 소모 대기 전력: 약 0.1mA, 최대 전력: 약 20mA


활용 예제

회로 구성

OLED 모듈 핀 아두이노 우노/나노 아두이노 메가
VCC 5V 또는 3.3V 5V 또는 3.3V
GND GND GND
SCL A5 21
SDA A4 22

장치 주소 확인

I2C 버스에 연결된 장치의 주소를 찾기 위해 사용되는 코드입니다.

아래 소개될 예제들을 실행하기 이전에 I2C Scanner를 먼저 실행해 모듈의 주소를 확인해주세요.

#include <Wire.h>

void setup() {
  Serial.begin(9600); // 시리얼 통신 시작
  Wire.begin();       // I2C 버스 시작
  Serial.println("I2C Scanner 시작...");
}

void loop() {
  byte error, address;
  int nDevices = 0;

  Serial.println("I2C 장치 검색 중...");

  for (address = 1; address < 127; address++) {
    // I2C 장치에 연결 시도
    Wire.beginTransmission(address);
    error = Wire.endTransmission();

    if (error == 0) {
      Serial.print("장치 발견! 주소: 0x");
      if (address < 16) {
        Serial.print("0");
      }
      Serial.print(address, HEX);
      Serial.println();
      nDevices++;
    } else if (error == 4) {
      Serial.print("주소 0x");
      Serial.print(address, HEX);
      Serial.println("에 오류 발생!");
    }
  }

  if (nDevices == 0) {
    Serial.println("I2C 장치가 발견되지 않았습니다.");
  } else {
    Serial.println("장치 검색 완료.");
  }

  delay(5000); // 5초 대기 후 다시 스캔
}


실행 결과


라이브러리

Adafruit SSD1306 라이브러리를 사용합니다.

SSD1306 설치시 추가로 요구하는 Adafruit BusIO, Adafruit GFX Library도 INSTALL ALL을 눌러 함께 설치해주세요.


1. 라이브러리 기본 제공 예제

File - Examples - Adafruit SSD1306 - ssd1306_128x64 i2c 를 클릭하여 예제를 열어주세요.


예제 코드 속 Address 부분을 이전에 I2C Scanner로 확인한 장치 주소로 변경해주세요.


실행 결과


2. 텍스트 출력

간단한 텍스트를 출력하는 예제입니다.

0.91인치 OLED를 사용했으며 이 모듈의 경우 128 x 32픽셀이기 때문에 6번째 줄 SCREEN_HEIGHT를 64에서 32로 변경했습니다.

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

#define SCREEN_WIDTH 128  // OLED 화면의 너비
#define SCREEN_HEIGHT 32   // OLED 화면의 높이

// OLED 모듈의 I2C 주소 (일반적으로 0x3D 또는 0x3C)
#define OLED_ADDR 0x3C 

// Adafruit_SSD1306 객체 생성
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);

void setup() {
  // OLED 초기화
  display.begin(SSD1306_SWITCHCAPVCC, OLED_ADDR);
  display.clearDisplay(); // 화면 지우기
  display.setTextSize(1); // 텍스트 크기 설정
  display.setTextColor(SSD1306_WHITE); // 텍스트 색상 설정
  display.setCursor(0, 0); // 커서 위치 설정
  display.println("GONGZIPSA"); // 텍스트 출력
  display.setCursor(0, 10); // 커서 위치 설정
  display.println("ArduWiki"); // 텍스트 출력
  display.display(); // 화면에 출력
}

void loop() {
  // 루프에서는 아무 작업도 하지 않음
}


사용된 함수들의 역할은 다음과 같습니다.

함수 이름 설명
begin() OLED 디스플레이를 초기화합니다. I2C 주소와 해상도를 설정합니다.
clearDisplay() 현재 디스플레이의 내용을 지웁니다. 화면을 초기화합니다.
setTextSize(size) 출력할 텍스트의 크기를 설정합니다. size는 배율을 나타냅니다. (예: 1, 2 등)
setTextColor(color) 텍스트의 색상을 설정합니다. 일반적으로 SSD1306_WHITE, SSD1306_BLACK를 사용합니다.
setCursor(x, y) 텍스트를 출력할 위치를 설정합니다. x는 가로 위치, y는 세로 위치입니다.

(0, 0)이 왼쪽 상단이며 x가 커지면 오른쪽, y가 커지면 아래로 이동합니다.

println("출력 내용") 출력할 내용을 설정합니다.
display() 버퍼에 저장된 내용을 OLED 디스플레이에 출력합니다.


실행 결과


3. 간단한 도형 출력

사각형, 삼각형, 원 등 간단한 도형들을 출력하는 예제입니다.

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

#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
#define OLED_ADDR 0x3C 

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

void setup() {
  display.begin(SSD1306_SWITCHCAPVCC, OLED_ADDR);
  display.clearDisplay(); // 화면 초기화
  display.drawTriangle(10, 10, 40, 30, 10, 30, WHITE); // 작은 삼각형 
  display.drawRect(50, 10, 30, 20, WHITE); // 사각형
  display.fillRect(90, 10, 30, 20, WHITE); // 채워진사각형
  display.drawCircle(25, 50, 13, WHITE); // 원
  display.drawRoundRect(50, 40, 30, 20, 7, WHITE); // 모서리가 둥근 사각형
  display.fillRoundRect(90, 40, 30, 20, 7, WHITE); // 모서리가 둥근 채워진 사각형
  display.display();
}

void loop() {
  
}


도형과 관련된 함수들은 다음과 같습니다.

함수 이름 설명
drawLine(x1, y1, x2, y2, color) 두 점을 연결하는 선을 그립니다.
drawRect(x, y, width, height, color) 빈 사각형을 그립니다.
fillRect(x, y, width, height, color) 채워진 사각형을 그립니다.
drawCircle(x, y, radius, color) 빈 원을 그립니다.
fillCircle(x, y, radius, color) 채워진 원을 그립니다.
drawTriangle(x1, y1, x2, y2, x3, y3, color) 삼각형을 그립니다.
drawRoundRect(x, y, width, height, radius, color) 둥근 모서리가 있는 사각형을 그립니다.
fillRoundRect(x, y, width, height, radius, color) 채워진 둥근 모서리 사각형을 그립니다.


실행결과


4. 아스키 코드 출력

아스키 코드 표에 대응하는 1~8번 문자를 출력하는 예제입니다.

더 많은 문자를 출력하시려면 아스키 코드 표를 참고하세요.

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

#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
#define OLED_ADDR 0x3C 

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

void setup() {
  display.begin(SSD1306_SWITCHCAPVCC, OLED_ADDR);
  display.clearDisplay(); // 화면 초기화

  // 텍스트 출력 설정
  display.setTextSize(1);       // 텍스트 크기 설정
  display.setTextColor(WHITE);  // 텍스트 색상 설정
  display.setCursor(0, 0);      // 커서 위치 설정

  // 아스키 코드 문자 출력
  display.println("ASCII Code Print");

  // 아스키 코드 문자 출력
  for (char c = 1; c < 9; c++) { // 아스키 코드 1부터 8까지
    display.print(c);                // 각 문자 출력
    display.print(" ");              // 공백 추가
  }

  display.display(); // 버퍼 내용을 화면에 출력
}

void loop() {
  // 반복할 작업이 없으므로 빈 상태
}


실행 결과


5. 비트맵 이미지 출력

이미지를 바이트 배열로 변환하여 OLED에서 출력하는 예제입니다.


이미지를 바이트 배열로 변환하는 방법

1. image2cpp (javl.github.io) 로 접속합니다.

2. 이미지 업로드

좌측 Select image에서 파일을 선택하여 업로드합니다.

3. 이미지 세팅

Canvas size에 이미지 사이즈를 입력하신 후, Preview를 확인합니다. 이미지가 너무 큰데 Canvas 이미지를 작게 만드는 등 사이즈 조절이 잘 못 된다면 Preview에 정상적으로 이미지가 출력되지 않습니다.


4. 출력

Code output format을 Arduino Code로 설정하신 후 Generate code를 누르면 아래에 배열이 출력됩니다.

출력된 배열을 복사하여 예제 코드에서 활용하세요.


예제 코드

drawBitmap(x, y, bitmap, width, height, color) 함수를 사용하여 지정된 위치에 비트맵 이미지를 그립니다.

color는 흰색으로 설정되어 있어 이미지를 흰색으로 표시합니다.


12번째 줄 const unsigned char ~ 부분을 위에서 만든 바이트 배열로 변경하여 활용하세요.

예제 이미지(64 x 64 사이즈)와 사이즈가 다르다면 56번째 줄 drawBitmap 함수의 x, y 커서 위치, width, height 사진 크기를 변경해주셔야 합니다.

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

#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
#define OLED_ADDR 0x3C 

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

// GONGZIPSA LOGO
const unsigned char GONGZIPSA [] PROGMEM = { 
	0xff, 0xff, 0xff, 0xf0, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x7f, 0xff, 0xff, 
	0xff, 0xff, 0xf0, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x03, 0xff, 0xff, 
	0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xff, 
	0xff, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 
	0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x03, 0xff, 0xff, 0x80, 0x00, 0x10, 0x00, 0x40, 0x01, 0xff, 
	0xff, 0x00, 0x00, 0x30, 0x00, 0xe0, 0x00, 0xff, 0xff, 0x00, 0x00, 0x70, 0x00, 0xf0, 0x00, 0xff, 
	0xfe, 0x00, 0x00, 0xf0, 0x00, 0xf8, 0x00, 0x7f, 0xfc, 0x00, 0x01, 0xf0, 0x00, 0xfc, 0x00, 0x3f, 
	0xf8, 0x00, 0x03, 0xf0, 0x00, 0xfc, 0x00, 0x1f, 0xf8, 0x00, 0x03, 0xf0, 0x00, 0xff, 0x00, 0x1f, 
	0xf0, 0x00, 0x07, 0xf0, 0x00, 0xff, 0xe0, 0x07, 0xff, 0x80, 0x3e, 0xf0, 0x01, 0xff, 0xf8, 0x7f, 
	0xbf, 0xf1, 0xff, 0xe0, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x03, 0xff, 0xff, 0xf7, 
	0xdf, 0xff, 0xff, 0xf0, 0x0f, 0xef, 0xff, 0xf3, 0xc7, 0xdf, 0xff, 0xf0, 0x0f, 0xe7, 0xff, 0x63, 
	0xc3, 0xff, 0xfc, 0xb0, 0x0f, 0xef, 0xff, 0xe3, 0x81, 0xff, 0xf9, 0xb0, 0x0f, 0xff, 0xff, 0xc1, 
	0x80, 0xff, 0xf1, 0x70, 0x07, 0xff, 0xcd, 0xc1, 0x80, 0xf9, 0xfc, 0xf0, 0x0f, 0xff, 0xef, 0xc1, 
	0x80, 0xc9, 0xff, 0xf0, 0x0f, 0xff, 0xff, 0xe1, 0x80, 0x5c, 0xff, 0xe0, 0x07, 0xfb, 0xff, 0xc1, 
	0x00, 0x7f, 0xcf, 0xe0, 0x07, 0xfb, 0xff, 0xc0, 0x00, 0x3f, 0xcf, 0xc0, 0x03, 0xff, 0xff, 0x80, 
	0x00, 0x1f, 0xff, 0x80, 0x01, 0xff, 0xff, 0x80, 0x00, 0x0f, 0xff, 0x00, 0x00, 0x7f, 0xff, 0x00, 
	0x00, 0x07, 0xff, 0x80, 0x00, 0xff, 0xfe, 0x00, 0x00, 0x01, 0xff, 0x80, 0x00, 0xff, 0xf4, 0x00, 
	0x00, 0x00, 0x7f, 0xc0, 0x01, 0xff, 0x90, 0x00, 0x00, 0x00, 0xff, 0xe0, 0x03, 0xff, 0x80, 0x00, 
	0x80, 0x00, 0xff, 0xe0, 0x03, 0xff, 0x80, 0x01, 0x80, 0x00, 0x73, 0x30, 0x02, 0x07, 0x00, 0x01, 
	0x80, 0x71, 0xcb, 0x4e, 0x7d, 0x78, 0xf0, 0x81, 0x81, 0xf3, 0xec, 0xdf, 0x7f, 0xfd, 0xf1, 0x81, 
	0x81, 0x06, 0x2c, 0xf0, 0x0b, 0xc7, 0x01, 0x81, 0xc1, 0x04, 0x7c, 0xe0, 0x13, 0xcf, 0x83, 0x83, 
	0xc3, 0x3c, 0x7a, 0xe6, 0x23, 0xf9, 0xf2, 0xc3, 0xc3, 0x1c, 0x73, 0xe2, 0x63, 0x80, 0x16, 0xc3, 
	0xe3, 0x1c, 0x53, 0xe2, 0xc3, 0x80, 0x17, 0xc7, 0xe3, 0xf7, 0xd1, 0xff, 0xf7, 0x83, 0xfc, 0xc7, 
	0xf1, 0xe3, 0x91, 0x3f, 0xff, 0x03, 0xc8, 0x4f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x0f, 
	0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 
	0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 
	0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 
	0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x03, 0xff, 
	0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xff, 
	0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 
	0xff, 0xff, 0xc0, 0x00, 0x00, 0x03, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x0f, 0xff, 0xff, 
	0xff, 0xff, 0xfe, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x0f, 0xff, 0xff, 0xff
};

void setup() {
  display.begin(SSD1306_SWITCHCAPVCC, OLED_ADDR);
  display.clearDisplay(); // 화면 초기화
}

void loop() {
  display.clearDisplay(); // 화면 지우기

  // 64x64 비트맵 이미지 그리기
  display.drawBitmap(32, 0, GONGZIPSA, 64, 64, WHITE); // (x, y, bitmap, width, height, color)

  display.display(); // 버퍼 내용을 화면에 출력
}

실행 결과

플리커링 현상 때문에 모습 촬영 시에 잘려서 보이지만 실제로는 동그란 로고가 깔끔하게 출력되었습니다.


구매 링크

공집사몰