본문 바로가기

아두이노우노 R4

아두이노 0.96인치 OLED 디스플레이(SSD1306) 실습

반응형


0.96인치 OLED 디스플레이 사용하기

 

안녕하세요. 이번포스팅에서에는 아두이노로 0.96인치 OLED 디스플레이를 제어하는 방법에 대해서 알아보도록 하겠습니다.

 

OLED 디스플레이 모듈

이번 포스팅에서 사용할 OLED 디스플레이 모듈은 아래 사진같이 크기가 0.96인치 입니다. 0.96인치 외에도 OLED 디스플레이 모듈은 다양한 사이즈와 색상으로 출시되고 있습니다. 아두이노를 사용한 프로젝트에 많이 사용되는 0.96인치 OLED는 128x64픽셀로 이루어져 있으며 이보다 작은 0.91인치 OLED는 128x32픽셀로 이루어져 있습니다.

0.96인치

0.91인치

흰색 OLED

이 모듈은 SSD1306이라는 OLED 구동용 IC 칩에 의해 구동되는데 이 IC칩은 마이크로컨트롤러와 통신하기 위해 I2C와 SPI통신을 지원합니다. 하지만 판매되고 있는 모듈은 대부분 두가지 통신 모드중 하나의 방식의 포트만 노출시켜 판매되기 때문에 둘중에 원하는 방식을 구입하시면 됩니다. 물론 두가지 방식을 모두 지원하는 모듈도 판매되고 있습니다. 이번 포스팅에서는 i2C 방식을 사용해 보겠습니다

 

I2C 방식(좌)과 SPI 방식(우)

0.96인치 oled 모듈(SSD1306)의 스펙은 아래와 같습니다.

디스플레이 방식
OLED (Organic LED)
인터페이스
I2C / SPI
스크린사이즈
0.96 인치
해상도
128×64 pixels
동작전압
3.3V – 5V
동작전류
20mA max
시야각
160°

OLED 모듈에서 사용하는 SSD1306 드라이버 칩은 내부에 1KB용량의 그래픽 디스플레이 전용 램(GDDRAM)이 내장되어 있어서 디스플레이 패널에 표시할 비트패턴을 저장하는 방식으로 동작합니다. 이 1K 메모리용량은 8개의 페이지(0-7번)으로 이루어져 있고 8개의 페이지는 각각 128개의 세로 줄(0-127번)로 구성되어 있습니다. 각각의 세로줄은 8개의 비트정보(0-7번)를 저장할 수 있기 때문에 이를 계산해보면

8페이지 x 128 개의 세로줄 x 8비트 데이타 = 8192비트 = 1024바이트 = 1KB 메모리 용량

이 됩니다.

위에서 말한 페이지, 세로줄, 세로줄의 비트를 그림으로 표현하면 아래와 같습니다.

SSD1306의 메모리 표현

위 그림에서 작은 사각형 하나는 OLED의 램에 저장된 데이터정보를 표시하는 픽셀의 기능을 합니다.

128x64 OLED스크린은 전체 램의 용량을 다 사용하지만 128x32OLED는 4페이지까지만 있기 때문에 전체 램 용량중 반만 사용하게 됩니다.

회로연결

아두이노버전에 따라 I2C 연결용 핀이 다르기 때문에 사용하시는 아두이노 모델에따라 OLED 모듈의 SCL, SDA핀을 아두이노의 SCL, SDA핀과 연결하면 됩니다.

아두이노
SCL
SDA
아두이노 우노
A5
A4
아두이노 나노
A5
A4
아두이노 메가
21
20
레오나르도/마이크로
3
2

OLED모듈의 VCC핀과 GND 핀은 각각 아두이노의 5V, GND 핀과 연결하면됩니다. 아두이노 우노버전을 기준으로 아래 그림과 같이 연결하면 됩니다.

 

라이브러리 설치하기

SSD1306을 라이브러리 없이 직접제어하는 것은 상당히 복잡하기 때문에 대부분 OLED모듈을 제어할 때는 라이브러리를 사용하게 되는데요. SSD1306제어용 라이브러리는 여러 종류가 있습니다. 그 중에서 가장 많이 사용되는 Adafruit사의 라이브러리를 설치해 보도록 하겠습니다.

우선 라이브러리 설치를 위해 [스케치]-[라이브러리 포함하기]-[라이브러리 관리]를 눌러 줍니다.

 

