[실습] PWM 방식 LED 밝기 조절
필기자
19시간 24분전
5
0
본문
PWM 방식 LED 밝기 조절
목 적
1. PWM DutyCycle
2. DutyCycle을 활용한 LED 발기 조절 프로그램
[문제: RGB LED 색상 조합 제어 실습]
목 적
- PWM output 방식을 이해한다.
- DutyCycle에 대해 이해한다.
1. PWM DutyCycle
2. DutyCycle을 활용한 LED 발기 조절 프로그램
2. DutyCycle을 활용한 LED 발기 조절 프로그램
1. PWM DutyCycle
- PWM에서 LED 밝기 조절 공식
- 전압, 전류, 저항, 전력
- 전압 (V) → 수압 (물을 밀어주는 힘)
- 전류 (A) → 수량 (실제 흐르는 물의 양)
- 저항 (Ω) → 파이프 좁기 (굵을수록 저항 작음, 좁을수록 저항 큼)
- 전력 (W) → 물레방아 회전력 (실제 일하는 양)
- 공급 전압 Vsupply = 3.3V (라즈베리파이 GPIO 기준), 저항 R = 50Ω (GPIO 내부 저항), 듀티사이클 80%
- LED 순방향 전압(Vf)은 색상마다 다름 (데이터시트 KY-009 5050 RGB 기준)
- 빨강: 1.8V ~ 2.4V (대표값 2.0V)
- 초록: 2.8V ~ 3.6V (데이터시트 기준, 실사용 시 약 2.7V로 낮아짐)
- 파랑: 2.8V ~ 3.6V (데이터시트 기준, 실사용 시 약 2.7V로 낮아짐)
- LED 밝기 단위 : mcd (밀리칸델라)
- mcd는 특정 방향으로 얼마나 밝게 빛나는지를 나타내는 광도 단위이다.
- 데이터시트 기준값 (KY-009 5050 RGB, 20mA 기준)
- 빨강: 300 ~ 500 mcd
- 초록: 500 ~ 700 mcd
- 파랑: 200 ~ 400 mcd
- 단, 데이터시트 mcd 값은 20mA 정격 전류 기준이므로, 이 실습(GPIO 내부 저항만 사용, 전류 다름)에서는 데이터시트 값을 그대로 적용할 수 없다.
- 정확한 밝기(mcd)와 평균 전류의 비례 관계는 직접 실험으로 측정해야 한다.
- 조도계 (lux meter) 준비
- LED와 조도계 거리 고정
- 듀티사이클 10% ~ 100% 단계별 변화
- 각 단계별 조도 (lux) 측정
- 평균 전류 vs 조도 그래프 작성
- 전압, 전류, 저항, 전력
- 순간 전류 (옴의 법칙):
I = (Vsupply − Vf) / R - 평균 전류 (옴의 법칙 × 듀티사이클) ∝ LED 밝기 :
Iavg = I × 듀티사이클
※ 색상별 순간 전류 (3.3V 기준, R = 50Ω GPIO 내부 저항)
| 색상 | Vf (데이터시트) | Vf (실사용 추정) | 순간 전류 I (mA) I = (3.3 − Vf) / 50 |
mcd (데이터시트, 20mA 기준) |
|---|---|---|---|---|
| 빨강 | 1.8V ~ 2.4V | 2.0V | (3.3 − 2.0) / 50 = 26mA | 300 ~ 500 mcd |
| 초록 | 2.8V ~ 3.6V | 약 2.7V ※ | (3.3 − 2.7) / 50 = 12mA | 500 ~ 700 mcd |
| 파랑 | 2.8V ~ 3.6V | 약 2.7V ※ | (3.3 − 2.7) / 50 = 12mA | 200 ~ 400 mcd |
※ 초록/파랑은 데이터시트 기준 Vf가 3.2V이지만, LED는 비선형 소자이므로 전류가 낮아지면 실제 Vf도 함께 낮아진다. 3.3V GPIO 환경에서는 약 2.7V 수준에서 동작점이 형성되어 정상 발광한다.
※ Keyes CNT1 모듈은 전류 제한 저항이 내장되어 있지 않으므로, GPIO 내부 저항(약 50Ω)만으로 전류가 제한된다. 빨강의 경우 GPIO 핀 권장 전류(16mA)를 초과하므로, 정식 회로 설계 시에는 외부 저항(150Ω 권장) 추가를 권장한다.
※ 위 mcd 값은 20mA 정격 전류 기준이며, 실습 환경의 전류와 다르므로 실제 밝기는 데이터시트 값과 다를 수 있다. 정확한 밝기 측정이 필요한 경우 조도계를 이용한 직접 실험이 필요하다.
빨강 LED 기준 듀티사이클별 평균 전류 (I = 26mA)
| 듀티사이클 (%) | 순간 전류 (mA) I = (3.3−2.0)/50 |
평균 전류 (mA) Iavg = I × 듀티 |
|---|---|---|
| 10% | 26 | 26 × 0.1 = 2.6 |
| 20% | 26 | 26 × 0.2 = 5.2 |
| 30% | 26 | 26 × 0.3 = 7.8 |
| 40% | 26 | 26 × 0.4 = 10.4 |
| 50% | 26 | 26 × 0.5 = 13.0 |
| 60% | 26 | 26 × 0.6 = 15.6 |
| 70% | 26 | 26 × 0.7 = 18.2 |
| 80% | 26 | 26 × 0.8 = 20.8 |
| 90% | 26 | 26 × 0.9 = 23.4 |
| 100% | 26 | 26 × 1.0 = 26.0 |
2. DutyCycle을 활용한 LED 발기 조절 프로그램
- 기본 구동 프로그램 : 라즈베리파이 가상환경에서 파이썬 코딩
- VSCode에서 led_pwm_duty.py 파일 생성
- GPIO 18핀(핀 12)을 출력 모드로 설정
- GPIO 18핀의 DutyCycle을 조절
import RPi.GPIO as GPIO
import time
# GPIO 모드 설정
GPIO.setmode(GPIO.BCM)
# LED 핀 설정
LED_PIN = 18
GPIO.setup(LED_PIN, GPIO.OUT)
# PWM 인스턴스 생성 (주파수 1kHz)
pwm = None
pwm = GPIO.PWM(LED_PIN, 10000)
pwm.start(0) # DutyCycle 0으로 시작 (꺼진 상태)
try:
while True:
# 점점 밝아짐
for dc in range(0, 101, 2):
pwm.ChangeDutyCycle(dc)
print("밝아 짐", dc)
time.sleep(0.1)
time.sleep(2)
# 점점 어두워짐
for dc in range(100, -1, -2):
print("어두워 짐", dc)
pwm.ChangeDutyCycle(dc)
time.sleep(0.1)
time.sleep(1)
except KeyboardInterrupt:
# Ctrl+C 눌렀을 때 실행 종료
pass
finally:
if pwm is not None:
try:
pwm.stop()
except:
pass
del pwm # __del__ 호출 시 오류 방지
GPIO.cleanup()
[문제: RGB LED 색상 조합 제어 실습]
- 3컬러 RGB LED는 아래와 같이 연결되어 있다.
- 빨강: GPIO 18
- 초록: GPIO 23
- 파랑: GPIO 24 (미사용)
- PWM을 사용하여 빨강(R)과 초록(G) 색상의 듀티사이클을 조절한다.
- 색상은 주황 → 노랑 → 연두 → 갈색 순으로 서서히 변화한다.
- R 100 고정 후 G 50→100 (주황→노랑)
- G 100 고정 후 R 100→50 (노랑→연두)
- R 50 고정 후 G 100→30 (연두→갈색)
- G 30 고정 후 R 50→100 (갈색→주황)
- 각 색상은 0.1초 간격으로 부드럽게 전환되도록 한다.
- 색상 전환은 무한 반복되도록 한다.
import RPi.GPIO as GPIO
import time
GPIO.setmode(GPIO.BCM)
R_PIN = 18
G_PIN = 23
GPIO.setup(R_PIN, GPIO.OUT)
GPIO.setup(G_PIN, GPIO.OUT)
pwm_r = None
pwm_g = None
pwm_r = GPIO.PWM(R_PIN, 1000)
pwm_g = GPIO.PWM(G_PIN, 1000)
pwm_r.start(0)
pwm_g.start(0)
try:
while True:
for g in range(50, 101, 5): # 주황 → 노랑
pwm_r.ChangeDutyCycle(100)
pwm_g.ChangeDutyCycle(g)
time.sleep(0.5)
print("주황 -> 노랑")
time.sleep(3)
for r in range(100, 49, -5): # 노랑 → 연두
pwm_r.ChangeDutyCycle(r)
pwm_g.ChangeDutyCycle(100)
time.sleep(0.5)
print("노랑 -> 연두")
time.sleep(3)
for g in range(100, 29, -5): # 연두 → 갈색
pwm_r.ChangeDutyCycle(50)
pwm_g.ChangeDutyCycle(g)
time.sleep(0.5)
print("연두 -> 갈색")
time.sleep(3)
for r in range(50, 101, 5): # 갈색 → 주황
pwm_r.ChangeDutyCycle(r)
pwm_g.ChangeDutyCycle(30)
time.sleep(0.5)
print("갈색 -> 주황")
time.sleep(3)
except KeyboardInterrupt:
# Ctrl+C 눌렀을 때 실행 종료
pass
finally:
if pwm_r is not None:
try:
pwm_r.stop()
except:
pass
del pwm_r # __del__ 호출 시 오류 방지
if pwm_g is not None:
try:
pwm_g.stop()
except:
pass
del pwm_g # __del__ 호출 시 오류 방지
GPIO.cleanup()
댓글목록0