행복한 하루

라즈베리파이 제로 프로젝트(11) – PWM으로 서보 모터(Servo Motor) 제어하기 본문

RaspberryPi/Raspberry Pi Zero

라즈베리파이 제로 프로젝트(11) – PWM으로 서보 모터(Servo Motor) 제어하기

변화의 물결 2021. 1. 11. 22:54

 

 

안녕하세요.

 

  이번에는 180도 회전하는 소형 서브 모터(Servo Motor) SG-90을 제어해보도록 하겠습니다.

  서보 모터를 제어하기 위해서는 사전에 알아 두어야 할 PWM이라는 기술이 있는데, 우선 확인해보고 시작하도록 하겠습니다.

1. PWM (Pulse Width Modulation)

  펄스폭 변조(Pulse Width Modulation, PWM) 방식은 펄스의 폭을 조절하는 방식입니다. 때때로 PDM(pulse-duration modulation)이라고도 합니다.

 

  설명을 조금 더 쉽게 하자면 출력 전압값(5 Volt)을 기준(1 cycle)으로 이를 일정한 비율(duty) 동안에는 켠 상태(High)로 유지하고 나머지는 끈 상태(Low) 값으로 시간을 조정한다고 보면 쉽지 않을까 합니다. 5V 기준으로 50%로 duty cycle이라고 한다면 2.5V가 출력된다고 보시면 됩니다.

 

PWM 제어

2. SG-90 스펙 및 사이즈

 

3. 라즈베리파이 제로와 연결

 

 

라즈베리파이 제로 서보 모터
2번 핀 (5V) RED (VCC)
6번 핀 (GND) BROWN (GND)
12번 핀 (PWM) ORANGE (PWM)

 

 

4. 서보 모터를 제어하기 위한 설명

  - 데이터 시트에 보면 아래의 문구가 적혀 있습니다.

Position "0" (1.5 ms pulse) is middle, "90" (~2ms pulse) is all the way to the right.

ms pulse) is all the way to the right, ""-90" (~1ms pulse) is all the way to the left.

 

  -  1.5ms 펄스를 주면 위치가 0이 된다고 합니다. 0도 기준으로 왼쪽(-90도)으로 움직이려면 ~1ms 펄스가 필요하고 오른쪽(90도) 움직이면 2ms 정도 펄스가 필요하다고 쓰여 있습니다.

 

  - 서보 모터 제어는 보통 50Hz(1/50(주파수)=20ms(시간)) 주기를 1 사이클(cycle)로 보고 있습니다. 그래서 위치에 맞는 펄스 신호가 필요하기 때문에 시간을 계산해보겠습니다.

 

  1) 최대 왼쪽으로 이동하기

    - 대략적 1ms보다 적다고 나와 있지만, 일반적인 서보모터 제어할 때 0.6ms 정도로 하고 있습니다.

    - 0.6ms / 20ms * 100 = 3% 정도의 High(On) 신호가 필요합니다.

 

  2) 0 점 위치로 이동하기

    - 1.5ms / 20ms * 100 = 7.5% 정도 High(On) 신호가 필요합니다.

 

  3) 최대 오른쪽으로 이동하기

    - 대략적 2ms보다 적다고 나와 있지만, 일반적인 서보 모터 제어할 때 2.4ms 정도로 하고 있습니다.

    - 2.4ms / 20ms * 100 = 12% 정도 High(On) 신호가 필요합니다.

 

 

  - 중요한 것은 신호를 한번 보내주고 끝내는 것이 아니라 지속해서 계속 보내주어야 그 위치를 계속 유지하고 있습니다. 그리고 위의 ms 시간은 데이터 시트마다 다를 수 있음으로 참고해서 개발해야 합니다.

5. 제어 프로그램 제어

  1) WiringPi 설치

  - wiringPi가 설치되어 있지 않다면 우선 설치를 하고 컴파일을 해야 합니다.

 

pi@raspberrypi:~ $ cd /opt

pi@raspberrypi:/opt $ sudo git clone https://github.com/WiringPi/WiringPi

pi@raspberrypi:/opt $ cd WiringPi

pi@raspberrypi:/opt $ sudo ./build

pi@raspberrypi:/opt $ gpio -v

 

 

  2) PWM 제어 소스 

    - 소프트웨어 PWM을 사용하지 않고 하드웨어 방식 PWM 출력을 사용합니다.

    - 제어 함수 : void pwmWrite(int pin, int value);

      pin :  출력할 핀번호,  value/1024의 듀티 비를 갖는 PWM 파형을 출력함.

      value : 0~1024

 

       <사용 예>

       - pwmWrite(1, 512);  // 1번 핀에서 듀티 비 50%의 PWM 신호를 출력시킴. (512/1024=0.5)

 

#include <stdio.h>
#include <wiringPi.h>
#include <softPwm.h>

#define PIN 12 

int main()
{
  // 물리적으로 핀번호로 설정하기 위해서
  if (wiringPiSetupPhys() == -1) 
     return 0;
  // 하드웨어 PWM으로 출력 설정
  pinMode(PIN, PWM_OUTPUT);

  // WiringPi는 PWM 신호 생성시 기본적으로 Balanced 모드이며 PWM_MODE_MS로 변경
  pwmSetMode(PWM_MODE_MS); 

  //라즈베리 베이스 클럭 19.2 * 10^6,
  // 50Hz(20ms) 주기를 만들기 위해 펄스 주기 설정 Main 주파수 / CLOCK / RANGE
  // 19.2 * 10^6 / 384 / 1000 = 50 Hz
  pwmSetClock(384);
  pwmSetRange(1000);


  char str='r';

  while(str != 'q'){
  
     
    pwmWrite(PIN, 30 );
    delay(3000);

    pwmWrite(PIN, 75 );
    delay(3000);

    pwmWrite(PIN, 120 );
    delay(3000);
    
    fputs("Contiune : any key, Quit : q \n" , stdout);
    scanf("%c",&str);

  }
  
  return 0 ;
}

 

pi@raspberrypi:/opt $ vim servo_pwm.c

pi@raspberrypi:/opt $ sudo gcc servo_pwm.c -o servo_pwm -lwiringPi

pi@raspberrypi:/opt $ sudo ./servo_pwm

 

   

- 왼쪽, 중간, 오른쪽으로 한 번씩 움직이고, 입력 대기를 한 다음 ‘q’가 입력되지 않으면 다시 돌아가서 반복하는 프로그램입니다.

 

감사합니다.

 

 

<참조 자료>

1. [흥프로] 라즈베리파이 실습 예제 SG90 서보 모터 사용하기

https://devicemart.blogspot.com/2019/05/sg90.html

2. [RaspberryPi3] WiringPi를 이용한 서보 모터 PWM 제어

https://inmile.tistory.com/8?category=793890

3. Raspberry Pi 3에서 Servo Motor 제어하기

https://webnautes.tistory.com/1346  

 

 

“쿠팡 파트너스 활동을 통해 일정액의 수수료를 받을 수 있음"

Comments