그리고 아래그림과 같이 라이브러리 매니저가 뜨면 adafruit gfx 라고 입력하고 해당 라이브버리를 설치해 줍니다. 이 라이브러리는 adafruit의 디스플레이 모듈의 그래픽 관련 처리를 도와주는 라이브러리라고 합니다. adafruit의 ssd1306의 동작에도 활용되기 때문에 설치가 필요합니다.

 

 

두번째로 adafruit ssd1306라이브러리를 설치해 줍니다. 아래 사진과 같이 adafruit ssd1306을 입력해 해당 라이브러리를 설치하면 됩니다.

 

예제 실행해보기

이제 제대로 동작하는지 확인하기 위해서 라이브러리의 예제를 실행해 보겠습니다. 아래 사진과 같이 [파일]-[예제]-[Adafruit SSD1306]-[ssd1306_128_64_i2c]를 클릭해서 예제 파일을 열어 줍니다.

 

스케치 파일에 보면 display.begin( )함수에 주소가 0x3D로 기본으로 설정되어 있는데 자신이 사용하는 모듈의 I2C주소로 바꿔 줘야 합니다. 이번 포스팅에서 사용한 모듈은 I2C 주소가 0x3C이기 떄문에 아래와 같이 0x3C로 바꿔주면 됩니다.

 

그리고 나서 스케치를 아두이노에 업로드 하면 아래 영상과 같이 예제 화면이 순서대로 순회하며 바뀌는 것을 확인 할 수 있습니다.

 
재생2,118
 
좋아요0
 
 
 
 
  •  
  •  

 

접기/펴기

adafruit ssd1306 oled 예제 구동

예제별 코드확인

위 예제파일은 구동여부를 확인해 보는 용도로는 좋지만 코드가 길어서 동작의 이해에는 어려움이 있습니다. oled 라이브러리의 사용법을 알아보기 위해 예제별로 코드를 하나씩 확인해 보도록 하겠습니다.

아래 코드는 아래 예제에서 공통적으로 필요한 부분으로 필요한 라이브러리를 불러오고 해상도를 지정한 뒤에 디스플레이 객체를 생성하는 부분입니다.

#include <Wire.h> //i2c통신을 사용하기 때문에 아두이노의 i2c 통신용 라이브러리가 필요 #include <Adafruit_GFX.h> // adafruit의 그래픽 관련 라이브러리 #include <Adafruit_SSD1306.h> // ssd1306 제어용 라이브러리 #define SCREEN_WIDTH 128 // OLED 디스플레이의 가로 픽셀수 #define SCREEN_HEIGHT 64 // OLED 디스플레이의 세로 픽셀수 #define OLED_RESET 4 // 리셋핀이 있는 oled의 리셋핀에 연결할 아두이노의 핀 번호, 리셋핀이 없는 모듈은 임의의 숫자를 넣어도 됨. Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET); // 디스플레이 객체 생성

아래 부분은 OLED 모듈을 초기화 하고 OLED 모듈의 버퍼(램)을 비우는 코드 입니다.

// 0x3C주소로 디스플레이 장치를 초기화 display.begin(SSD1306_SWITCHCAPVCC, 0x3C); // 버퍼를 비움 display.clearDisplay();

이제 간단한 기능별로 코드를 살펴 보겠습니다.

【문자표시하기】

- 간단한 문자 표시(Hello world!)-

// 문자표시하기 display.clearDisplay(); display.setTextSize(1); display.setTextColor(WHITE); display.setCursor(0,28); display.println("Hello world!"); display.display(); delay(2000);

문자를 스크린에 표시하려면 폰트사이즈를 먼저 지정해 주어야 합니다. 폰트사이즈는 setTextSize( ) 함수에 폰트사이즈 값을 파라미터로 넣어 주면 되고 최소값은 1부터 시작합니다.

폰트색상는 setTextColor() 함수에 사용할 색상값을 파라미터로 입력해 주면 됩니다. 어두운 배경일 때는 WHITE를 밝은 배경일 때는 BLACK를 넣어 주면 됩니다.(사용하는 OLED모듈의 글자 색상이 파란색이어도 WHITE를 입력하면 됩니다.)

