13주차 스마트디바이스 (OLED 활용) - jungjaeyeol/jyeol03 GitHub Wiki

OLED 디스플레이

✅ OLED란?

OLED(Organic Light Emitting Diode, 유기 발광 다이오드)는 유기 화합물이 전류에 의해 스스로 빛을 내는 자발광 디스플레이 기술입니다.
백라이트가 필요 없고, 얇고 유연한 형태로 제작이 가능합니다.

🧬 구조

  • 기판 (Substrate): 유리 또는 플라스틱 재질
  • 양극 (Anode): 정공(hole)을 공급
  • 유기층 (Organic Layer):
    • HTL (정공 수송층)
    • EML (발광층)
    • ETL (전자 수송층)
  • 음극 (Cathode): 전자(electron)를 공급

⚙️ 특징

항목 설명
자발광 백라이트 없이 스스로 빛을 냄
얇고 유연함 플렉서블 디스플레이 구현 가능
고명암비 완전한 블랙 표현 가능
빠른 응답속도 영상 잔상 거의 없음
넓은 시야각 다양한 각도에서도 색상 유지

🔍 장단점

✔ 장점

  • 백라이트 불필요 → 얇고 가벼움
  • 픽셀 단위 온/오프 → 완전한 블랙 구현
  • 플렉서블 구현 가능 (폴더블, 롤러블 등)
  • 고명암비 및 빠른 반응속도

❌ 단점

  • 번인(Burn-in) 현상 가능성
  • 제조 단가 높음
  • 파란색 유기물 수명이 짧음

🔄 OLED vs LCD

항목 OLED LCD
발광 방식 자발광 백라이트 필요
명암비 매우 높음 낮음
두께 매우 얇음 상대적으로 두꺼움
시야각 넓음 좁음
응답속도 빠름 느림
번인 가능성 있음 없음

📌 활용 분야

  • 스마트폰 (삼성 Galaxy, Apple iPhone 등)
  • OLED TV (LG, Sony 등)
  • 스마트워치 및 웨어러블 기기
  • 차량용 디스플레이
  • AR/VR 디바이스

I2C 인터페이스

✅ I2C란?

I2C(Inter-Integrated Circuit)는 **NXP(구 Philips)**에서 개발한 양방향 직렬 통신 프로토콜입니다.
마이크로컨트롤러와 다양한 주변 장치 간의 짧은 거리 통신에 사용됩니다.

🧪 기본 특성

  • 통신 방식: 마스터-슬레이브 (Master-Slave)
  • 버스 구조: 2선식 (SDA, SCL)
  • 속도:
    • Standard mode: 100 kbps
    • Fast mode: 400 kbps
    • Fast mode plus: 1 Mbps
    • High-speed mode: 최대 3.4 Mbps
  • 전송 거리: 수십 cm 내외 (보통 짧은 거리)
  • 전압: 3.3V 또는 5V에서 동작 가능

🔌 핀 구성

핀 이름 설명
SDA (Serial Data) 데이터 송수신
SCL (Serial Clock) 클럭 신호 전송

모든 장치가 이 두 선을 공유하여 통신함

🧭 통신 동작 방식

  1. 마스터가 통신 시작(Start condition)을 전송
  2. 슬레이브 주소 전송 (7bit 또는 10bit)
  3. 슬레이브가 ACK(응답) 전송
  4. 데이터 송수신
  5. 마스터가 통신 종료(Stop condition) 전송

🧵 마스터-슬레이브 구조

  • 하나의 마스터가 여러 슬레이브를 제어 가능
  • 하나의 버스에 여러 장치 연결 가능
  • 슬레이브는 고유한 주소를 가짐

💡 장점

  • 핀 수가 적어 간단한 연결 가능
  • 하나의 버스로 여러 장치 제어 가능
  • 슬레이브 주소 기반 통신

⚠️ 단점

  • 속도가 느림 (고속 통신엔 부적합)
  • 버스 상의 충돌 가능성 있음
  • 거리 제한이 있음

📌 주요 활용 예시

  • 센서 (온도, 습도, 가속도계 등)
  • EEPROM, RTC 등 메모리 모듈
  • LCD, OLED 디스플레이
  • 마이크로컨트롤러 간 통신

📌 실습 (ESP32 OLED 적용)

  • 코드
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 32

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

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

  // OLED 디스플레이 초기화
  if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
    Serial.println("SSD1306 오류");
    while (true);
  }

  // OLED 디스플레이 클리어
  display.clearDisplay();
}

