보고서 09 12 7 -...

16

Transcript of 보고서 09 12 7 -...

Page 1: 보고서 09 12 7 - ysdragon.tistory.comysdragon.tistory.com/attachment/cfile5.uf@201407214BE4D4DF2136AF.… · nnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnÑ

분 야 서보모터제어시스템 설계

초소형 DC 서보 모터를 이용한

정역 속도제어기 구현

소 속 공주대학교

전 공 전 자 공 학

이 름 이 승 용

작 성 일 2009. 12. 10

Page 2: 보고서 09 12 7 - ysdragon.tistory.comysdragon.tistory.com/attachment/cfile5.uf@201407214BE4D4DF2136AF.… · nnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnÑ

목 차

Ⅰ. 서 론 ---------------------------------------------------- 1

Ⅱ. 본 론 ---------------------------------------------------- 1

Ⅲ. 결 론 ---------------------------------------------------- 6

참고문헌 --------------------------------------------------------- 6

#첨 부 ------------------------------------------------------- 7

Page 3: 보고서 09 12 7 - ysdragon.tistory.comysdragon.tistory.com/attachment/cfile5.uf@201407214BE4D4DF2136AF.… · nnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnÑ

- 1 -

Ⅰ. 서 론

이 시스템은 초소형 DC 서보 모터를 이용한 정역 속도 제어기 구현에 목적이 있다. 피드백 제어

기로는 비례적분 제어기(Proportional-Integral Controller)을 사용한다.

그림 1은 초소형 DC 서보 모터를 사용한 속도제어 시스템 구성도를 나타내고 있다.

그림 1. 초소형 DC 서보 모터를 사용한 속도제어 시스템 구성도.[1]

Ⅱ. 본 론

1. 하드웨어 구성

표 1은 시스템 구성에 사용되는 주요 모듈 및 소자를 나타낸다.

항 목 사 양 사용전압

OK-TFT Ver 1.0 ATMEGA2561, TFT 모듈 포함 +3.3V, +5V

DC Servo MOTORRA20GM 03TYPE 기어비 : 1/10

(로타리 엔코더 내장)+15V

DC Motor Driver Ver 1.0 L298N(DUAL FULL-BRIDGE DRIVER) 포함 +5V, +15V

표 1. 주요 모듈 및 소자.

그림 2. OK-TFT 키트와 DC Motor Driver 보드 및

직류 서보모터의 접속도.

Page 4: 보고서 09 12 7 - ysdragon.tistory.comysdragon.tistory.com/attachment/cfile5.uf@201407214BE4D4DF2136AF.… · nnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnÑ

- 2 -

그림 2를 보면 OK-TFT Kit의 여분의 병렬 포트를 이용해서 DC Motor Driver 보드와 연결한

다.

그림 3은 DC Motor Driver Board에서 각 커넥터로 연결된 병렬포트와 로터리의 엔코더 라인

의 색을 보여준다. 또 L298N에서 SENA 부분에서는 과전류 측정을 위해 2W/1Ω의 저항 2개를

병렬 연결하여 사용한다. 또 로타리 엔코더에서 나오는 펄스를 이용한 속도 측정을 위해

PD2(INT)를 이용한다.

그림 3. DC Motor Driver Board 회로도.[2]

1) 모터 특성

이 시스템에서 사용한 초소형 DC 서보 모터 특성은 그림 4와 같다.

그림 4. 초소형 DC 서보모터의 RPM 그래프.

Page 5: 보고서 09 12 7 - ysdragon.tistory.comysdragon.tistory.com/attachment/cfile5.uf@201407214BE4D4DF2136AF.… · nnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnÑ

- 3 -

이 실험은 PWM 주파수 2.853kHz에서 듀티비를 10% 씩 증가시키면서 측정한 결과이다. 이

상적인 DC 서보 모터 RPM(그림 4의 점선)과 많은 차이를 보인다.

2) 로타리 엔코더 특성

그림 5 로타리 엔코더에 1회전 당 생성되는 3개의 펄스

그림 5는 로타리 엔코더에서 나오는 펄스를 오실로스코프로 측정한 결과이다. 이 시스템에

사용되는 초소형 DC 서보 모터의 로타리 엔코더는 모터가 1회전 당 3개의 펄스를 생성 한다.

RPM이 증가하면 펄스 주기가 짧아진다. RPM은 60초당 3개의 펄스가 생성된 시간을 나누어

