180 likes | 357 Views
Application of Interrupt and Timer : Motor Position Control. Encoder. Incremental Encoder 13 pulses/round/channel 1 pulse = 360/13 도 (motor), 360/50/13 도 (wheel) direction A/B channel 의 위상을 비교. A Ch. B Ch. A Ch. B Ch. Measurement of Motor Angular Displacement.
E N D
Encoder • Incremental Encoder • 13 pulses/round/channel • 1 pulse = 360/13 도 (motor), 360/50/13 도 (wheel) • direction • A/B channel의 위상을 비교 A Ch. B Ch. A Ch. B Ch.
Measurement of Motor Angular Displacement • Representation of Angular Displacement • Degree/Radian • Degree = No_of_pulse *360/13/50 = No_of_pulse *36/65 • 최소 표시 범위 : -180 ~ 180 • int type • Not absolute angular position • Not defined for zero position • Angular displacement (각 변위)
Interrupt Service Routine (INT5, Left Motor) ISR(INT5_vect) { if ( (PINE & 0x10) == 0x10 ) { Pulse_Left++; // 시계 방향 Dir_L = 0; } else { Pulse_Left--;; // 반시계방향 Dir_L = 1; } }
Angle Measurement Program #include <avr/io.h> #include <avr/interrupt.h> void txd_char(unsigned char data){ while( (UCSR0A & 0x20) == 0 ); UDR0 = data; } int Pulse_Left = 0, Pulse_Right = 0; unsigned char Dir_L, Dir_R; int main(){ unsigned char i; int ang_left; unsigned char text[] = "\r Left : ";
Angle Measurement Program /* UART 초기화 */ /* PWM 초기화는 없음 */ /* motordisable, 단순 각도 측정 */ DDRB = 0xCF; DDRD = 0x18; DDRE = 0x01; EICRB = 0x08; // EICRB = 0x88; EIMSK = 0x20; // EIMSK = 0xA0; sei();
Angle Measurement Program while(1){ i=0; while(text[i] != '\0') txd_char(text[i++]); if( Pulse_Left >= 0 ) { txd_char('+'); ang_left = Pulse_Left*36/65; } else { txd_char('-'); ang_left = -Pulse_Left*36/65; } txd_char(ang_left/100 + '0'); txd_char((ang_left/10)%10 + '0'); txd_char(ang_left%10 + '0'); txd_char('\r'); }
연습 • 손으로 모터를 회전하면서 회전 각도 확인 • Right Motor에 대해 각도 측정 code 완성
Position (angle) control of DC motor • Feedback Control • Proportional Control (비례 제어) motor controller + Kp ref _ PWM Encoder(Hall sensor)
Angle Control Program #include <avr/io.h> #include <avr/interrupt.h> void txd_char(unsigned char data){ while( (UCSR0A & 0x20) == 0 ); UDR0 = data; } int Pulse_Left = 0, Pulse_Right = 0; unsigned char Dir_L, Dir_R; int main(){ unsigned char i=0; int ang_left, err_left, ref; unsigned int motor_pwm, Kp; unsigned char text[] = "\r\n Left : ";
Angle Control Program DDRB = 0xCF; DDRD = 0x18; DDRE = 0x01; /* Port 초기화 */ /* UART 초기화 */ EICRB = 0x08; EIMSK = 0x20; /* lefthall sensor 초기화 */ TCCR1A = 0x2B; TCCR1B = 0x0A; TCCR1C = 0x00; /* PWM 초기화 */ ref = 90; /* reference command = 90 */ Kp = 30; /* 비례 제어기 gain = 30 */ sei();
Angle Control Program while(1){ ang_left = Pulse_Left*36/65; err_left = ref - ang_left; / * angle 오차 계산 */ if( err_left >= 0 ) { /* PWM 환산 */ PORTB = 0x01; motor_pwm = Kp*err_left; } else { PORTB = 0x02; motor_pwm = -Kp*err_left; } if (motor_pwm >= 0x3FF ) motor_pwm = 0x3FF; OCR1B = motor_pwm; /* UART 각도 전송부 추가 */
연습 • Right motor에 대한 각도 제어 • 다양한 reference 각도와 gain에 대한 테스트
Digital Control • Sampled-data System controlled system : continuous-time signal control algorithm : discrete-time signal
Digital Control • clear time on compare match (CTC) mode (output compare interrupt) • TCNT0 : 8 bit timer/counter • fclk = 7372800 Hz & prescale : 1024 • ftimer = 7372800/1024 = 7200 • Ttimer = 1/7200 • OCR0 = 72 => 72*Ttimer = 1/100 = 10 mSec 마다 interrupt 발생 • 10mSec 마다 Control • TCCR0 = 0x0F; • TIMSK = 0x02;
Digital Control Program #include <avr/io.h> #include <avr/interrupt.h> void txd_char(unsigned char data){ while( (UCSR0A & 0x20) == 0 ); UDR0 = data; } int Pulse_Left = 0, Pulse_Right = 0; unsigned char Dir_L, Dir_R, Int_flag = 0; int main(){ unsigned char i=0; int ang_left, err_left, ref; unsigned int motor_pwm, Kp; unsigned char text[] = "\r\n Left : ";
Digital Control Program while(1){ if ( Int_flag == 1 ){ Int_flag = 0; /* 제어및 UART 통신 */ } } … ISR(TIMER0_COMP_vect) { Int_flag = 1; }
연습 • UART를 이용한 각도 명령 • 예) ‘1’ : left -90, ‘2’ : left -45, ‘3’ : left 0, ….