문자를 입력할 위치는 setCursor(X, Y)함수를 통해 지정할 수 있습니다. 파라미터로 입력한 X, Y의 값대로 수평으로 X, 수직을 Y의 위치에서 글자를 시작하게 됩니다. 원점인 0, 0은 OLED 모듈의 왼쪽 상단이고 +X는 오른쪽으로 +Y는 아래쪽으로 증가하는 방식으로 동작합니다.

 

출력할 글자는 시리얼 통신에 문자를 출력하는 방식과 마찬가지로 print(" "), 또는 println(" ")함수에 넣은 메시지를 출력합니다. 이 함수는 ATmega328내의 스크린 버퍼에 전달되어 저장되었다가 display( )함수가 호출되면 OLED모듈의 램으로 전달되어 바로 화면으로 출력이 이루어 집니다. 따라서 display( ); 함수를 사용하기 전까지는 OLED 디스플레이의 화면이 바뀌지 않습니다.

-반전문자표시-

// 반전문자표시하기 display.clearDisplay(); display.setTextColor(BLACK, WHITE); // 'inverted' text display.setCursor(0,28); display.println("Hello world!"); display.display(); delay(2000);

반전문자를 표시하기 위해서는 setTextColor( ) 함수에 파라미터로 글자색상과 함께 배경색상을 지정해 주면 됩니다. 위 코드에서 입력한 BLACK, WHITE는 하얀 배경에 검정색으로 글씨를 쓰라는 의미가 되어 반전된 글자가 출력되게 됩니다.

-글자크기 변경-

// 글자 사이즈 변경 display.clearDisplay(); display.setTextColor(WHITE); display.setCursor(0,24); display.setTextSize(2); display.println("Hello!"); display.display(); delay(2000);

위에서 언급했다시피 글자 사이즈를 지정하는 함수는 setTextSize( )함수입니다. 위에서는 파라미터로 최소 1부터 입력할 수 있으며 음수는 음력할 수 없습니다. 여기에 넣은 숫자는 가로:세로 7:10의 비율로 확장되어 출력된다고 하는데요. 이말을 1을 입력하면 한문자당 7픽셀x10픽셀을 차지하게 된다는 의미입니다. 따라서 숫자 2를 입력하면 한문자당 14x20픽셀을 차지하게 됩니다.

문자폰트는 Adafruit_GFX에 의해 처리되는데 기본 폰트는 mono-spaced 폰트로 설정되어 있다고 합니다. 이 라이브러리를 통해 다른 폰트를 사용하거나 추가할 수 있다고 하니 폰트 변경을 원한다면 해당 라이브러리를 자세히 살펴보시면 될 것 같네요.

-숫자표시-

// 숫자표시하기 display.clearDisplay(); display.setTextSize(1); display.setCursor(0,28); display.println(123456789); display.display(); delay(2000);

숫자는 print( ) 또는 println( ) 함수에 문자대신 숫자를 입력하면 되는데요. 파라미터는 32bit unsigned int 값을 받아 들일 수 있기 때문에 0에서 4,294,967,295.까지의 숫자를 넣을 수 있습니다.

-진법표시-

//진법 표시하기 display.clearDisplay(); display.setCursor(0,28); display.print("0x"); display.print(0xFF, HEX); display.print("(HEX) = "); display.print(0xFF, DEC); display.println("(DEC)"); display.display(); delay(2000);

print( )또는 println( ) 함수에 두번째 파라미터로 표현하고 싶은 진법을 넣으면 해당 숫자와 숫자 옆에 괄호로 (진법)이 표시됩니다. 파라미터로는 2진법은 BIN, 8진법은 OCT, 십진법은 DEC, 16진법은 HEX를 넣으면 됩니다.

만약 실수표현에서 두번째 파라미터로 숫자를 넣으면 소수점 뒤에 표현할 숫자의 갯수를 의미합니다. 예를 들면 아래와 같습니다.

print(78, BIN) ===> “1001110”

print(78, OCT) ===> “116”

print(78, DEC) ===> “78”

print(78, HEX) ===> “4E”

println(1.23456, 0) ===> “1”

println(1.23456, 2) ===> “1.23”

println(1.23456, 4) ===> “1.2346”

-아스키 문자 표시하기-

// 아스키 문자 표시하기 display.clearDisplay(); display.setCursor(0,24); display.setTextSize(2); display.write(3); display.display(); delay(2000);

