Raspberry Pi 라즈베리파이로 모터 돌리기

지토·2022년 5월 4일
0

장비 사용 매뉴얼

목록 보기
6/8

Raspberry Pi 로 모터 굴리기

PCA 9685 를 사용하지 않고 GPIO 만 사용해서 모터 컨트롤하기

다음과 같이 연결한다.

13
# -*- coding: utf-8 -*-
from RPi import GPIO
import time
from time import sleep
import sys
import tty
import termios

from driving_class import Drive


def getch():
    fd = sys.stdin.fileno()
    old_settings = termios.tcgetattr(fd)
    try:
        tty.setraw(sys.stdin.fileno())
        ch = sys.stdin.read(1)
    finally:
        termios.tcsetattr(fd, termios.TCSADRAIN, old_settings)
    return ch


pins = {
    'ENA_1': 4,
    'IN1_1': 17,
    'IN2_1': 18,

    'ENA_2': 13,
    'IN3_1': 24,
    'IN4_1': 25,

    'ENB_1': 23,
    'IN1_2': 19,
    'IN2_2': 26,


    'ENB_2': 21,
    'IN3_2': 20,
    'IN4_2': 16,
}


car = Drive(pins=pins)


while True:
    char = getch()

    if(char == "w"):
        print("leftup_diagonal")
        car.leftup_diagonal()
        time.sleep(1)
    if(char == "e"):
        print("forward")
        car.forward()
        time.sleep(2)
    if(char == "r"):
        print("rightup_diagonal")
        car.rightup_diagonal()
        time.sleep(1)
    if(char == "s"):
        print("left")
        car.left()
        time.sleep(1)
    if(char == "d"):
        print("Program ended")
        break
    if(char == "f"):
        print("right")
        car.right()
        time.sleep(1)
    if(char == "x"):
        print("leftdown_diagonal")
        car.leftdown_diagonal()
        time.sleep(1)
    if(char == "c"):
        print("backward")
        car.backward()
        time.sleep(1)
    if(char == "v"):
        print("rightdown_diagonal")
        car.rightdown_diagonal()
        time.sleep(1)

GPIO.cleanup()

참조하고 있는 Drive Class 는 다음과 같다.

# -*- coding: utf-8 -*-
from RPi import GPIO
 
