dc motorccrs.hanyang.ac.kr/webpage_limdj/automation/motor.pdf · 2020. 11. 24. · 6...
TRANSCRIPT
Automation Programming
DC Motor
Modeling and Control
2
직류모터의모델
자기장(magnetic field) 내에서전류가흐르는도체에는힘이작용하며, 이힘의세기는자기장의세기와도체에흐르는전류의크기에비례한다.
자기장내에서도체를움직이면이도체에는기전력(emf, electro-motive force)이발생하며, 이기전력의크기는도체가움직이는속도에비례한다.
3
직류모터의모델
t aK i
b b b
de K K
dt
4
직류모터의모델
a aa a a a b a a a b
di di de R i L e R i L K
dt dt dt
2
2t a a
d dK i J B
dt dt
t aK i
b b b
de K K
dt
5
직류모터의모델: 전달함수
2 2
2
2
( ) ( ) ( ) ( )
( ) ( )
( ) ( ) ( ) ( )
( ) ( ) ( )
( ) ( ) ( )
( )
( )
( ) ( )
( ) (
a a a a a b
a a a b
t a a a
t a a a t a t b
t a a a a t b
t
a a a a t b
a a
E s R I s L sI s K s s
R L s I s K s s
K I s J s s Bs s J s Bs s
K E s R L s K I s K K s s
K E s R L s J s Bs s K K s s
Ks
E s R L s J s Bs K K s
s s s
E s E
)
t
a a a t b
K
s R L s J s B K K
6
모터의기계파워와전기파워
손실이없다고가정: 기계파워=전기파워
e a aP e i
bm t a
b
eP K i
K
, 0, 0m e b a a a
t b
P P e e R L
K K
7
Optical Encoder
8
Magnetic Encoder
Image credit: ams AG
9
10
11
Timer 2 configuration
12
Remap PA15
13
14
/* USER CODE BEGIN Includes */
#include "stdio.h"
/* USER CODE END Includes */
/* USER CODE BEGIN 0 */
#ifdef __GNUC__
#define PUTCHAR_PROTOTYPE int __io_putchar(int ch)
#else
#define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)
#endif /* __GNUC__ */
PUTCHAR_PROTOTYPE
{
HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, 0xFFFF);
return ch;
}
/* USER CODE END 0 */
15
/* USER CODE BEGIN 2 */
HAL_TIM_Encoder_Start(&htim2,TIM_CHANNEL_1);
/* USER CODE END 2 */
/* USER CODE BEGIN WHILE */
while (1)
{
printf("%ld\r\n",TIM2->CNT);
HAL_Delay(100);
/* USER CODE END WHILE */
16
17
18
Assume
2
2
2
,
( ) ( ) ( ), ( ) ( )
1/ 1/( ),
( ) 11
a a a b t a a
a a a b t a a
b b a am
a m t ba a
t b
d de R i K K i J
dt dt
E s R I s K s s K I s J s s
K K R JsT
E s s T s K KR Js s
K K
0aL
19
Transfer Function
Output: angle(position)
Output: angular velocity(speed)
1/( ) ( )
( ) ( ) 1
b
a a m
Ks s s
E s E s T s
1/ 1/( )
, ( ) 1
1
b b a am
a m t ba a
t b
K K R JsT
E s s T s K KR Js s
K K
20
/* USER CODE BEGIN PV */
#define CAPTURE_START 1
#define CAPTURE_FINISHED 2
int data_flag=0;
int data_counter=0,sf=1000;
int data[4000];
/* USER CODE END PV */
/* USER CODE BEGIN 2 */
HAL_TIM_Base_Start_IT(&htim10);
HAL_TIM_Encoder_Start(&htim2,TIM_CHANNEL_1);
HAL_DAC_Start(&hdac, DAC_CHANNEL_2);
/* USER CODE END 2 */
21
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
if (data_flag == CAPTURE_FINISHED) {
printf("%d %d\r\n",0,0);
for (int i=1; i < 2*sf ;i++){
printf("%d %d\r\n",i,data[i]-data[i-1]);
}
HAL_GPIO_WritePin(GPIOG, GPIO_PIN_14, GPIO_PIN_RESET);
data_flag = 0;
}
/* USER CODE END WHILE */
22
/* USER CODE BEGIN 4 */
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
HAL_GPIO_WritePin(GPIOG, GPIO_PIN_14, GPIO_PIN_SET);
data_flag = CAPTURE_START;
}
/* USER CODE END 4 */
23
/* USER CODE BEGIN Callback 0 */
int x_encoder;
if (htim->Instance == TIM10) {
if (data_flag == CAPTURE_START) {
HAL_DAC_SetValue(&hdac, DAC_CHANNEL_2, DAC_ALIGN_12B_R, (uint32_t)(2048+1024));
x_encoder = TIM2->CNT;
data[data_counter++] = x_encoder;
if (data_counter >= 2*sf) {
data_flag = CAPTURE_FINISHED;
data_counter = 0;
HAL_DAC_SetValue(&hdac, DAC_CHANNEL_2, DAC_ALIGN_12B_R, (uint32_t)(2048));
}
}
}
/* USER CODE END Callback 0 */
24
25
26
34 1000 2556( / sec)
96 4
1/( ) ( ) 55.6
( ) ( ) 1 0.015 1
b
a a m
rad
Ks s s
E s E s T s s
27
/* USER CODE BEGIN PV */
float Kp,Kd,control;
int32_t y,oldy,ref,interrupt_counter,data_counter,sampling_frequency;
int16_t data[2000];
volatile uint8_t data_flag,data_done;
/* USER CODE END PV */
/* USER CODE BEGIN Init */
sampling_frequency=1000;
Kp=8.0; Kd=0.00;
/* USER CODE END Init */
28
/* USER CODE BEGIN Callback 0 */
int32_t da_value;
if (htim->Instance == TIM10) {
y = TIM2->CNT;
interrupt_counter++;
if (interrupt_counter >= sampling_frequency*2) {
interrupt_counter=0;
if (data_flag==1) {
data_counter=0;
data_flag=2;
ref = 192;
}
else {
ref = 0;
}
}
if (interrupt_counter >= sampling_frequency*1) {
ref=0;
}
29
if (data_flag==2) {
if (data_counter<=sampling_frequency*2) {
data[data_counter++]=(int16_t)y;
}
else {
data_done=1;
}
}
control = Kp*(float)(ref-y)-(float)sampling_frequency*Kd*(float)(y-oldy);
oldy=y;
if (control > 2047) control = 2047;
if (control < -2048) control = -2048;
da_value = control + 2048;
HAL_DAC_SetValue(&hdac, DAC_CHANNEL_2, DAC_ALIGN_12B_R, (uint32_t)(da_value));
}
/* USER CODE END Callback 0 */
30
Step response for Kp=8.0 and Kd=0.0
31
Step response for Kp=8.0 and Kd=0.02
32
Step response for Kp=8.0 and Kd=0.04
33
Block diagram
34
Kp=8;Kd=0.0;Ki=0;
D=Kp+tf([Ki],[1 0])
G=tf([2*55.6*384/(2*3.14*204.8)],[0.015 1 0])
G1=feedback(G, tf([Kd 0],[1]))
Gt=feedback(D*G1,1)
t=0:0.001:0.2;
R=0.5*ones(size(t));
figure(2)
lsim(Gt,R,t)
pole(Gt)
axis([0 .2 0 1])
xlabel('Time');
ylabel('Revolution');
grid on
35
Step response for Kp=8.0 and Kd=0.0
36
Step response for Kp=8.0 and Kd=0.02
37
Step response for Kp=8.0 and Kd=0.04