print( ) 함수와 println( ) 함수는 데이터를 사람이 읽을 수 있는 ASCII 문자로 변환해서 디스플레이에 표시하는 반면 write( ) 함수는 넣은 숫자에 해당하는 아스키테이블의 심볼을 표시하게 됩니다. 아래표는 아스키심볼 테이블의 일부입니다.

 

-문자스크롤링하기-

 

// 문자스크롤링하기 display.clearDisplay(); display.setCursor(0,0); display.setTextSize(1); display.println("Full"); display.println("screen"); display.println("scrolling!"); display.display(); display.startscrollright(0x00, 0x07); delay(2000); display.stopscroll(); delay(1000); display.startscrollleft(0x00, 0x07); delay(2000); display.stopscroll(); delay(1000); display.startscrolldiagright(0x00, 0x07); delay(2000); display.startscrolldiagleft(0x00, 0x07); delay(2000); display.stopscroll();

수평방향의 문자스크롤링은 오른쪽 스크롤링의 경우 startscrollright( ) 함수를 왼쪽 스크롤링은 startcrollleft( ) 함수를 통해 실행할 수 있습니다. 이 함수들에 파라미터로 집어 넣는 2개의 값이 전체 화면 중에서 스크롤을 시킬 범위를 지정하는데 사용됩니다. 위에서 언급한바와 같이 0.96인치 OLED를 기준으로 0에서 7까지의 8개의 페이지로 구분되기 때문에 전체 화면이 스크롤링되게 하려면 파라미터에 0x00과 0x07을 입력하면 됩니다. 위 함수가 실행된 뒤에 스크롤을 머출 때에는 stopscroll( ) 함수를 실행하면 됩니다.

-원하는 줄만 스크롤링하기-

 
// 일부분만 스크롤되게 하기 display.setCursor(0,0); display.setTextSize(1); display.println("Scroll"); display.println("some part"); display.println("of the screen."); display.display(); display.startscrollright(0x00, 0x00);

여러줄로 이루어진 문자열에서 일부분만 스크롤되도록 만들고 싶을때도 있을 거십니다. 이때는 startscrollright( ) 함수와 startscrollleft( ) 함수의 시작페이지와 정지 페이지를 파라미터로 입력할 때 원하는 줄에 해당하도록 입력하면 됩니다. 위에서 0x00은 첫번째 시작페이지를 의미하고 0x00는 정지페이지도 첫번째 줄이기 때문에 첫번째 줄의 문자만 스크롤하게 된 것입니다. 만약 2번째줄과 3번째 줄만 스크롤되게 하고 싶다면 파라미터로 (0x01, 0x02) 를 입력해 주면 됩니다.

【기초 도형 표시하기】

이번에는 그림을 표시하는 방법에 대해서 예제별로 살펴보도록 하겠습니다.

- 사각형 그리기 -

display.clearDisplay(); display.setTextSize(1); display.setTextColor(WHITE); display.setCursor(0,0); display.println("Rectangle"); display.drawRect(0, 15, 60, 40, WHITE); display.display(); delay(2000); display.clearDisplay(); display.setTextSize(1); display.setTextColor(WHITE); display.setCursor(0,0); display.println("Filled Rectangle"); display.fillRect(0, 15, 60, 40, WHITE); display.display(); delay(2000);

사각형을 그리기 위해서는 drawRect( ) 함수를 사용하면 됩니다. 이 함수는 5개의 파라미터를 넣을 수 있는데요. 사각형을 그리기 시작하는 시작점(왼쪽 위 모서리)의 x좌표, y좌표, 가로길이, 세로길이, 색상 의 5개를 넣으면 됩니다. 이 함수는 기본으로는 1픽셀 만큼의 선 두께를 가진 사각형을 그리게 되는데요. 만약 꽉 채워진 사각형을 그리고자 한다면 fillRect( )함수를 사용하면 됩니다.

- 모서리가 둥근 사각형 그리기 -

display.clearDisplay(); display.setTextSize(1); display.setTextColor(WHITE); display.setCursor(0,0); display.println("Round Rectangle"); display.drawRoundRect(0, 15, 60, 40, 8, WHITE); display.display(); delay(2000); display.clearDisplay(); display.setTextSize(1); display.setTextColor(WHITE); display.setCursor(0,0); display.println("Filled Round Rectangl"); display.fillRoundRect(0, 15, 60, 40, 8, WHITE); display.display(); delay(2000);