서 구한다.

2. 소프트웨어 구성

1) 인터럽트 처리 루틴

그림 6은 모터의 속도를 측정을 위한 인터럽트 루틴의 흐름도이다.

그림 6. 인터럽트 루틴 흐름도.

Page 6: 보고서 09 12 7 - ysdragon.tistory.comysdragon.tistory.com/attachment/cfile5.uf@201407214BE4D4DF2136AF.… · nnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnÑ

- 4 -

처음 펄스 상승 에지시 TCNT4 값 저장 후 15번째 펄스의 상승 에지시 TCNT4 값을 저장

한 후 처음 펄스 상승 에지와의 차를 이용해서 현재 RPM를 구한다. 여기서 사용되는 속도 측

정 방법은 T-Method이다.

2) Main 루틴

인터럽트 루틴에서 구한 상승 에지들의 TCNT4의 값을 이용 Main 루틴에서는 PI 제어를

이용한 속도 추종을 한다.

그림 7은 Main 루틴의 흐름도를 나타내고 있다. P GAIN과 I GAIN은 시행착오법

(Trial-and-error method)을 이용해서 구한다.

그림 7. Main 루틴 흐름도.

Page 7: 보고서 09 12 7 - ysdragon.tistory.comysdragon.tistory.com/attachment/cfile5.uf@201407214BE4D4DF2136AF.… · nnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnÑ

- 5 -

3) 화면 구성

그림 8은 화면 구성이다. 현재 RPM과 지령 RPM이 표시되고 RPM 변화를 속도 그래프로

보여준다. 지령 RPM은 버튼으로 0~±9000 까지 조정한다.

속도

그래프

듀티비

표시현재(추종) RPM

지령 RPM

지령 RPM 조절

버튼(±500)

그림 8 화면 구성

4) 실제 구현 사진

그림 9 실제 구현 사진

Page 8: 보고서 09 12 7 - ysdragon.tistory.comysdragon.tistory.com/attachment/cfile5.uf@201407214BE4D4DF2136AF.… · nnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnÑ

- 6 -

Ⅲ. 결 론

초소형 DC 서보 모터를 이용해서 정역 속도 제어기를 구현 해봤다. Open-loop 제어 때부터 여기

서 사용된 DC 서보 모터가 일반적인 DC 서보모터와의 RPM 증가 곡선에서 많은 차이를 보였다. 최

종적인 정역 속도 제어기에서도 0~±1000 RPM의 지령 RPM 설정 시 추종하지를 못한다. 1500RPM

이상으로 설정했을 때는 정상적인 속도 추종을 하게 된다. 감지 저항을 이용해서 흐르는 전류값 측

정은 구현 하지 못했다.

이 정역 속도제어기를 작은 미니카에 적용한다면 좋을 것 같다.

단순히 정역 속도제어만 해봤지만 앞으로의 연구과제로 위치제어도 해보고 싶다.

참고문헌

[1] 윤덕용, 2005, 『Atmega128를 활용한 졸업작품 만들기』, OHM사, p461

[2] 윤덕용, http://cpu.kongju.ac.kr, DC Motor Driver 및 Step Motor Driver 보드 1.0의 사용설명

Page 9: 보고서 09 12 7 - ysdragon.tistory.comysdragon.tistory.com/attachment/cfile5.uf@201407214BE4D4DF2136AF.… · nnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnÑ

- 7 -

# 첨 부

1. 프로그램 소스#include "header/Font.h"

#include "header/TFT28.h"

#include <avr/interrupt.h>

#define FORWARD 0x04 // PORTE2

#define REVERSE 0x02 // PORTE1

#define STOP 0xF8 // PORTE3

#define Kp 0.02 // P gain

#define Ki 0.90 // I gain

#define Ts 0.004 // Speed sampling time[sec]

//////////////////////////////////////////////////////////////// 전역 변수 선언 /////////////////////////////////////////////////////////////

U08 PulseCount = 0;

S16 RPM = 0; // RPM

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

// 엔코더의 펄스 수 카운트 루틴

ISR ( INT2_vect ) // 인터럽트 처리

