2017 멀티캠퍼스/Raspberry Pi

#9 라즈베리파이 PWM

꿈꾸는어린이 2018. 1. 30. 15:19

//

일시 : 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()