모서리가 둥근 사각형을 그리고자 한다면 drawRect( ) 함수 대신에 drawRoundRect( ) 함수를 사용하면 됩니다. 이 함수는 위에서 사용한 drawRect( ) 함수와 동일한 파라미터에 추가적으로 한개의 파라미터를 더 받아 들입니다. 이 파라미터는 코너의 반경입니다. 이 반경값을 조절하면 모서리의 둥근정도를 조절할 수 있습니다. 만약 내부가 채워진 사각형을 그리고자 한다면 fillRoundRect( ) 함수를 사용하면 됩니다.

display.clearDisplay(); display.setTextSize(1); display.setTextColor(WHITE); display.setCursor(0,0); display.println("Triangle"); display.drawTriangle(30, 15, 0, 60, 60, 60, WHITE); display.display(); delay(2000); display.clearDisplay(); display.setTextSize(1); display.setTextColor(WHITE); display.setCursor(0,0); display.println("Filled Triangle"); display.fillTriangle(30, 15, 0, 60, 60, 60, WHITE); display.display(); delay(2000);

삼각형은 drawTryangle( ) 함수를 통해 그릴수 있습니다. 이 함수는 7개의 파라미터를 받아 들이며 이 중 첫번째부터 6번째까지의 파라미터는 삼각형 세 모서리의 x, y 좌표이고 마지막 7번째 파라미터는 삼각형의 색상을 지정합니다. 이 함수도 기본적으로는 1픽셀의 선 두께를 가진 삼각형을 그리고 내부가 채워진 삼각형을 그릴때는 fillTriangle( ) 함수를 사용하면 됩니다.

【비트맵 이미지 표시하기】

마지막 예제로서 OLED 디스플레이에 어떻게 비트맵이미지를 표시하는지 확인해 보겠습니다. 이 방법은 회사의 로고나 이미지 그 밖의 재밌는 그래픽이나 정보를 표시할 때 유용한 방법입니다. 일단 아래 코드를 복사해서 아두이노에 업로드 해 보겠습니다. (코드가 길어서 블로그에 넣어지지 않아서 3개로 나눴습니다.)

#include <SPI.h> #include <Wire.h> #include <Adafruit_GFX.h> #include <Adafruit_SSD1306.h> #define SCREEN_WIDTH 128 #define SCREEN_HEIGHT 64 #define OLED_RESET 4 Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);

// 마를린 먼로 이미지