void loop() {
  // "Hello, World!"를 크기가 다른 세 개의 텍스트로 표시
  display.clearDisplay();
  
  // 크기 6의 폰트로 텍스트 표시
  display.setTextSize(1);
  display.setTextColor(WHITE);
  display.setCursor(0, 0);
  display.println("Hello, World!");

  // 크기 8의 폰트로 텍스트 표시
  display.setTextSize(2);
  display.setTextColor(WHITE);
  display.setCursor(0, 15);
  display.println("Arduino");

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

📌 실습2 (NTP 서버 활용 OLED 시간 나타내기)

  • 코드
#include <WiFi.h>  // WiFi 통신을 위한 라이브러리
#include <time.h>  // 시간과 관련된 함수를 위한 라이브러리

#include <Adafruit_GFX.h>      // 디스플레이를 위한 그래픽 라이브러리
#include <Adafruit_SSD1306.h>  // SSD1306 OLED 디스플레이를 위한 라이브러리
// SSD1306 디스플레이 객체 초기화
Adafruit_SSD1306 display = Adafruit_SSD1306(128, 32, &Wire, -1);

const char* ssid = "Your_SSID";          // 여기에 사용하는 WiFi 네트워크 이름 (SSID)을 입력하세요
const char* password = "Your_Password";  // 여기에 사용하는 WiFi 네트워크 비밀번호를 입력하세요

int GMTOffset = 60 * 60 * 9;  // 시간 오프셋 설정, 한국은 UTC/GMT +9입니다.
int daylightOffset = 0;       // 국가에서 서머타임을 사용하는 경우 오프셋 값을 설정하세요.

const String weekDays[7] = { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" };  // 요일 이름 배열

void setup() {
  Serial.begin(115200);  // 디버깅을 위한 시리얼 통신 시작

  // SSD1306 디스플레이 초기화
  if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
    Serial.println(F("SSD1306 초기화 실패"));
    while (1)
      ;  // 디스플레이 초기화에 실패하면 프로그램 실행 중지
  }

  delay(2000);                  // 2초 동안 대기
  display.clearDisplay();       // 디스플레이 지우기
  display.setTextSize(1);       // 텍스트 크기를 1로 설정
  display.setCursor(0, 0);      // 커서 위치를 디스플레이 왼쪽 위 모서리로 설정
  display.setTextColor(WHITE);  // 텍스트 색상을 흰색으로 설정

  WiFi.begin(ssid, password);  // 제공된 SSID와 비밀번호를 사용하여 WiFi 네트워크에 연결
  while (WiFi.status() != WL_CONNECTED) {
    delay(1000);
    Serial.println("Connecting...");
  }

  Serial.println("Connected to Wi-Fi!");
  // 시간 설정을 위한 NTP 서버 설정
  configTime(GMTOffset, daylightOffset, "pool.ntp.org", "time.nist.gov");
}


void loop() {

  // 현재 시간 가져오기
  time_t rawtime = time(nullptr);
  struct tm* timeinfo = localtime(&rawtime);

  // 시리얼 모니터에 날짜 출력
  Serial.print(timeinfo->tm_mday);
  Serial.print("/");
  Serial.print(timeinfo->tm_mon + 1);
  Serial.print("/");
  Serial.print(timeinfo->tm_year + 1900);

  Serial.print(" ");

  // 시리얼 모니터에 시간 출력
  Serial.print("Time: ");
  Serial.print(timeinfo->tm_hour);
  Serial.print(":");
  Serial.print(timeinfo->tm_min);
  Serial.print(":");
  Serial.println(timeinfo->tm_sec);

  // OLED 디스플레이 초기화
  display.clearDisplay();
  display.setTextSize(3);
  display.setTextColor(WHITE);
  display.setCursor(0, 0);

  // 시간 출력
  if (timeinfo->tm_hour < 10)
    display.print("0");
  display.print(timeinfo->tm_hour);

  display.print(":");

  if (timeinfo->tm_min < 10)
    display.print("0");
  display.print(timeinfo->tm_min);

  display.print(":");

  // 초 출력
  display.setTextSize(2);
  display.setCursor(102, 5);

  if (timeinfo->tm_sec < 10)
    display.print("0");
  display.print(timeinfo->tm_sec);

  // 날짜 출력
  display.setTextSize(1);
  display.setCursor(0, 25);
  display.print(timeinfo->tm_mday);
  display.print("/");
  display.print(timeinfo->tm_mon + 1);
  display.print("/");
  display.print(timeinfo->tm_year + 1900);

  display.print(" ");
  display.print(weekDays[timeinfo->tm_wday]);

  // 디스플레이에 표시
  display.display();

  delay(1000);
}

☢️ 주의 사항

  • 1번 실습을 실행하기 전 Adafruit_SSD1306 라이브러리와 Adafruit_GFX 라이브러리 두 가지 라이브러리를 설치하기
⚠️ **GitHub.com Fallback** ⚠️