class Drive(object):
   def __init__(self, pins):
 
     
       GPIO.setwarnings(False)
       GPIO.setmode(GPIO.BCM)
 
       self.pins = pins
 
       GPIO.setup(self.pins['ENA_1'], GPIO.OUT)
       GPIO.setup(self.pins['IN1_1'], GPIO.OUT)
       GPIO.setup(self.pins['IN2_1'], GPIO.OUT)
       GPIO.setup(self.pins['ENB_1'], GPIO.OUT)
       GPIO.setup(self.pins['IN3_1'], GPIO.OUT)
       GPIO.setup(self.pins['IN4_1'], GPIO.OUT)
       GPIO.setup(self.pins['ENA_2'], GPIO.OUT)
       GPIO.setup(self.pins['IN1_2'], GPIO.OUT)
       GPIO.setup(self.pins['IN2_2'], GPIO.OUT)
       GPIO.setup(self.pins['ENB_2'], GPIO.OUT)
       GPIO.setup(self.pins['IN3_2'], GPIO.OUT)
       GPIO.setup(self.pins['IN4_2'], GPIO.OUT)
 
       self.pwm1 = GPIO.PWM(self.pins['ENA_1'], 50)
       self.pwm2 = GPIO.PWM(self.pins['ENB_1'], 50)
       self.pwm3 = GPIO.PWM(self.pins['ENA_2'], 50)
       self.pwm4 = GPIO.PWM(self.pins['ENB_2'], 50)
 
       self.pwm1.start(50)
       self.pwm2.start(50)
       self.pwm3.start(50)
       self.pwm4.start(50)
  
   def forward(self, speed):
       self.pwm1.ChangeDutyCycle(speed)
       GPIO.output(self.pins['IN1_1'],True)
       GPIO.output(self.pins['IN2_1'],False)
 
       self.pwm2.ChangeDutyCycle(speed)
       GPIO.output(self.pins['IN3_1'],True)
       GPIO.output(self.pins['IN4_1'],False)
 
       self.pwm3.ChangeDutyCycle(speed)
       GPIO.output(self.pins['IN1_2'],True)
       GPIO.output(self.pins['IN2_2'],False)
 
       self.pwm4.ChangeDutyCycle(speed)
       GPIO.output(self.pins['IN3_2'],True)
       GPIO.output(self.pins['IN4_2'],False)
 
   def backward(self, speed):
       self.pwm1.ChangeDutyCycle(speed)
       GPIO.output(self.pins['IN1_1'],False)
       GPIO.output(self.pins['IN2_1'],True)
 
       self.pwm2.ChangeDutyCycle(speed)
       GPIO.output(self.pins['IN3_1'],False)
       GPIO.output(self.pins['IN4_1'],True)
 
       self.pwm3.ChangeDutyCycle(speed)
       GPIO.output(self.pins['IN1_2'],False)
       GPIO.output(self.pins['IN2_2'],True)
 
       self.pwm4.ChangeDutyCycle(speed)
       GPIO.output(self.pins['IN3_2'],False)
       GPIO.output(self.pins['IN4_2'],True)
      
   def left(self):
       self.pwm1.ChangeDutyCycle(self.speed)
       GPIO.output(self.pins['IN1_1'],False)
       GPIO.output(self.pins['IN2_1'],True)
       self.pwm2.ChangeDutyCycle(self.speed)
       GPIO.output(self.pins['IN3_1'],True)
       GPIO.output(self.pins['IN4_1'],False)
       self.pwm3.ChangeDutyCycle(self.speed)
       GPIO.output(self.pins['IN1_2'],True)
       GPIO.output(self.pins['IN2_2'],False)
       self.pwm4.ChangeDutyCycle(self.speed)
       GPIO.output(self.pins['IN3_2'],False)
       GPIO.output(self.pins['IN4_2'],True)
 
   def right(self):
       self.pwm1.ChangeDutyCycle(self.speed)
       GPIO.output(self.pins['IN1_1'],True)
       GPIO.output(self.pins['IN2_1'],False)
       self.pwm2.ChangeDutyCycle(self.speed)
       GPIO.output(self.pins['IN3_1'],False)
       GPIO.output(self.pins['IN4_1'],True)
       self.pwm3.ChangeDutyCycle(self.speed)
       GPIO.output(self.pins['IN1_2'],False)
       GPIO.output(self.pins['IN2_2'],True)
       self.pwm4.ChangeDutyCycle(self.speed)
       GPIO.output(self.pins['IN3_2'],True)
       GPIO.output(self.pins['IN4_2'],False)
 
   def leftup_diagonal(self):
       """
       pwm1.ChangeDutyCycle(speed)
       GPIO.output(IN1_1,False)
       GPIO.output(IN2_1,False)
       """
       self.pwm2.ChangeDutyCycle(self.speed)
       GPIO.output(self.pins['IN3_1'],True)
       GPIO.output(self.pins['IN4_1'],False)
       self.pwm3.ChangeDutyCycle(self.speed)
       GPIO.output(self.pins['IN1_2'],True)
       GPIO.output(self.pins['IN2_2'],False)
       """
       pwm4.ChangeDutyCycle(speed)
       GPIO.output(IN3_2,False)
       GPIO.output(IN4_2,False)
       """
 
   def rightup_diagonal(self):
       self.pwm1.ChangeDutyCycle(self.speed)
       GPIO.output(self.pins['IN1_1'],True)
       GPIO.output(self.pins['IN2_1'],False)
       """
       pwm2.ChangeDutyCycle(speed)
       GPIO.output(IN3_1,False)
       GPIO.output(IN4_1,False)
 
       pwm3.ChangeDutyCycle(speed)
       GPIO.output(IN1_2,False)
       GPIO.output(IN2_2,False)
 
       """
       self.pwm4.ChangeDutyCycle(self.speed)
       GPIO.output(self.pins['IN3_2'],True)
       GPIO.output(self.pins['IN4_2'],False)
 
   def leftdown_diagonal(self):
       self.pwm1.ChangeDutyCycle(self.speed)
       GPIO.output(self.pins['IN1_1'],False)
       GPIO.output(self.pins['IN2_1'],True)
       """
       pwm2.ChangeDutyCycle(speed)
       GPIO.output(IN3_1,False)
       GPIO.output(IN4_1,False)
       pwm3.ChangeDutyCycle(speed)
       GPIO.output(IN1_2,False)
       GPIO.output(IN2_2,False)
       """
       self.pwm4.ChangeDutyCycle(self.speed)
       GPIO.output(self.pins['IN3_2'],False)
       GPIO.output(self.pins['IN4_2'],True) 
 
   def rightdown_diagonal(self):
       """
       pwm1.ChangeDutyCycle(speed)
       GPIO.output(IN1_1,False)
       GPIO.output(IN2_1,False)
       """
       self.pwm2.ChangeDutyCycle(self.speed)
       GPIO.output(self.pins['IN3_1'],False)
       GPIO.output(self.pins['IN4_1'],True)
       self.pwm3.ChangeDutyCycle(self.speed)
       GPIO.output(self.pins['IN1_2'],False)
       GPIO.output(self.pins['IN2_2'],True)
       """
       pwm4.ChangeDutyCycle(speed)
       GPIO.output(IN3_2,False)
       GPIO.output(IN4_2,False)
       """
   def rightturn(self):
       self.pwm1.ChangeDutyCycle(self.speed)
       GPIO.output(self.pins['IN1_1'],True)
       GPIO.output(self.pins['IN2_1'],False)
       self.pwm2.ChangeDutyCycle(self.speed)
       GPIO.output(self.pins['IN3_1'],False)
       GPIO.output(self.pins['IN4_1'],True)
       self.pwm3.ChangeDutyCycle(self.speed)
       GPIO.output(self.pins['IN1_2'],True)
       GPIO.output(self.pins['IN2_2'],False)
       self.pwm4.ChangeDutyCycle(self.speed)
       GPIO.output(self.pins['IN3_2'],False)
       GPIO.output(self.pins['IN4_2'],True)
 
   def leftturn(self):
       self.pwm1.ChangeDutyCycle(self.speed)
       GPIO.output(self.pins['IN1_1'],False)
       GPIO.output(self.pins['IN2_1'],True)
       self.pwm2.ChangeDutyCycle(self.speed)
       GPIO.output(self.pins['IN3_1'],True)
       GPIO.output(self.pins['IN4_1'],False)
       self.pwm3.ChangeDutyCycle(self.speed)
       GPIO.output(self.pins['IN1_2'],False)
       GPIO.output(self.pins['IN2_2'],True)
       self.pwm4.ChangeDutyCycle(self.speed)
       GPIO.output(self.pins['IN3_2'],True)
       GPIO.output(self.pins['IN4_2'],False)
 
 