const unsigned char MarilynMonroe [] PROGMEM = {

0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,

0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x1f, 0xff, 0xff, 0xf0, 0x41, 0xff, 0xff, 0xff, 0xff, 0xff,

0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x7f, 0xff, 0xff, 0xf8, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff,

0xff, 0xff, 0xff, 0xff, 0xff, 0xf9, 0xff, 0xff, 0xff, 0xe0, 0x07, 0xff, 0xff, 0xff, 0xff, 0xff,

0xff, 0xff, 0xff, 0xff, 0xff, 0x87, 0xff, 0xff, 0xff, 0xf8, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff,

0xff, 0xff, 0xff, 0xff, 0xff, 0x07, 0xff, 0xff, 0xff, 0xf8, 0x01, 0xf1, 0xff, 0xff, 0xff, 0xff,

0xff, 0xff, 0xff, 0xff, 0xff, 0x9f, 0xff, 0xff, 0xff, 0xf8, 0x00, 0xf8, 0xff, 0xff, 0xff, 0xff,

0xff, 0xff, 0xff, 0xff, 0xff, 0xbf, 0xff, 0xff, 0xff, 0xfc, 0x02, 0x78, 0x7f, 0xff, 0xff, 0xff,

0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x3f, 0xff, 0xff, 0xfe, 0x03, 0x7c, 0x1f, 0xff, 0xff, 0xff,

0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x07, 0xff, 0xff, 0xfe, 0x01, 0xfe, 0x1f, 0xff, 0xff, 0xff,

0xff, 0xff, 0xff, 0xff, 0xfd, 0xe0, 0x03, 0xff, 0xff, 0xfc, 0x00, 0xfe, 0x0f, 0xff, 0xff, 0xff,

0xff, 0xff, 0xff, 0xff, 0xfe, 0x87, 0xe0, 0xff, 0xff, 0xfc, 0x00, 0x06, 0x07, 0xff, 0xff, 0xff,

0xff, 0xff, 0xff, 0xff, 0xfc, 0x1f, 0xf9, 0xff, 0xff, 0xfc, 0x00, 0x02, 0x07, 0xff, 0xff, 0xff,

0xff, 0xff, 0xff, 0xff, 0xf8, 0x1f, 0xff, 0xff, 0xff, 0xfc, 0x00, 0xc3, 0xc3, 0xff, 0xff, 0xff,

0xff, 0xff, 0xff, 0xff, 0xf0, 0x3f, 0xff, 0xff, 0xe0, 0x0c, 0x00, 0xe7, 0x81, 0xff, 0xff, 0xff,

0xff, 0xff, 0xff, 0xff, 0xf0, 0x0f, 0xff, 0xff, 0xe0, 0x02, 0x00, 0x02, 0x00, 0xff, 0xff, 0xff,

0xff, 0xff, 0xff, 0xff, 0xf0, 0x0f, 0xff, 0xff, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff,

0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x3f, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x1e, 0x3f, 0xff, 0xff,

0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x0f, 0xff, 0x3f, 0xf8, 0x00, 0x18, 0x7f, 0x1f, 0xff, 0xff,

0xff, 0xff, 0xff, 0xf8, 0x01, 0x80, 0x03, 0xfc, 0x3f, 0xfc, 0x00, 0x70, 0xfe, 0x1f, 0xff, 0xff,

0xff, 0xff, 0xff, 0xf0, 0x43, 0xff, 0xff, 0xf8, 0x7f, 0xf8, 0x00, 0x00, 0x7e, 0x1f, 0xff, 0xff,

0xff, 0xff, 0xff, 0xe0, 0x07, 0xff, 0xff, 0xf0, 0xff, 0xfc, 0x00, 0x00, 0x7c, 0x3f, 0xff, 0xff,

0xff, 0xff, 0xff, 0xe0, 0x0f, 0xff, 0xff, 0xf1, 0xef, 0xf8, 0x00, 0x01, 0xfc, 0x3f, 0xff, 0xff,

0xff, 0xff, 0xff, 0xe4, 0xff, 0xff, 0xff, 0xf3, 0x80, 0xa0, 0x00, 0x07, 0xfc, 0xaf, 0xff, 0xff,

0xff, 0xff, 0xff, 0xec, 0x5f, 0xff, 0xff, 0xe7, 0xf0, 0x00, 0x00, 0x03, 0xfe, 0xdf, 0xff, 0xff,

0xff, 0xff, 0xff, 0xee, 0x7f, 0xff, 0xff, 0xc7, 0xf8, 0x00, 0x00, 0x03, 0xff, 0xdf, 0xff, 0xff,

0xff, 0xff, 0xff, 0xfe, 0x7f, 0xff, 0xf7, 0xc7, 0xff, 0x06, 0x00, 0x03, 0xff, 0xbf, 0xff, 0xff,

0xff, 0xff, 0xff, 0xfe, 0x5f, 0xff, 0xc7, 0x07, 0xff, 0x80, 0x00, 0x07, 0xdb, 0xbf, 0xff, 0xff,

0xff, 0xff, 0xff, 0xee, 0xff, 0xff, 0x80, 0x03, 0xff, 0xc0, 0x00, 0x03, 0xc3, 0x0f, 0xff, 0xff,

0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0x98, 0x03, 0xff, 0xf8, 0x00, 0x07, 0xe0, 0x0f, 0xff, 0xff,

0xff, 0xff, 0xff, 0xef, 0xff, 0xff, 0xf8, 0x01, 0xff, 0xfc, 0x01, 0x07, 0xfc, 0x1f, 0xff, 0xff,

0xff, 0xff, 0xff, 0xcf, 0xef, 0xff, 0xff, 0xe1, 0xff, 0xfc, 0x01, 0x07, 0xf8, 0x1f, 0xff, 0xff,

0xff, 0xff, 0xff, 0x9f, 0xff, 0xff, 0x7f, 0xf1, 0xff, 0xf8, 0x02, 0x07, 0x88, 0x3f, 0xff, 0xff,

0xff, 0xff, 0xff, 0xcf, 0xef, 0xf8, 0x0f, 0xff, 0xff, 0xe0, 0x00, 0x07, 0x84, 0x3f, 0xff, 0xff,

0xff, 0xff, 0xff, 0xe7, 0xef, 0xf0, 0x04, 0x7f, 0xff, 0xc0, 0x00, 0x07, 0x84, 0x7f, 0xff, 0xff,

0xff, 0xff, 0xff, 0x3f, 0xff, 0xe0, 0x00, 0x1f, 0xff, 0x80, 0x00, 0x06, 0x04, 0xff, 0xff, 0xff,

0xff, 0xff, 0xff, 0x3f, 0x7f, 0xe1, 0xf0, 0x07, 0xff, 0x80, 0x00, 0x07, 0x06, 0xff, 0xff, 0xff,

0xff, 0xff, 0xff, 0xff, 0xff, 0xc3, 0xfe, 0x03, 0xff, 0x00, 0x00, 0x03, 0x80, 0xff, 0xff, 0xff,

0xff, 0xff, 0xff, 0xf2, 0x3f, 0xc6, 0x7f, 0x81, 0xce, 0x00, 0x00, 0x01, 0xc1, 0xff, 0xff, 0xff,

0xff, 0xff, 0xff, 0xe0, 0x3f, 0xc0, 0x07, 0xc1, 0xfe, 0x00, 0x00, 0x0d, 0xc0, 0x7f, 0xff, 0xff,

0xff, 0xff, 0xff, 0xe0, 0x3f, 0xc0, 0x01, 0xe0, 0xfc, 0x00, 0x00, 0x0f, 0xc0, 0x7f, 0xff, 0xff,

0xff, 0xff, 0xff, 0xc0, 0x3f, 0xc0, 0x00, 0x50, 0xfc, 0x00, 0x00, 0x0e, 0xc0, 0xff, 0xff, 0xff,

0xff, 0xff, 0xff, 0xc0, 0x3f, 0xc0, 0x00, 0x18, 0xf8, 0x00, 0x00, 0x0e, 0xc1, 0xff, 0xff, 0xff,

0xff, 0xff, 0xff, 0xc0, 0x3f, 0xc0, 0x00, 0x00, 0xf8, 0x00, 0x00, 0x66, 0x81, 0xff, 0xff, 0xff,

0xff, 0xff, 0xff, 0xc0, 0x1f, 0xc7, 0x80, 0x00, 0xf8, 0x00, 0x01, 0xe0, 0x00, 0xff, 0xff, 0xff,

0xff, 0xff, 0xff, 0xc0, 0x1f, 0xc1, 0xe0, 0x01, 0xf8, 0x00, 0x03, 0xf0, 0x01, 0xff, 0xff, 0xff,

0xff, 0xff, 0xff, 0x80, 0x1f, 0xc0, 0x3e, 0x03, 0xf0, 0x00, 0x00, 0xe0, 0x03, 0xff, 0xff, 0xff,

0xff, 0xff, 0xff, 0x00, 0x1f, 0xe0, 0xe0, 0x03, 0xf2, 0x00, 0x00, 0xc0, 0x03, 0xff, 0xff, 0xff,

0xff, 0xff, 0xff, 0x80, 0x1f, 0xf0, 0x00, 0x07, 0xe6, 0x00, 0x00, 0xc0, 0x03, 0xff, 0xff, 0xff,

0xff, 0xff, 0xff, 0x80, 0x1f, 0xff, 0x00, 0x1f, 0xee, 0x00, 0x00, 0x80, 0x07, 0xff, 0xff, 0xff,

0xff, 0xff, 0xff, 0xb8, 0x0f, 0xff, 0xf0, 0x3f, 0xdc, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xff,

0xff, 0xff, 0xff, 0xbc, 0x0f, 0xff, 0xff, 0xff, 0xdc, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xff,

0xff, 0xff, 0xff, 0x9e, 0x0f, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff,

0xff, 0xff, 0xff, 0x08, 0x0f, 0xff, 0xff, 0xff, 0x70, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff,

0xff, 0xff, 0xff, 0x00, 0x0b, 0xff, 0xff, 0xfe, 0xe0, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff,

0xff, 0xff, 0xff, 0x00, 0x0b, 0xff, 0xff, 0xf9, 0xc0, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff,

0xff, 0xff, 0xff, 0x3c, 0x09, 0xff, 0xff, 0xf1, 0x80, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xff,

0xff, 0xff, 0xff, 0x1e, 0x08, 0x3f, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xff,

0xff, 0xff, 0xff, 0x1f, 0x08, 0x03, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xff,

0xff, 0xff, 0xff, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff,

0xff, 0xff, 0xff, 0x80, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff,

0xff, 0xff, 0xff, 0xce, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff,

0xff, 0xff, 0xff, 0xfe, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff,

0xff, 0xff, 0xff, 0xff, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xff

};

