ServoBlaster 절대로 Raspberry Pi에서 서보을 움직일 수 있지만, 명령으로 조작하기 때문에 C ++에서 사용 어려웠다.
Raspberry Pi의 GPIO 18 번 핀 PWM 출력을 낼 것 같아서 그것을 가지기를 보았다.
사용한 것
- Raspberry Pi Model B
- SG90 (서보)
- WiringPi
서보 제어 방식
PWM 신호 라든지 서보 메커니즘을 잘 알고 있지 않았기 때문에, 우선은이 페이지를 읽고 공부했다.
H8로 배우는 마이크로 컨트롤러 개발 입문 (9) : 모터 제어에 필수적인 기술 "PWM"뭐야? (1/3) - MONOist (모노이스토)
일정한주기와 펄스 폭을 가진 PWM 신호 서보를 제어 할 수있는 것 같다.
SG90의 사양
이번 사용할 서보는 SG90의 사양은 다음과 같다.
이것을 보면이 서보는 180 ° 회전 할 수 있고, 그러기 위해서는주기 : 20ms 펄스 폭 : 0.5 ~ 2.4ms의 PWM 신호를 출력하면된다 알 수있다.
※ 2 사이트는 펄스 폭 1 ~ 2ms로 써 있지만 모두 시도하면 1이 올바른 것 같았다.
WiringPi에서 서보를 제어하는 방법
이번 GPIO 제어는 WiringPi를 사용하기로했다.
WiringPi는 PWM 출력 기능이 있으므로, 이들로 서보 제어에 적합한 PWM 신호를 출력 할 수있다.
Raspberry Pi Specifics | Wiring Pi
PWM 출력 함수는 다음의 3 개.
- pwmSetMode (int mode);
- pwmSetRange (unsigned int range);
- pwmSetClock (int divisor);
WiringPi 레퍼런스를 읽어도 사용법을 잘 몰랐는데,이 사이트의 답변이 도움이되었다.
gpio - Control Hardware PWM frequency - Raspberry Pi Stack Exchange
요점을 정리하면,
- WiringPi는 기본적으로 Balanced 모드이므로 Mark : Space 모드로 설정해야합니다.
- PWM 주파수를 다음 식으로 계산할 수 있고, 이것이 서보의주기와 일치하도록 clock과 range를 설정한다.
- 19.2MHz이란 Raspberry Pi의 PWM이있는베이스 클럭 주파수.
- 베이스 클럭을 clock으로 나눈 값 (
= 19.2 [ MHz] / C L O C K )는 PWM 카운터의주기를 나타내며이주기에서 PWM 카운터가 1 씩 증가된다. - range는 PWM 분해능에 영향을주는 값입니다.
라고하는 것 같다. 베이스 클럭에 대해서는 잘 모르겠지만, 신호의 On / Off를 전환 타이밍이 초당
그리고는 clock과 range를 SG90의 사양에 맞게 결정하면 좋지만 어떤 값이 좋은지 몰라서이 사이트의 값을 사용해 보았다.
Controlling Two Servos with Hardware PWM on the Raspberry Pi Model A + - electronut.in
- PWM 카운터주기 :
19.2 [ MHz] / C L O C K = 19.2 * 106/ 400 = 48 [ KHz] ≒ 0.0208 [ M S ] - PWM 주파수 :
19.2 [ MHz] / C L O C K / R a N ge = 19.2 * 106/ 400 / 1024 = 46.875 [ Hz] ≒ 21.3 [ M S ]
되었다.
SG90의 PWM의주기가 20ms 그래서 PWM 주파수가 조금 낮은 것 같지만, 이동 보니 문제가 없었다. 어바웃에 좋은 것 같다.
다음 서보을 끝에서 끝까지 회전 값을 계산한다.
SG90의 사양이라고 펄스 폭 : 0.5 ~ 2.4ms이므로,
48 [ KHz] * 0.5 [ M S ] = 48000 [ Hz] * 0.0005 [ s ] = 24 48 [ KHz] * 2.4 [ M S ] = 48000 [ Hz] * 0.0024 [ s ] = 115.2 ≒ 115
이 값을 WiringPi으로 설정하면 서보를 좌우로 한계까지 회전된다.
Raspberry Pi에서 서보를 제어하는
Raspberry Pi 및 SG90은 오렌지 ⇒GPIO18 / 레드 ⇒5V / 차 ⇒GND 및 배선한다.
WiringPi을 사용하여 서보가 움직일 프로그램 다음과 같다.
정수 값을 입력하여 값을 GPIO18로 설정한다.
#include <iostream>
#include <wiringPi / wiringPi.h>
int main ()
{
if ( wiringPiSetupGpio () == - 1 ) {
std :: cout << "can not setup gpio." << std :: endl ;
return 1 ;
}
pinMode ( 18 , PWM_OUTPUT );
pwmSetMode ( PWM_MODE_MS );
pwmSetClock ( 400 );
pwmSetRange ( 1024 );
while ( true ) {
int num ;
std :: cin >> num ;
if ( num == - 1 ) {
break ;
}
pwmWrite ( 18 , num );
}
return 0 ;
}
결과는 이쪽.
처음에 24을 입력 후 115을 입력하고있다.
WiringPi Servo Sample | Youtube
동영상이라면 180 ° 조금 돌고 있지만, 서보 주로 사양보다 조금 큰 범위까지 회전 할 수있는 것 같기 때문에 위의 계산은 맞고있는 것 같다.
무사 서보을 달릴 수 있었다.
여담
먼저 WiringPi의 exapmle에 PWM 출력의 샘플 프로그램 (pwm.c)가있어이를 사용하면 간단하게 할 수 있다고 생각하지만,이 샘플에서는 서보 제어는 못했다.
운동을 움직여 보면 서보에 붙인 암이 뿌리 치고 움직일 수 없게되고, 막 구입 한 서보 끊었다 ...! ? 생각 초조해했다. 괜찮다고했지만.
샘플 PWM 모드는 Balanced 모드로되어 있고,이 모드는 LED의 밝기를 조정할 때 적합한 모드 같다.