# if __name__ == '__main__':
#     pins = {
#         'ENA_1': 1
#     }
#     car = Drive(pins=pins)

GPIO 배경지식

라즈베리파이에는 GPIO (General Purpose Input / Output : 다용도 입출력) 핀이 있다.

![7](https://user-image13s.githubusercontent.com/52185595/100460340-575bcc80-310a-11eb-9837-a65ca2cb87c0.png)

GPIO 란 입력이나 출력을 포함한 동작이 런타임 시에 사용자에 의해 제어될 수 있는 집적 회로나 전기 회로 기판의 디지털 신호 핀이다.

DC 모터를 원하는 대로 움직이기 위해서는 PWM 제어가 필요하다.

PWM 제어 예시

1-1) RPi.GPIO 모듈

import RPi.GPIO as GPIO

GPIO.setmode(GPIO.BOARD) / 핀 번호를 라즈베리파이 보드 번호로 참조
GPIO.setup(pin, GPIO.IN) / 핀을 입력으로 설정
GPIO.setup(pin, GPIO.OUT) / 핀을 출력으로 설정
GPIO.output(pin, GPIO.HIGH) / 디지털 출력을 HIGH 로 설정
GPIO.output(pin, GPIO.LOW) / 디지털 출력을 LOW 로 설정 
GPIO.input(pin) / 디지털 값을 읽음 
GPIO.cleanup() / GPIO 모듈의 점유 리소스를 해제

LED 의 밝기가 점점 밝아지다가 다시 점점 어두워지는 것을 세 번 반복하는 예제 

import RPI.GPIO as GPIO
import time

GPIO.setmode(GPIO.BOARD)
GPIO.setup(12, GPIO.OUT)

pwm = GPIO.PWM(12,50)  /* pwm 초기화를 위해 GPIO.PWM ([pin],[frequency]) 함수를 사용한다 . 여기서는 50 Hz*/ 
pwm.start(0) // pwm.start([duty cycle]) 함수를 통해 듀티 사이클 초기값 세팅

for i in range (0,3):
	for dc in range(0,101,5):
		pwm.ChangeDutyCycle(dc)
		time.sleep(0.1) / 0.1초 동안 프로세스 중지 
	for dc in range(100,-1,-5):
		pwm.ChangeDutyCycle(dc)
		time.sleep(0.1)
pwm.stop()
GPIO.cleanup()

pwm 은 초당 펄스의 주파수를 유지한 채 펄스의 길이를 변화시키는 기술이다.
pwm.start([duty cycle]) 함수를 통해 duty cycle 초기값을 세팅한다.

ex)

pwm = GPIO.PWM(18, 500)
pwm.start(100)

-> pwm의 500 Hz 주파수를 세팅하고, 출력을 100% 의 duty cycle 로 세팅한다.

pwm.ChangeDutyCycle([duty cycle]) 함수를 사용하면 0~100% 사이의 duty cycle 값으로 바꿀 수 있다.

BUS

부품들 간, 또는 컴퓨터 간에 데이터와 정보를 전송하는 통로이다.

busio 모듈

https://circuitpython.readthedocs.io/en/latest/shared-bindings/busio/

busio 모듈은 serial protocol 을 위한 클래스를 담고 있다.

0개의 댓글