from Project/└ ATmega128 2013. 9. 18. 15:12

전에 스마트폰으로 대~충 적어서 서보모터 제어한 걸 올렸었는데


그건 보기도 불편하고 아무런 사진이나 소스등이 없어서 나중에 보기 편하게 자료 정리하기로 결정.


짜둔 소스랑 중간에 발생한 문제점을 어떻게 해결하였는지 좀 잘 써본다



먼저 서보모터 제어를 위해 가장 먼저 알아야 할 것은 PWMDuty 에 관해서 이다.


위 두가지를 기본적으로 알고 있어야 서보모터를 시작할 수 있으니 모르는 경우 일단 그것부터 알아보고오길..

이 글은 내 생각정리 용이므로 저 두가지는 당연히 알고 있다는 가정하에 생략하겠다


그 두가지를 알면, 이제 Coding을 하면 되는데...


1. PORT 설정을 한다.


1
2
3
4
5
6
7
8
9
10
11
/*=========PORT IO 설정========*/
void PORT_init(void){    
    cli();        //모든 인터럽트 사용금지
    /* 입출력 레지스터 */
    DDRB=0xFF;        //PB6: OC1B Pin.(1개)
    //OC1A(PB5):LPWM,  OC1B(PB6):PWM_servo, OC1C(PB7):RPWM, PB3: EN, PB4: DIS
    PORTB=(1<<OC1A)|(1<<OC1B)|(1<<OC1C)|(1<<EN)|(1<<DIS);    
 
    sei();                //SREG 레지스터 "I"비트 "1" 값으로 설정
                    //I 비트가 "0"이면 모든 인터럽트 작동X.
}

뭐 이런 식으로 따로 Function을 만들어 사용하는게 편하다.

여기서 PORTB 는 내가 사용한 Timer 1 과 관련된 OC1A, OC1B, OC1C 핀들이

이 PORTB 핀에 속하기에 설정해주었다.

저 3가지 핀 중 난 OC1B 핀인 PB6 을 서보모터에 사용했다

※ OC1A, OC1B 등은 define으로 미리 정의해 두었다.


2. Timer/Couter 1 설정을 해준다(PWM 설정)


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
/* 타이머/카운터1 레지스터 */
void PWMS_init(void)
{
    cli();    //모든 인터럽트 사용금지.
 
    // Timer/Counter1 로 PWM 사용하는 경우 
    // WGM13:12:11:10=0101 Fast PWM(8-bit)
    // COM1B1:COM1B0=11  Compare Match에서 OCR 일치시 H. 오버플로우 시 L.
    // CS12:11:10=101 clk/1024 분주비. 주기 : 16.32ms
    TCCR1A=(0<<WGM11)|(1<<WGM10)|(1<<COM1B1)|(1<<COM1B0);    
    TCCR1B=(0<<WGM13)|(1<<WGM12)|(1<<CS12)|(0<<CS11)|(1<<CS10);    
    TCNT1L=217;    //주기: 2.4ms. 256-n. n=16.(1024/16000000=64us. 1ms=64us x 16.)
    OCR1BL=240;    //0~240 Low. 240~255까지 H. 1/1024 분주비일때 1ms.
                    //233 중앙 239 제일왼쪽 225 제일 오른쪽
    TIMSK=(1<<TOIE1)|(1<<OCIE1B);    //타이머/카운터1 Overflow 인터럽트 허용.
                        //OC1B Compare Match 인터럽트 허용.
 
    sei();    //SREG 레지스터 "I"비트 "1" 값으로 설정
             //I 비트가 "0"이면 모든 인터럽트 작동X.
}
/* 타이머/카운터1 루틴 
   iom128.h 파일 참조. */
SIGNAL(SIG_OUTPUT_COMPARE1B)
{
}
SIGNAL(SIG_OVERFLOW1)
{
    TCNT1L=217;    
}


이 Function은 Servo motor용 PWM제어 함수인데,

주기: 2.4ms 로 TCNT1L 값이 설정된 217부터 255까지 Count 되는데 걸리는 시간이 약 2.432ms 이다.

TCNT1L이 255가 되어 Overflow interrupt 가 되는 순간 SIG_OVERFLOW1 이 가리키는 루틴 함수로 들어가게 되고

다시 TCNT1L은 217 이 되게 된다.

그리고 DutyOCR1BL240인 경우 TCNT1L이 240이 된 순간 High신호가 Output되고  순간 SIG_OUTPUT_COMPARE1B가 가리키는 루틴함수로 들어가게 된다. 따라서 이 루틴함수를 꼭 소스에 첨부해야한다. 그다음 TCNT1L이 255가 되어 Overflow 되면 다시 Low가 된다. 


3. PWM을 실행한다.


이제 위에서 모든 설정은 끝났다.

남은건 내가 원하는 DutyOCR1BL 에 넣으면 해당하는 시간만큼 High를 유지하게 된다.

테스트해본 결과,

OCR1BL = 233 인 경우(=1.4ms) 바퀴가 정가운데

OCR1BL = 239 인 경우(=1.0ms) 바퀴가 제일 왼쪽

OCR1BL = 225 인 경우(=1.9ms) 바퀴가 제일 오른쪽


뭐 이런 식으로 해서 동작하게 된다.

위에서 언급한 1.0ms, 1.4ms, 1.9ms는 내가 사용한 자동차에 달린 서보모터의 경우이고

실제 이 서보모터는 180도까지 지원되는 모델이므로 이보다 더 넓은 범위에서 동작하게 된다.



위 소스를 이용하면 쉽게 서보모터를 제어할 수 있다.

다만 서보모터마다 Duty가 약간씩 다르므로 그점은 유의해야 한다.


이제 실행한 모습을 보겠다






파형은 이처럼 깔끔하게 나온다.


그럼 동작모습을 보자


뭐 대충 이런식??


이로인해 서보모터 제어는 끝났다.


다음에 DC모터 제어에대해 올리겠다.


그럼 이만...





ps. 노이즈가 심해 서보모터가 지맘대로 움직이는 경우가 있는데 이경우 전압이 부족한거 일 수 있으니 

5V의 전압을 제대로 줘야한다.(7805 레귤레이터의 경우 7V이상의 Input을 줘야 정확히 동작한다.)

또한 그라운드를 확실히 연결해줘야 제대로 동작하니 참고한다.



'Project > └ ATmega128' 카테고리의 다른 글

TFTLCD 참고 소스  (3) 2013.10.02
[AVR]서보모터 제어  (1) 2013.09.12
,