스마트디바이스실습 ‐ 12주차 - jiho0419/SmartDevice_2025-1 GitHub Wiki

1️⃣ OLED

*️⃣ 정의

💠 유기 화합물층에서 전류가 흐를 때 스스로 빛을 내는 디스플레이 기술을 말한다.
💠 LCD와 달리 백라이트가 필요 없어 더 얇고 가볍게 제작 가능하다.

*️⃣ 구조 및 동작 원리

💠 기본 구조

🔸 기판(Substrate) : 유리 또는 플라스틱 (유연 OLED의 경우)
🔸 양극(Anode) : 투명 전극 (ITO 등)
🔸 홀 전달층(Hole Transport Layer, HTL)
🔸 발광층(Emissive Layer) : 유기물질이 실제로 빛을 발하는 층
🔸 전자 전달층(Electron Transport Layer, ETL)
🔸 음극(Cathode) : 금속 전극

💠 동작 원리

🔸 전압이 인가되면 양극에서 정공(hole) , 음극에서 전자(electron) 가 주입
🔸 이들이 발광층에서 만나 전자-정공 재결합 이 발생하며, 이때 빛을 방출
🔸 발광층의 유기 화합물 특성에 따라 다양한 색을 구현 가능

*️⃣ 종류

구분 특징
PMOLED (Passive Matrix OLED) 단순 구조, 저해상도에 적합
AMOLED (Active Matrix OLED) 고해상도 구현 가능, 스마트폰 등 주요 제품에 사용
플렉서블 OLED 구부릴 수 있는 OLED, 웨어러블 기기에 적합
투명 OLED 배경이 보이는 디스플레이 구현 가능
마이크로 OLED (Micro OLED) VR/AR용 고밀도 디스플레이에 사용

*️⃣ 장 / 단점

💠 장점

🔸 자체 발광 : 백라이트 불필요 → 얇고 가벼움
🔸 높은 명암비 : 진정한 블랙 구현 가능
🔸 넓은 시야각
🔸 빠른 응답 속도
🔸 디자인 유연성 : 휘거나 접히는 형태 가능

💠 단점

🔸 번인(Burn-in) 현상 : 특정 화소의 수명 감소로 잔상이 남음
🔸 짧은 수명 : 특히 청색 발광체의 수명이 짧음
🔸 높은 제조 비용
🔸 수분·산소에 민감 : 밀봉 기술 필요

2️⃣ I2C

*️⃣ 정의

💠 I2C (Inter-Integrated Circuit) 는 필립스(현 NXP)에 의해 1982년에 개발된 양방향 직렬 통신 프로토콜을 말한다.
💠 두 개의 신호선(SDA, SCL) 만으로 여러 개의 장치와 통신할 수 있다.

*️⃣ 특징

🔸 단순한 2선식 통신 (SDA: 데이터, SCL: 클럭)
🔸 마스터/슬레이브 구조
🔸 다중 슬레이브 및 다중 마스터 가능
🔸 동기식(serial synchronous)
🔸 반이중 방식

*️⃣ 구조 및 동작 원리

💠 물리적 구성

선명 기능
SCL (Serial Clock) 클럭 신호 전송 (마스터가 제공)
SDA (Serial Data) 데이터 송수신 선 (양방향)

🔸 양쪽 모두 풀업 저항(pull-up resistor) 이 필요하며, 신호는 오픈 드레인 방식으로 전송됨

💠 통신 구조

🔸 마스터(Master) : 통신 시작, 클럭 제어
🔸 슬레이브(Slave) : 마스터의 요청에 응답
🔸 주소 체계 : 7비트 또는 10비트 주소 사용 (일반적으로 7비트)

💠 데이터 전송 과정

🔸 Start 조건 : SDA가 High에서 Low로 전이되며 시작
🔸 주소 전송 : 마스터가 슬레이브 주소 + 읽기/쓰기 비트 전송
🔸 ACK/NACK : 슬레이브가 응답 (ACK: 0)
🔸 데이터 전송 : 송신자 → 수신자 (8비트 단위)
🔸 ACK/NACK : 수신자가 응답
🔸 Stop 조건 : SDA가 Low에서 High로 전이되며 종료

*️⃣ 장 / 단점

💠 장점

🔸 단순한 2선식 구성 → 배선 최소화
🔸 다중 슬레이브 연결 용이
🔸 적은 핀으로 다양한 장치 제어 가능
🔸 칩 간 통신 외에도 기판 내부 센서, EEPROM 연결에 적합

💠 단점

🔸 SPI에 비해 느린 속도
🔸 데이터 충돌 방지 위해 소프트웨어 관리 필요
🔸 배선이 길어지면 신호 저하 가능
🔸 풀업 저항 설계 필요

3️⃣ 실습

*️⃣ OLED 디스플레이 문자 표시

💠 ESP32를 이용하여 문자를 OLED 디스플레이에 표시하는 실습 진행

💠 준비물

🔸 ESP32
🔸 ESP32 확장 쉴드
🔸 OLED 디스플레이


💠 회로 연결

ESP32 실드 OLED 디스플레이
S : D21 SDA
S : D22 SCL
VCC VCC
GND GND

💠 코드

#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("Hello, World");

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

💠 라이브러리 설치

🔸 실습을 위해 Adafruit_SSD1306Adafruit_GFX 라이브러리 설치


💠 실습 결과

🔸 OLED 디스플레이에 문자 Hello, World!가 표시됨

*️⃣ OLED 디스플레이 현재 시간 표시

💠 ESP32를 이용하여 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);
}

💠 실습 결과

🔸OLED 디스플레이에 현재 년/월/일 과 현재 시간이 표시되는 것을 확인

⚠️ **GitHub.com Fallback** ⚠️