일시 : 2018.01.10
내용 : PWM
//
PWM(Pulse Width Modulation)
Pulse Width Modulation : 펄스 폭 변조
전압의 on(high)/off(low)를 이용해 가변 전압을 얻기 위한 기술
period : 한 사이클의 시간
Duration(pulse 시간) : 한 사이클에서 high 시간
Duty Cycle(사용률): 주기에 대한 on/off 시간의 비
예를 들어 Duty Cycle 20%는 high 20, low 80
주파수(frequency) : 1초에 몇 개의 cycle이 반복되는가. 단위는 Hz.
1Hz => 1초에 period 1번 반복 (1s, 1000ms)
100Hz => 1초에 100번 반복. 이 때 1 pulse는 1/100 초 (0.01s, 10ms)
같은 주파수 100Hz에서 하나의 pulse에 low, high 조절하여 속도 조절 가능.
high구간이 더 길수록 속도가 더 빨라짐.
PWM 발생 방법은 SW PWM과 HW PWM이 있음. SW PWM에서는 딜레이를 넣어 high와 low상태를 변화시키고, HW PWM에서는 타이머 카운터에서 인터럽트를 발생시켜 주기적으로 PWM을 만들어냄.
SW PWM은 정확한 Duty cycle을 제어하기 어려움
SW PWM 출력 GPIO 핀에 PWM 신호를 출력할 수 있는 핸들러 포함되어 있음.
Duty Cycle 실습
- DC Motor PWM
import RPi.GPIO as GPIO
import time
GPIO.setmode(GPIO.BCM)
GPIO_RP = 4
GPIO_RN = 25
GPIO_EN = 12
GPIO.setup(GPIO_RP, GPIO.OUT) # IN1
GPIO.setup(GPIO_RN, GPIO.OUT) # IN2
GPIO.setup(GPIO_EN, GPIO.OUT) # PWM
##단계(1~10)를 넣어 모터의 속도를 조절
def setSpeed(speed,p):
p.ChangeDutyCycle(speed*10)
try:
p = GPIO.PWM(GPIO_EN, 100) # 100hz
p.start(0) # start the PWM on 0% duty cycle
while True:
for i in range(10):
GPIO.output(GPIO_RP, True)
GPIO.output(GPIO_RN, False)
setSpeed(i, p)
time.sleep(1)
finally:
GPIO.cleanup()
import RPi.GPIO as GPIO
import time
GPIO.setmode(GPIO.BCM)
GPIO_RP = 4 # IN1
GPIO_RN = 25 # IN2
GPIO_EN = 12 # pwm
GPIO.setup(GPIO_RP, GPIO.OUT)
GPIO.setup(GPIO_RN, GPIO.OUT)
GPIO.setup(GPIO_EN, GPIO.OUT)
try:
while True:
for i in range(0,100):
print("100HZ, duty bee = 20%")
GPIO.output(GPIO_RP, True)
GPIO.output(GPIO_RN, False)
GPIO.output(GPIO_EN, True)
time.sleep(0.002)
GPIO.output(GPIO_EN, False)
time.sleep(0.008)
for i in range(0,100):
print("100HZ, duty bee = 50%")
GPIO.output(GPIO_RP, True)
GPIO.output(GPIO_RN, False)
GPIO.output(GPIO_EN, True)
time.sleep(0.005)
GPIO.output(GPIO_EN, False)
time.sleep(0.005)
for i in range(0,100):
print("100HZ, duty bee = 80%")
GPIO.output(GPIO_RP, True)
GPIO.output(GPIO_RN, False)
GPIO.output(GPIO_EN, True)
time.sleep(0.008)
GPIO.output(GPIO_EN, False)
time.sleep(0.002)
for i in range(0,100):
print("100HZ, duty bee = 100%")
GPIO.output(GPIO_RP, True)
GPIO.output(GPIO_RN, False)
GPIO.output(GPIO_EN, True)
time.sleep(0.01)
finally:
GPIO.cleanup()
- LED PWM
led 밝기 조절
import RPi.GPIO as GPIO
import time
GPIO.setmode(GPIO.BCM)
led_pin1 = 14
led_pin2 = 15
GPIO.setup(led_pin1, GPIO.OUT)
GPIO.setup(led_pin2, GPIO.OUT)
##단계(1~10)를 넣어 LED 밝기를 조절
def setLight(light, p):
p.ChangeDutyCycle(light*10)
try:
p = GPIO.PWM(led_pin1, 100)
p.start(0)
while True :
for i in range(10):
GPIO.output(led_pin1, True)
GPIO.output(led_pin2, False)
p.ChangeDutyCycle(i*10)
setLight(i, p)
time.sleep(1)
except KeyboardInterrupt:
pass
finally:
GPIO.cleanup()
LED 하나는 점점 밝아지고, 하나는 점점 어두워지게
import RPi.GPIO as GPIO
import time
GPIO.setmode(GPIO.BCM)
led_pin1 = 14
led_pin2 = 15
GPIO.setup(led_pin1, GPIO.OUT)
GPIO.setup(led_pin2, GPIO.OUT)
def setLight(light, p):
p.ChangeDutyCycle(light)
try:
p1 = GPIO.PWM(led_pin1, 100)
p2 = GPIO.PWM(led_pin2, 100)
p1.start(0)
p2.start(0)
while True :
# 첫번째 LED 점점 밝아지게
for i in range(10):
GPIO.output(led_pin1, True)
p1.ChangeDutyCycle(i*10)
setLight(i * 10, p1)
time.sleep(0.5)
# 두번째 LED 점점 어두워지게
for j in range(10, -1, -1):
p2.start(100)
GPIO.output(led_pin2, True)
p2.ChangeDutyCycle(j*10)
setLight(j * 10, p2)
time.sleep(0.5)
except KeyboardInterrupt:
pass
finally:
GPIO.cleanup()
'2017 멀티캠퍼스 > Raspberry Pi' 카테고리의 다른 글
#11 라즈베리파이 조도센서 (0) | 2018.01.30 |
---|---|
#10 라즈베리파이 Ultrasonic (초음파 센서) (0) | 2018.01.30 |
#8 라즈베리파이 Piezo 센서 (0) | 2018.01.30 |
#7 라즈베리파이 I2C 통신 (0) | 2018.01.14 |
#6 라즈베리파이 PIR 센서 (움직임 감지) (0) | 2018.01.14 |