본문 바로가기

My Project/교통정리로봇

[교통정리로봇] 프로젝트 문서 2. 관련연구(여덟번째)


 

■ RC 서보 모터

서보 모터는 주어진 신호에 의해서 일정한 각을 유지하거나 일정한 위치를 유지하는 모터로서, 일반적으로 무선 모형 비행기나 자동차에 많이 사용되는 모터입니다. 서보 모터는 서보 신호에 의해 특정한 각도를 유지하며, 서보 신호는 PWM 신호로서 일정한 주기의 펄스폭으로 입력됩니다. 그리고 서버 모터는 일반적인 DC모터나 스텝모터와는 달리 회전각에 제한이 있으며, 보통 180도 정도의 회전각을 갖습니다.

이번 프로젝트에서 사용할 모터는 HS-311 입니다. 사양은

--------------------------

토크 : 3.0(4.8V) / 3.5Kg(6.0V)

속도 : 0.19(4.8V) / 0.15(6.0V)

크기 : 41 X 20 X 37 mm

중량 : 48.5g

동작전압 : 4.8~6V

--------------------------


RC서보 모터는 일정한 폭을 갖는 펄스에 의해 각도를 제어할 수 있는데, 이 HS-311은 0.60ms의 신호를 인가하면 0도, 1.50ms의 신호를 인가하면 90도, 2.40ms의 신호를 인가하면 180도의 각을 유지합니다.

그리고 서보모터가 현재의 각을 유지하기 위해서는 일정한 주기로 신호를 반복해서 인가해야 하며, 10ms~ 20ms의 주기로 서보 모터에 PWM 신호를 인가합니다.

서보모터의 토크는 클수록 힘이 좋지만, 그만큼 속도는 떨어지게 되며, 속도가 빠르면 토크가 약하게 됩니다.

밑의 그림은 RC서보 모터의 신호 선에 대한 그림입니다.


 

■ RC서보 모터 예제

================================================================================================

RC서보 모터를 2초 주기로 0도->90도->180도로 회전시키는 프로그램

------------------------------------------------------------------------------------------------

이 프로그램은 오버플로우 인터럽트를 사용하여 모터를 주기대로 회전시키게 하는 프로그램입니다.

================================================================================================

#include <mega128.h>


unsigned int tim0_cnt, mot_pos, change;

unsigned int rc_time[3] = {60,150,240}; // 0도, 90도, 180도


int main(void)

{

        DDRA = 0xFF; // 포트 A 출력 설정


        tim0_cnt = 0; // 타이머/카운터0 오버플로우 횟수 리셋

        mot_pos = 0; // 모터 위치 = 0도

        change = 0; // 각도 변화 주기 리셋

        // 타이머/카운터 0 인터럽트 주기

        TIMSK = 0x01; // 오버플로우를 인터럽트로 사용

        TCCR0 = 0x02; // 일반모드, 프리스케일 = CK/8

        TCNT0 = 238; // 타이머/카운터0 레지스터 초기값

        SREG = 0x80; // 인터럽트 인에이블 비트 셋


        tim0_cnt = 0;

        PORTA = 0xFF; // 모터 high 출력


        while(1)

        {

                if(tim0_cnt >= 2000) // 20ms 주기 체크

                {

                        tim0_cnt = 0;

                        PORTA = 0xFF;

                        change++;

                        if(change == 100) // 20ms x 100 = 2sec 각도 변화 주기 체크

                        {

                                mot_pos = (mot_pos + 1) % 3;

                                change = 0;

                        }

                }

                if(tim0_cnt >= rc_time[mot_pos])

                {

                        PORTA = 0x00; // 모터 low 출력

                }

        }

}


interrupt [TIM0_OVF] void timer_int0(void)

{

        tim0_cnt++;

        TCNT0 = 238; // 타이머/카운터0 초기값 재설정

}

================================================================================================