{

if ( 15 == PulseCount ) // 15번째 펄스 상승

{

TCCR4B = 0x0000; // Normal 모드로 돌림(카운터/타이머 기능 정지)

//////////////////////////////////////////////// RPM 계산 부분 ////////////////////////////////////////////////////////////////////////////

// 실수로 계산 되므로 float으로 캐스팅 후 U16로 다시 캐스팅

// RPM 구하는 공식 ; ( 60(초) / ( ( 15 펄스의 카운트 수 / 5 ) * 카운트 시간 ) )

RPM = ( S16 ) ( ( ( 60.0 / ( ( TCNT4 / 5.0 ) * ( 16.0 * 0.000001 ) ) ) ) );

Page 10: 보고서 09 12 7 - ysdragon.tistory.comysdragon.tistory.com/attachment/cfile5.uf@201407214BE4D4DF2136AF.… · nnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnÑ

- 8 -

if ( PORTE & REVERSE ) RPM = -RPM;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

PulseCount = 0;

} // if ( 15 == PulseCount ) End

else

{

if ( 0 == PulseCount ) // 처음 펄스 상승

{

////////////////////////////////////// Timer/Counter 4 CTC Mode 세팅 ////////////////////////////////////////////////

// B상에서 나오는 세 펄스의 주기를 측정을 위한 Timer ; 내부 기능만 사용

TCNT4 = 0; // 초기값 0

//TCCR4A = 0x00; // default setting

TCCR4B = 0x0C; // CTC Mode(4) f/256 Setting

//TCCR4C = 0x00; // default setting

OCR4A = 62499; // TOP 값

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

} // if ( 0 == PulseCount ) End

PulseCount++;

} // else End

EIFR |= 0x20; // Interrupt 2 Clear

} // ISR ( INT2_vect ) End

Page 11: 보고서 09 12 7 - ysdragon.tistory.comysdragon.tistory.com/attachment/cfile5.uf@201407214BE4D4DF2136AF.… · nnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnÑ

- 9 -

int main ( void )