void setup() { // I2C 주소를 0x3C로 초기화 display.begin(SSD1306_SWITCHCAPVCC, 0x3C); // 버퍼를 비우기 display.clearDisplay(); // 비트맵 이미지 표시 display.drawBitmap(0, 0, MarilynMonroe, 128, 64, WHITE); display.display(); } void loop() {}

그럼 아래와 같이 마를린 먼로의 이미지가 출력이 됩니다. 참고로 위에서 PROGMEM이라는 키워드를 사용한 이유는 배열 변수를 램이아닌 플래시메모리에 저장하라는 의미입니다. 이렇게 하는 이유는 아두이노의 램에 변수를 저장하기에는 이미지를 바이트코드로 변환한 배열의 사이즈가 너무 커서 램용량이 부족해 지기 때문입니다.(아두이노 우노버전을 기준으로 플래시메모리는 32KB인 반면 램은 2KB에 불과합니다)

비트맵이미지를 OLED에 표시하기 위해서는 drawBitmap( ) 이라는 함수를 사용하면 되는데요. 이 함수는 6개의 파라미터를 필요로 합니다. 파라미터는 각각 비트맵 이미지의 왼쪽위 모서리의 x좌표, y좌표, 비트맵이미지의 바이트 배열, 비트맵이미지의 가로길이, 비트맵이미지의 세로길이, 색상 입니다. 우리는 128x64픽셀의 이미지를 사용했기 때문에 X, Y 좌표는 0, 0을 너비와 길이에는 128, 64를 각각 입력한 것입니다.

이런 방식으로 drawBitmap( ) 함수를 사용하면 그림을 표현할 수 있다는 것은 알았는데 어떻게 128x64의 사이즈를 가진 이미지를 얻을 수 있는지 궁금하실 텐데요. Inkscape, 포토샵, Paint 등등의 이미지 편집프로그램을 사용해서 사진의 크기를 128x64로 맞춰주면 됩니다.

이미지 크기 변환

이제 128x64 사이지의 이미지를 얻었다면 이를 어떻게 바이트 배열로 변환할 수 있는지 알아야 겠죠?

- 온라인 비트맵 배열 생성프로그램(image2cpp) -

image2cpp라는 온라인 프로그램을 사용하면 손쉽게 이미지를 바이트 배열로 변환할 수 있습니다. 주소는 여기( http://javl.github.io/image2cpp/ )로 접속하시면 됩니다.. 이 프로그램을 사용하면 우리가 원하는 이미지를 손쉽게 바이트 배열로 바꿀 수 있을 뿐만아니라 이미지 색상반전, 밝기조절, 아두이노 코드로 출력하기 등의 추가 기능도 제공합니다.

예시를 위해 아래와 같은 아두이노 로고 이미지를 한번 디스플레이에 출력해 보도록 하겠습니다.

이미지는 먼저 포토샵이과 같은 이미지 편집프로그램 등을 사용해서 128x64픽셀의 사이즈로 변환시켜 줍니다.

그리고 나서 위에서 말한 image2cpp 웹사이트로 접속합니다.

사이트 접속화면

사이즈에 접속하면 우선 Select image버튼을 클릭해서 변환하고자 하는 이미지 파일을 업로드 합니다.

그다음으로 이미지 세팅에서 사진사이즈는 128x64로 지정해 주고 배경색상을 지정해 줍니다.

3. Preview를 통해 미리보기 기능도 제공이 되는데요. 이상이 없으면 4번에서 Code output format을 Arduino code로 선택하고 generate code 버튼을 눌러줍니다. 그럼 아래에 바이트 배열 코드가 생성이 됩니다.

이제 생성된 배열바이트 코드를 복사해서 아두이노에 마를린 먼로 코드가 있던 곳을 지워고 새로운 코드를 복사해 줍니다.

그리고 drawBitmap의 배열변수도 새로 생성한 배열변수로 수정해 줍니다.

이제 소스코드를 업로드하면 아래 사진처럼 로고가 바뀐 것을 확인 할 수 있습니다.

이제 OLED 모듈 사용 전혀 어렵지 않겠죠?^^ 그럼이만~

참고자료 및 더 읽어보기

반응형

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