2017 멀티캠퍼스/Raspberry Pi

#4 라즈베리파이 DC Motor

꿈꾸는어린이 2018. 1. 14. 14:35

//

일시 : 2018.01.09 16:00 ~ 18:00

내용 : DC모터

//

GPIO 모터

DC Motor

  • DC Motor는 공급 전류에 비례하여 회전 속도 및 회전력 증가

  • DC Motor 내부 저항 고정 -> 공급 전압에 따라 전류 비례 --> 공급 전압에 따라 회전력, 회전 속도 변화

  • 한 pulse에서 high와 low구간을 달리하여 전압 가변 -> 회전속도 제어

  • 캐패시터 : 갑자기 최대 속도로 모터를 회전시키면 순간적으로 전류 소비 ↑ -> 전류가 부족해지는 것을 막기 위해 전류를 일정 용량 저장하여 공급 전원의 안정화 역할.

  • 회전 방향을 바꾸려면 공급 전원의 극성을 변경

  • short brake 모드 : 브레이크

    stop 모드 : 관성에 따라 멈출때까지 기다림, 브레이크보다 멈추는데 오래걸림

  • DC Motor는 DC_MOTOR_P, DC_MOTOR_N, DC_MOTOR_PWM 신호에 동작

  • DC_MOTOR_P, DC_MOTOR_N은 Low, High 조합에 따라 CW(시계 방향), CCW(시계 반대 방향)로 동작하고 DC_MOTOR_PWM에 따라 회전함. (high일 때 최대속도, low일 때 정지)

  • GPIO.output(GPIO_EN, False) 일 때 0볼트까지 흐름




전류, 전압, 저항

  • 전류 : 전기적 위치 에너지 차에 의하여 전위가 높은쪽에서 낮은 쪽으로의 전하 흐름

  • 전압 : 전하의 흐름에 가해지는 압력의 정도

  • 저항 : 전하의 흐름을 방해하는 정도

  • 전압과 전류는 비례, 전압-전류 그래프에서 직선의 기울기는 저항

  • 전류는 전압에 비례, 저항에 반비례

    V(전압) = I(전류)R(저항) , I = V/R




★★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 신호를 출력할 수 있는 핸들러 포함되어 있음.





실습

DC Motor CW/CCW/Stop/Break

  • time.sleep()함수 : 수행한 문장 중 잠시 딜레이.

    forward 상태에서 그 다음 문자 실행까지 2초 딜레이.

    따라서 forward회전 2초동안 지속.

  
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)
GPIO.setup(GPIO_RN, GPIO.OUT)
GPIO.setup(GPIO_EN, GPIO.OUT)


try:
   while True:
       print ("forward")
       GPIO.output(GPIO_RP, True)
       GPIO.output(GPIO_RN, False)
       GPIO.output(GPIO_EN, True)
       time.sleep(2)
       
       print("stop")
       GPIO.output(GPIO_RP, False)
       GPIO.output(GPIO_RN, False)
       GPIO.output(GPIO_EN, True)
       time.sleep(2)
       
       print ("backward")
       GPIO.output(GPIO_RP, True)
       GPIO.output(GPIO_RN, False)
       GPIO.output(GPIO_EN, True)
       time.sleep(2)
       
       print("break")
       GPIO.output(GPIO_EN, False)
       time.sleep(2)
   
finally:
   GPIO.cleanup()





클래스 이용한 모터

  import RPi.GPIO as GPIO
import time

class motor :
   
   def __init__(self):
       GPIO.setwarnings(False)
       GPIO.setmode(GPIO.BCM)
       self.GPIO_RP = 4 # IN1
       self.GPIO_RN = 25 # IN2
       self.GPIO_EN = 12 # pwm
       GPIO.setup(self.GPIO_RP, GPIO.OUT)
       GPIO.setup(self.GPIO_RN, GPIO.OUT)
       GPIO.setup(self.GPIO_EN, GPIO.OUT)
       
   def __del__(self):
       GPIO.cleanup()
   
   def setDir(self, setV):
       if setV == 'forward':
           GPIO.output(self.GPIO_RP, True)
           GPIO.output(self.GPIO_RN, False)
       elif setV == 'backward':
           GPIO.output(self.GPIO_RP, False)
           GPIO.output(self.GPIO_RN, True)
       else:
           print("정방향 setV : setDir('forward') ")
           print("역방향 setV : setDir('backword') ")
   
   def stop(self):
       GPIO.output(self.GPIO_EN, False)
   
   def shortBreak(self):
       GPIO.output(self.GPIO_RP, True)
       GPIO.output(self.GPIO_RN, True)
       
   def start(self, setV):
       self.setDir(setV)
       GPIO.output(self.GPIO_EN, True)

if __name__ == "__main__":
   try:
       iMotor=motor()
       
       iMotor.start("forward")
       time.sleep(3)
       iMotor.stop()
   except KeyboardInterrupt:
       pass
   finally:
       del(iMotor)