{

//////////////////////////////////////////////////////////////// 지역 변수 선언 /////////////////////////////////////////////////////////////

U08 key; // 키 입력 코드 값

U08 DutyRatio; // 듀티비 저장

S16 ReferenceRPM = 0; // 기준(지령) RPM

U08 cnt = 20;

U08 pr = 0;

U16 tempX1 = 20, tempY1 = 315;

U16 tempX2 = 20, tempY2 = 315;

volatile S16 PWM;

volatile float Werr0 = 0, Werr1, PIconstant, PI = 0;

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

PIconstant = Kp + Ki * Ts; // PI 상수 계산

//////////////////////////////////////////////////////////// MCU 및 TFT-LCD 초기화 //////////////////////////////////////////////////////////

MCU_Initialize ();

TFT_Initialize ();

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

///////////////////////////////////////////////////////////////// 화면 세팅 /////////////////////////////////////////////////////////////////

TFT_clear_screen ();

TFT_screen_mode ( 'P' );

Page 12: 보고서 09 12 7 - ysdragon.tistory.comysdragon.tistory.com/attachment/cfile5.uf@201407214BE4D4DF2136AF.… · nnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnÑ

- 10 -

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

//////////////////////////////////////////////////////////////// 초기 화면 출력 /////////////////////////////////////////////////////////////

TFT_string ( 2, 6, WHITE, BLACK, "Servo Motor Control System" );

TFT_string ( 2, 12, WHITE, BLACK, "Duty Ratio : " );

TFT_string ( 2, 18, WHITE, BLACK, "Servo RPM :" );

TFT_string ( 16, 18, GREEN, BLACK, "+0000 RPM" );

TFT_string ( 2, 24, WHITE, BLACK, "Ref. RPM : " );

TFT_string ( 16, 24, CYAN, BLACK, "+0000 RPM" );

Blocks ( 20, 215, 210, 315, PINK, BLACK ); // 화면 지움

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

// PORTE 3

/////////////////////////////////////////////////////////// PWM 및 모터 방향 설정(TIMER/COUNTER 3) //////////////////////////////////////////

TCCR3A = 0x82; // Fast PWM mode(14)

TCCR3B = 0x1A; // 분주비 : 1/8

TCCR3C = 0x00;

ICR3 = 700; // TOP값 : f = 2MHz / 1 + ( 700 ) = 2853.07Hz = 2.853kHz

OCR3A = 0; // 초기값

PORTE &= 0xF8; // 회전 방향 설정(정지)

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

Page 13: 보고서 09 12 7 - ysdragon.tistory.comysdragon.tistory.com/attachment/cfile5.uf@201407214BE4D4DF2136AF.… · nnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnÑ

- 11 -

//////////////////////////////////////////////////////////////// INT 2 기능 세팅 ////////////////////////////////////////////////////////////

// 엔코더 B상에서 발생되는 펄스 상승 에지시 발생

EICRA = 0x30; // 상승(Rising) 에지시 INT 2 발생

EIMSK = 0x04;

EIFR = 0xFF; // 모든 인터럽트 플래그 클리어

sei (); // global Interrupt enable

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

while ( 1 )

{

//////////////////////////////////////////////////////////// 키 입력 처리 ///////////////////////////////////////////////////////////////

key = Key_input ();

switch ( key )

{

// 기준(지령) RPM 변경

case 0xD0 : // Key2

if ( 9000 > ReferenceRPM ) ReferenceRPM += 500;

break;

case 0xE0 : // Key1

if ( -9000 < ReferenceRPM ) ReferenceRPM -= 500;

break;

} // switch ( key ) End

TFT_xy ( 16, 24 );

TFT_color ( CYAN, BLACK );

Page 14: 보고서 09 12 7 - ysdragon.tistory.comysdragon.tistory.com/attachment/cfile5.uf@201407214BE4D4DF2136AF.… · nnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnÑ

- 12 -

TFT_signed_decimal ( ReferenceRPM, 4, 4 );

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

if ( 0 == ReferenceRPM ) // 추종해야할 속도가 0이면 All Zero

{

DutyRatio = 0;

PI = 0;

RPM = 0;

} // if ( 0 == ReferenceRPM ) End

else

{

////////////////////////////////////////////////// 듀티비 계산 부분 /////////////////////////////////////////////////////////////////////

DutyRatio = ( U16 ) ( ( ( ( float ) OCR3A ) / ( ( float ) ICR3 ) ) * 100.0 ); // 듀티비 계산

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

//////////////////////////////////////////////////////// PI 제어 ///////////////////////////////////////////////////////////////////////

Werr1 = ( float ) ( ReferenceRPM - RPM );

PI = PI + PIconstant * Werr1 - Kp * Werr0;

Werr0 = Werr1;

// PI Limiter

if ( PI > 700.0 ) PI = 700.0;

else if ( PI < -700.0 ) PI = -700.0;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

} // Else End

PWM = ( signed int ) PI;

PORTE &= STOP; // 정지

Page 15: 보고서 09 12 7 - ysdragon.tistory.comysdragon.tistory.com/attachment/cfile5.uf@201407214BE4D4DF2136AF.… · nnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnÑ

- 13 -

if ( PWM >= 0 ) PORTE |= FORWARD; // 정방향

else PORTE |= REVERSE; // 역방향

OCR3A = abs ( PWM );

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////// 각 값들 출력 ///////////////////////////////////////////////////////////////////

TFT_xy ( 17, 12 );

TFT_color ( PINK, BLACK );

TFT_unsigned_decimal ( DutyRatio, 3, 3 );

TFT_string ( 20, 12, PINK, BLACK, " %" );

TFT_xy ( 16, 18 );

TFT_color ( GREEN, BLACK );

TFT_signed_decimal ( RPM, 4, 4 );

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

/////////////////////////////////////////////////////////// RPM 그래프 출력 ////////////////////////////////////////////////////////////

if ( pr == 10 )

{

if ( cnt >= 210 )

{

cnt = 20;

Blocks ( 20, 215, 210, 315, PINK, BLACK ); // 화면 지움

tempX2 = tempX1 = 20;

tempY2 = tempY1;

Page 16: 보고서 09 12 7 - ysdragon.tistory.comysdragon.tistory.com/attachment/cfile5.uf@201407214BE4D4DF2136AF.… · nnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnÑ

- 14 -

} // if ( cnt >= 210 ) End

tempX2 = cnt;

tempY2 = 315 - ( abs ( PWM ) * 7 / 50 );

if ( PWM < 0 ) Line ( tempX1, tempY1, tempX2, tempY2, RED ); // 역방향일 때(RED)

else Line ( tempX1, tempY1, tempX2, tempY2, YELLOW ); // 정방향일 때(YELLOW)

tempX1 = tempX2;

tempY1 = tempY2;

cnt = cnt + 1;

pr = 0;

}

pr++;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

} // while ( 1 ) End

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

} // int main ( void ) End