Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of DCmotor2 by
controller.cpp@12:459af534d1ee, 2013-01-04 (annotated)
- Committer:
- kosaka
- Date:
- Fri Jan 04 12:00:48 2013 +0000
- Revision:
- 12:459af534d1ee
- Child:
- 13:ba71733c11d7
DC motor control program using TA7291P type H bridge driver and rotary encoder with A, B phase.;
Who changed what in which revision?
| User | Revision | Line number | New contents of line |
|---|---|---|---|
| kosaka | 12:459af534d1ee | 1 | // BLDCmotor.cpp: 各種3相同期モータに対するセンサあり運転のシミュレーション |
| kosaka | 12:459af534d1ee | 2 | // Kosaka Lab. 121215 |
| kosaka | 12:459af534d1ee | 3 | #include "mbed.h" |
| kosaka | 12:459af534d1ee | 4 | #include "QEI.h" |
| kosaka | 12:459af534d1ee | 5 | |
| kosaka | 12:459af534d1ee | 6 | #include "controller.h" |
| kosaka | 12:459af534d1ee | 7 | #include "Hbridge.h" |
| kosaka | 12:459af534d1ee | 8 | Serial pc(USBTX, USBRX); // Display on tera term in PC |
| kosaka | 12:459af534d1ee | 9 | |
| kosaka | 12:459af534d1ee | 10 | motor_parameters p; // モータの定数、信号など |
| kosaka | 12:459af534d1ee | 11 | current_loop_parameters il; // 電流制御マイナーループの定数、変数 |
| kosaka | 12:459af534d1ee | 12 | velocity_loop_parameters vl; // 速度制御メインループの定数、変数 |
| kosaka | 12:459af534d1ee | 13 | |
| kosaka | 12:459af534d1ee | 14 | QEI encoder (CH_A, CH_B, NC, N_ENC, QEI::X4_ENCODING); |
| kosaka | 12:459af534d1ee | 15 | // QEI(PinName channelA, mbed pin for channel A input. |
| kosaka | 12:459af534d1ee | 16 | // PinName channelB, mbed pin for channel B input. |
| kosaka | 12:459af534d1ee | 17 | // PinName index, mbed pin for channel Z input. (index channel input Z phase th=0), (pass NC if not needed). |
| kosaka | 12:459af534d1ee | 18 | // int pulsesPerRev, Number of pulses in one revolution(=360 deg). |
| kosaka | 12:459af534d1ee | 19 | // Encoding encoding = X2_ENCODING, X2 is default. X2 uses interrupts on the rising and falling edges of only channel A where as |
| kosaka | 12:459af534d1ee | 20 | // X4 uses them on both channels. |
| kosaka | 12:459af534d1ee | 21 | // ) |
| kosaka | 12:459af534d1ee | 22 | // void reset (void) |
| kosaka | 12:459af534d1ee | 23 | // Reset the encoder. |
| kosaka | 12:459af534d1ee | 24 | // int getCurrentState (void) |
| kosaka | 12:459af534d1ee | 25 | // Read the state of the encoder. |
| kosaka | 12:459af534d1ee | 26 | // int getPulses (void) |
| kosaka | 12:459af534d1ee | 27 | // Read the number of pulses recorded by the encoder. |
| kosaka | 12:459af534d1ee | 28 | // int getRevolutions (void) |
| kosaka | 12:459af534d1ee | 29 | // Read the number of revolutions recorded by the encoder on the index channel. |
| kosaka | 12:459af534d1ee | 30 | /*********** User setting for control parameters (end) ***************/ |
| kosaka | 12:459af534d1ee | 31 | |
| kosaka | 12:459af534d1ee | 32 | AnalogOut analog_out(DA_PORT); |
| kosaka | 12:459af534d1ee | 33 | AnalogIn VshuntR_Uplus(p19); // *3.3 [V], Volt of shunt R_SHUNT[Ohm]. The motor current i = v_shunt_r/R_SHUNT [A] |
| kosaka | 12:459af534d1ee | 34 | AnalogIn VshuntR_Uminus(p20); // *3.3 [V], Volt of shunt R_SHUNT[Ohm]. The motor current i = v_shunt_r/R_SHUNT [A] |
| kosaka | 12:459af534d1ee | 35 | AnalogIn VshuntR_Vplus(p16); // *3.3 [V], Volt of shunt R_SHUNT[Ohm]. The motor current i = v_shunt_r/R_SHUNT [A] |
| kosaka | 12:459af534d1ee | 36 | AnalogIn VshuntR_Vminus(p17); // *3.3 [V], Volt of shunt R_SHUNT[Ohm]. The motor current i = v_shunt_r/R_SHUNT [A] |
| kosaka | 12:459af534d1ee | 37 | |
| kosaka | 12:459af534d1ee | 38 | unsigned long _count; // sampling number |
| kosaka | 12:459af534d1ee | 39 | float _time; // time[s] |
| kosaka | 12:459af534d1ee | 40 | float debug[20]; // for debug |
| kosaka | 12:459af534d1ee | 41 | float disp[10]; // for printf to avoid interrupted by quicker process |
| kosaka | 12:459af534d1ee | 42 | DigitalOut led1(LED1); |
| kosaka | 12:459af534d1ee | 43 | DigitalOut led2(LED2); |
| kosaka | 12:459af534d1ee | 44 | DigitalOut led3(LED3); |
| kosaka | 12:459af534d1ee | 45 | DigitalOut led4(LED4); |
| kosaka | 12:459af534d1ee | 46 | |
| kosaka | 12:459af534d1ee | 47 | #ifdef GOOD_DATA |
| kosaka | 12:459af534d1ee | 48 | float data[1000][5]; // memory to save data offline instead of "online fprintf". |
| kosaka | 12:459af534d1ee | 49 | unsigned int count3; // |
| kosaka | 12:459af534d1ee | 50 | unsigned int count2=(int)(TS2/TS0); // |
| kosaka | 12:459af534d1ee | 51 | unsigned short _count_data=0; |
| kosaka | 12:459af534d1ee | 52 | #endif |
| kosaka | 12:459af534d1ee | 53 | DigitalOut debug_p26(p26); // p17 for debug |
| kosaka | 12:459af534d1ee | 54 | DigitalOut debug_p25(p25); // p17 for debug |
| kosaka | 12:459af534d1ee | 55 | //DigitalOut debug_p24(p24); // p17 for debug |
| kosaka | 12:459af534d1ee | 56 | //AnalogIn VCC(p19); // *3.3 [V], Volt of VCC for motor |
| kosaka | 12:459af534d1ee | 57 | //AnalogIn VCC2(p20); // *3.3 [V], Volt of (VCC-R i), R=2.5[Ohm]. R is for preventing too much i when deadtime is failed. |
| kosaka | 12:459af534d1ee | 58 | |
| kosaka | 12:459af534d1ee | 59 | unsigned short f_find_origin; // flag to find the origin of the rotor angle theta |
| kosaka | 12:459af534d1ee | 60 | |
| kosaka | 12:459af534d1ee | 61 | #if 1 //BUG!! if move sqrt2 to fast_math.h, sim starts and completed without working!? |
| kosaka | 12:459af534d1ee | 62 | float sqrt2(float x){ // √xのx=1まわりのテイラー展開 √x = 1 + 1/2*(x-1) -1/4*(x-1)^2 + ... |
| kosaka | 12:459af534d1ee | 63 | // return((1+x)*0.5); // 一次近似 |
| kosaka | 12:459af534d1ee | 64 | return(x+(1-x*x)*0.25); // 二次近似 |
| kosaka | 12:459af534d1ee | 65 | } |
| kosaka | 12:459af534d1ee | 66 | #endif |
| kosaka | 12:459af534d1ee | 67 | |
| kosaka | 12:459af534d1ee | 68 | void init_parameters(){ // IPMSMの機器定数等の設定, 制御器の初期化 |
| kosaka | 12:459af534d1ee | 69 | #ifdef SIMULATION |
| kosaka | 12:459af534d1ee | 70 | p.L = 0.0063; // H |
| kosaka | 12:459af534d1ee | 71 | p.R = 0.143; // Ω |
| kosaka | 12:459af534d1ee | 72 | p.phi = 0.176; // V s |
| kosaka | 12:459af534d1ee | 73 | p.Jm = 0.00018; // Nms^2 |
| kosaka | 12:459af534d1ee | 74 | p.p = 2; // 極対数 |
| kosaka | 12:459af534d1ee | 75 | #endif |
| kosaka | 12:459af534d1ee | 76 | p.th[0] = p.th[1] = 0; |
| kosaka | 12:459af534d1ee | 77 | p.w = 0; |
| kosaka | 12:459af534d1ee | 78 | p.i = 0; |
| kosaka | 12:459af534d1ee | 79 | p.v =0; |
| kosaka | 12:459af534d1ee | 80 | |
| kosaka | 12:459af534d1ee | 81 | p.w = 0; |
| kosaka | 12:459af534d1ee | 82 | |
| kosaka | 12:459af534d1ee | 83 | // 制御器の初期化 |
| kosaka | 12:459af534d1ee | 84 | vl.i_ref=0; // 電流指令[A] |
| kosaka | 12:459af534d1ee | 85 | vl.w_lpf = 0; // 検出した速度[rad/s] |
| kosaka | 12:459af534d1ee | 86 | vl.eI_w = 0; // 速度制御用偏差の積分値(積分項) |
| kosaka | 12:459af534d1ee | 87 | il.eI_i = 0; // 電流制御用偏差の積分値(積分項) |
| kosaka | 12:459af534d1ee | 88 | #ifndef SIMULATION |
| kosaka | 12:459af534d1ee | 89 | encoder.reset(); // set encoder counter zero |
| kosaka | 12:459af534d1ee | 90 | p.th[0] = p.th[1] = (float)encoder.getPulses()/(float)N_ENC*2.0*PI; // get angle [rad] from encoder |
| kosaka | 12:459af534d1ee | 91 | #endif |
| kosaka | 12:459af534d1ee | 92 | } |
| kosaka | 12:459af534d1ee | 93 | |
| kosaka | 12:459af534d1ee | 94 | void idq_control(){ |
| kosaka | 12:459af534d1ee | 95 | // dq座標電流PID制御器(電流マイナーループのフィードバック制御) |
| kosaka | 12:459af534d1ee | 96 | // 入力:指令電流 i_ref [A], 実電流 p.i [A], PI制御積分項 eI, サンプル時間 TS0 [s] |
| kosaka | 12:459af534d1ee | 97 | // 出力:電圧指令 v_ref [A] |
| kosaka | 12:459af534d1ee | 98 | float e; |
| kosaka | 12:459af534d1ee | 99 | |
| kosaka | 12:459af534d1ee | 100 | //debug[0]=il.i_ref; |
| kosaka | 12:459af534d1ee | 101 | // dq電流偏差の計算 |
| kosaka | 12:459af534d1ee | 102 | e = il.i_ref - p.i; |
| kosaka | 12:459af534d1ee | 103 | |
| kosaka | 12:459af534d1ee | 104 | // dq電流偏差の積分項の計算 |
| kosaka | 12:459af534d1ee | 105 | il.eI_i = il.eI_i + TS0*e; |
| kosaka | 12:459af534d1ee | 106 | |
| kosaka | 12:459af534d1ee | 107 | // PI制御 |
| kosaka | 12:459af534d1ee | 108 | il.v_ref = iKP*e + iKI*il.eI_i; |
| kosaka | 12:459af534d1ee | 109 | |
| kosaka | 12:459af534d1ee | 110 | } |
| kosaka | 12:459af534d1ee | 111 | |
| kosaka | 12:459af534d1ee | 112 | void current_loop(){ // 電流制御マイナーループ |
| kosaka | 12:459af534d1ee | 113 | // 電流センサによってiu, iv を検出 |
| kosaka | 12:459af534d1ee | 114 | #ifndef SIMULATION |
| kosaka | 12:459af534d1ee | 115 | p.i = (VshuntR_Uplus - VshuntR_Uminus) /R_SHUNT; // get i [A] from shunt resistance; |
| kosaka | 12:459af534d1ee | 116 | #endif |
| kosaka | 12:459af534d1ee | 117 | //debug[0]=p.i; |
| kosaka | 12:459af534d1ee | 118 | // dq電流制御(電流フィードバック制御) |
| kosaka | 12:459af534d1ee | 119 | debug[0]=il.i_ref; |
| kosaka | 12:459af534d1ee | 120 | #ifdef USE_CURRENT_CONTROL |
| kosaka | 12:459af534d1ee | 121 | idq_control(); |
| kosaka | 12:459af534d1ee | 122 | #else |
| kosaka | 12:459af534d1ee | 123 | il.v_ref = il.i_ref/iMAX*vMAX; |
| kosaka | 12:459af534d1ee | 124 | #endif |
| kosaka | 12:459af534d1ee | 125 | // 電圧指令の大きさをMAX制限 |
| kosaka | 12:459af534d1ee | 126 | // anti-windup: if u=v_ref is saturated, then reduce eI. |
| kosaka | 12:459af534d1ee | 127 | if( il.v_ref > vMAX ){ |
| kosaka | 12:459af534d1ee | 128 | il.eI_i -= (il.v_ref - vMAX)/iKI; if( il.eI_i<0 ){ il.eI_i=0;} |
| kosaka | 12:459af534d1ee | 129 | il.v_ref = vMAX; |
| kosaka | 12:459af534d1ee | 130 | }else if( il.v_ref < -vMAX ){ |
| kosaka | 12:459af534d1ee | 131 | il.eI_i -= (il.v_ref + vMAX)/iKI; if( il.eI_i>0 ){ il.eI_i=0;} |
| kosaka | 12:459af534d1ee | 132 | il.v_ref = -vMAX; |
| kosaka | 12:459af534d1ee | 133 | } |
| kosaka | 12:459af534d1ee | 134 | p.v = il.v_ref; |
| kosaka | 12:459af534d1ee | 135 | |
| kosaka | 12:459af534d1ee | 136 | p.th[1] = p.th[0]; // thを更新 |
| kosaka | 12:459af534d1ee | 137 | } |
| kosaka | 12:459af534d1ee | 138 | |
| kosaka | 12:459af534d1ee | 139 | |
| kosaka | 12:459af534d1ee | 140 | void vel_control(){ |
| kosaka | 12:459af534d1ee | 141 | // 速度制御器:速度偏差が入力され、q軸電流指令を出力。 |
| kosaka | 12:459af534d1ee | 142 | // 入力:指令速度 w_ref [rad/s], 実速度 w_lpf [rad/s], PI制御積分項 eI, サンプル時間 TS1 [s] |
| kosaka | 12:459af534d1ee | 143 | // 出力:電流指令 i_ref [A] |
| kosaka | 12:459af534d1ee | 144 | float e; |
| kosaka | 12:459af534d1ee | 145 | |
| kosaka | 12:459af534d1ee | 146 | // 速度偏差の計算 |
| kosaka | 12:459af534d1ee | 147 | e = vl.w_ref - vl.w_lpf; |
| kosaka | 12:459af534d1ee | 148 | |
| kosaka | 12:459af534d1ee | 149 | // 速度偏差の積分値の計算 |
| kosaka | 12:459af534d1ee | 150 | vl.eI_w = vl.eI_w + TS1*e; |
| kosaka | 12:459af534d1ee | 151 | |
| kosaka | 12:459af534d1ee | 152 | // PI制御 |
| kosaka | 12:459af534d1ee | 153 | vl.i_ref = wKp*e + wKi*vl.eI_w; |
| kosaka | 12:459af534d1ee | 154 | } |
| kosaka | 12:459af534d1ee | 155 | |
| kosaka | 12:459af534d1ee | 156 | void velocity_loop(){ // 速度制御メインループ(w_ref&beta_ref to idq_ref) |
| kosaka | 12:459af534d1ee | 157 | float tmp; |
| kosaka | 12:459af534d1ee | 158 | |
| kosaka | 12:459af534d1ee | 159 | // 速度ωを求めるために、位置θをオイラー微分して、一次ローパスフィルタに通す。 |
| kosaka | 12:459af534d1ee | 160 | #if 1 |
| kosaka | 12:459af534d1ee | 161 | tmp = p.th[0]-p.th[1]; |
| kosaka | 12:459af534d1ee | 162 | while( tmp> PI ){ tmp -= 2*PI;} |
| kosaka | 12:459af534d1ee | 163 | while( tmp<-PI ){ tmp += 2*PI;} |
| kosaka | 12:459af534d1ee | 164 | vl.w_lpf = iLPF*vl.w_lpf + tmp/TS0 *(1-iLPF); |
| kosaka | 12:459af534d1ee | 165 | #else |
| kosaka | 12:459af534d1ee | 166 | vl.w_lpf = p.th[0]; |
| kosaka | 12:459af534d1ee | 167 | #endif |
| kosaka | 12:459af534d1ee | 168 | // 速度制御:速度偏差が入力され、電流指令を出力。 |
| kosaka | 12:459af534d1ee | 169 | vel_control(); |
| kosaka | 12:459af534d1ee | 170 | |
| kosaka | 12:459af534d1ee | 171 | // 電流指令のMAX制限(異常に大きい指令値を制限する) |
| kosaka | 12:459af534d1ee | 172 | // anti-windup: if u=i_ref is saturated, then reduce eI. |
| kosaka | 12:459af534d1ee | 173 | if( vl.i_ref > iMAX ){ |
| kosaka | 12:459af534d1ee | 174 | vl.eI_w -= (vl.i_ref - iMAX)/wKi; if( vl.eI_w<0 ){ vl.eI_w=0;} |
| kosaka | 12:459af534d1ee | 175 | vl.i_ref = iMAX; |
| kosaka | 12:459af534d1ee | 176 | }else if( vl.i_ref < -iMAX ){ |
| kosaka | 12:459af534d1ee | 177 | vl.eI_w -= (vl.i_ref + iMAX)/wKi; if( vl.eI_w>0 ){ vl.eI_w=0;} |
| kosaka | 12:459af534d1ee | 178 | vl.i_ref = -iMAX; |
| kosaka | 12:459af534d1ee | 179 | } |
| kosaka | 12:459af534d1ee | 180 | //debug[0]=vl.eI_w; |
| kosaka | 12:459af534d1ee | 181 | |
| kosaka | 12:459af534d1ee | 182 | // 電流の目標値を速度制御メインループから電流制御マイナーループへ渡す。 |
| kosaka | 12:459af534d1ee | 183 | il.i_ref = vl.i_ref; |
| kosaka | 12:459af534d1ee | 184 | //debug[0]=il.i_ref; |
| kosaka | 12:459af534d1ee | 185 | } |
| kosaka | 12:459af534d1ee | 186 | |
| kosaka | 12:459af534d1ee | 187 | void v2Hbridge(){ // vより、PWMを発生 |
| kosaka | 12:459af534d1ee | 188 | float duty; |
| kosaka | 12:459af534d1ee | 189 | |
| kosaka | 12:459af534d1ee | 190 | // duty = (p.v/vMAX+1)*0.5; |
| kosaka | 12:459af534d1ee | 191 | // IN.duty = duty; |
| kosaka | 12:459af534d1ee | 192 | duty = p.v/vMAX; |
| kosaka | 12:459af534d1ee | 193 | if( duty>=0 ){ |
| kosaka | 12:459af534d1ee | 194 | IN.duty = duty; |
| kosaka | 12:459af534d1ee | 195 | if( IN.fReverse[0]==1 ){ |
| kosaka | 12:459af534d1ee | 196 | IN.fDeadtime = 1; |
| kosaka | 12:459af534d1ee | 197 | } |
| kosaka | 12:459af534d1ee | 198 | IN.fReverse[0] = 0; |
| kosaka | 12:459af534d1ee | 199 | }else{ |
| kosaka | 12:459af534d1ee | 200 | IN.duty = -duty; |
| kosaka | 12:459af534d1ee | 201 | if( IN.fReverse[0]==0 ){ |
| kosaka | 12:459af534d1ee | 202 | IN.fDeadtime = 1; |
| kosaka | 12:459af534d1ee | 203 | } |
| kosaka | 12:459af534d1ee | 204 | IN.fReverse[0] = 1; |
| kosaka | 12:459af534d1ee | 205 | } |
| kosaka | 12:459af534d1ee | 206 | } |
| kosaka | 12:459af534d1ee | 207 | |
| kosaka | 12:459af534d1ee | 208 | #ifdef SIMULATION |
| kosaka | 12:459af534d1ee | 209 | void sim_motor(){ |
| kosaka | 12:459af534d1ee | 210 | // モータシミュレータ |
| kosaka | 12:459af534d1ee | 211 | // 入力信号:電圧p.v [V]、負荷トルクp.TL [Nm] |
| kosaka | 12:459af534d1ee | 212 | // 出力信号:モータ角度p.th[0] [rad], モータ速度p.w [rad/s], モータ電流p.i [A] |
| kosaka | 12:459af534d1ee | 213 | float i_dot, Tall, TL; |
| kosaka | 12:459af534d1ee | 214 | analog_out=p.v/100.+0.5;//debug |
| kosaka | 12:459af534d1ee | 215 | //debug[0]=p.v; |
| kosaka | 12:459af534d1ee | 216 | // get i |
| kosaka | 12:459af534d1ee | 217 | i_dot = (1.0/p.L) * ( p.v - (p.R*p.i + p.w*p.phi) ); |
| kosaka | 12:459af534d1ee | 218 | p.i = p.i + TS0*i_dot; |
| kosaka | 12:459af534d1ee | 219 | |
| kosaka | 12:459af534d1ee | 220 | // モータトルクの計算 |
| kosaka | 12:459af534d1ee | 221 | p.Tm = p.p * p.phi * p.i; |
| kosaka | 12:459af534d1ee | 222 | |
| kosaka | 12:459af534d1ee | 223 | // モータ速度ωの計算 |
| kosaka | 12:459af534d1ee | 224 | if( abs(p.w) > 5*2*PI ) |
| kosaka | 12:459af534d1ee | 225 | if( p.w>=0 ) TL= p.TL; |
| kosaka | 12:459af534d1ee | 226 | else TL=-p.TL; |
| kosaka | 12:459af534d1ee | 227 | else |
| kosaka | 12:459af534d1ee | 228 | TL = p.w/(5*2*PI)*p.TL; |
| kosaka | 12:459af534d1ee | 229 | |
| kosaka | 12:459af534d1ee | 230 | Tall = p.Tm - TL; |
| kosaka | 12:459af534d1ee | 231 | p.w = p.w + TS0 * (1.0 / p.Jm) * Tall; |
| kosaka | 12:459af534d1ee | 232 | |
| kosaka | 12:459af534d1ee | 233 | // モータ角度θの計算 |
| kosaka | 12:459af534d1ee | 234 | p.th[0] = p.th[0] + TS0 * p.w; |
| kosaka | 12:459af534d1ee | 235 | if( p.th[0]>2*PI) |
| kosaka | 12:459af534d1ee | 236 | p.th[0] = p.th[0] - 2*PI; |
| kosaka | 12:459af534d1ee | 237 | |
| kosaka | 12:459af534d1ee | 238 | if( p.th[0]<0 ) |
| kosaka | 12:459af534d1ee | 239 | p.th[0] = p.th[0] + 2*PI; |
| kosaka | 12:459af534d1ee | 240 | //debug[0]=p.v; |
| kosaka | 12:459af534d1ee | 241 | } |
| kosaka | 12:459af534d1ee | 242 | #endif |
| kosaka | 12:459af534d1ee | 243 | |
| kosaka | 12:459af534d1ee | 244 | void data2mbedUSB(){ // save data to mbed USB drive |
| kosaka | 12:459af534d1ee | 245 | if( _count_data<1000 ){ |
| kosaka | 12:459af534d1ee | 246 | data[_count_data][0]=p.th[0]/*vl.w_ref*/; data[_count_data][1]=debug[0]; |
| kosaka | 12:459af534d1ee | 247 | data[_count_data][2]=vl.w_lpf; data[_count_data][3]=_count*TS0; data[_count_data][4]=il.v_ref; |
| kosaka | 12:459af534d1ee | 248 | _count_data++; |
| kosaka | 12:459af534d1ee | 249 | } |
| kosaka | 12:459af534d1ee | 250 | #if 0 |
| kosaka | 12:459af534d1ee | 251 | if( _count_data<500 ){ |
| kosaka | 12:459af534d1ee | 252 | debug[0]=p.vab[0]; debug[1]=p.vab[1]; debug[2]=il.vdq_ref[0]; debug[3]=il.vdq_ref[1]; debug[4]=p.iab[0]; |
| kosaka | 12:459af534d1ee | 253 | debug[5]=p.iab[1]; debug[6]=p.vuvw[0]; debug[7]=p.vuvw[1]; debug[8]=p.vuvw[2]; debug[9]=p.iuvw[0]; |
| kosaka | 12:459af534d1ee | 254 | debug[10]=p.iuvw[1]; debug[11]=p.iuvw[2]; debug[12]=p.idq[0]; debug[13]=p.idq[1]; debug[14]=p.TL; |
| kosaka | 12:459af534d1ee | 255 | debug[15]=p.Tm; debug[16]=p.w; debug[17]=vl.w_lpf; debug[18]=p.th[0]; debug[19]=_count*TS0;//_time; |
| kosaka | 12:459af534d1ee | 256 | //BUG for(j=0;j<19;j++){ fprintf( fp, "%f, ",debug[j]);} fprintf( fp, "%f\n",debug[19]); |
| kosaka | 12:459af534d1ee | 257 | for(j=0;j<19;j++){ printf("%f, ",debug[j]);} printf("%f\n",debug[19]); |
| kosaka | 12:459af534d1ee | 258 | // for(j=0;j<19;j++){ pc.printf("%f, ",debug[j]);} pc.printf("%f\n",debug[19]); |
| kosaka | 12:459af534d1ee | 259 | } |
| kosaka | 12:459af534d1ee | 260 | #endif |
| kosaka | 12:459af534d1ee | 261 | } |
| kosaka | 12:459af534d1ee | 262 | void timerTS0(){ // timer called every TS0[s]. |
| kosaka | 12:459af534d1ee | 263 | debug_p26 = 1; |
| kosaka | 12:459af534d1ee | 264 | _count++; |
| kosaka | 12:459af534d1ee | 265 | _time += TS0; |
| kosaka | 12:459af534d1ee | 266 | |
| kosaka | 12:459af534d1ee | 267 | current_loop(); // 電流制御マイナーループ(i_ref to volt) |
| kosaka | 12:459af534d1ee | 268 | v2Hbridge(); // volt. to Hbridge |
| kosaka | 12:459af534d1ee | 269 | #ifdef SIMULATION |
| kosaka | 12:459af534d1ee | 270 | //debug[0]=p.v; |
| kosaka | 12:459af534d1ee | 271 | // モータシミュレータ |
| kosaka | 12:459af534d1ee | 272 | sim_motor(); // IPM, dq座標 |
| kosaka | 12:459af534d1ee | 273 | #else |
| kosaka | 12:459af534d1ee | 274 | p.th[1] = p.th[0]; |
| kosaka | 12:459af534d1ee | 275 | p.th[0] = (float)encoder.getPulses()/(float)N_ENC*2.0*PI; // get angle [rad] from encoder |
| kosaka | 12:459af534d1ee | 276 | #endif |
| kosaka | 12:459af534d1ee | 277 | debug_p26 = 0; |
| kosaka | 12:459af534d1ee | 278 | } |
| kosaka | 12:459af534d1ee | 279 | void timerTS1(void const *argument){ |
| kosaka | 12:459af534d1ee | 280 | debug_p25 = 1; |
| kosaka | 12:459af534d1ee | 281 | velocity_loop(); // 速度制御メインループ(w_ref&beta_ref to idq_ref) |
| kosaka | 12:459af534d1ee | 282 | debug_p25 = 0; |
| kosaka | 12:459af534d1ee | 283 | } |
| kosaka | 12:459af534d1ee | 284 | |
| kosaka | 12:459af534d1ee | 285 | void display2PC(){ // display to tera term on PC |
| kosaka | 12:459af534d1ee | 286 | pc.printf("%8.1f[s]\t%8.2f[V]\t%8.2f [Hz]\t%8.2f\t%8.2f\r\n", _time, il.v_ref, vl.w_lpf/(2*PI), vl.w_ref/(2*PI), debug[0]); // print to tera term |
| kosaka | 12:459af534d1ee | 287 | // pc.printf("%8.1f[s]\t%8.5f[V]\t%4d [deg]\t%8.2f\r\n", _time, _u, (int)(_th/(2*PI)*360.0), _r);//debug[0]*3.3/R_SHUNT); // print to tera term |
| kosaka | 12:459af534d1ee | 288 | } |
| kosaka | 12:459af534d1ee | 289 | void timerTS2(){ |
| kosaka | 12:459af534d1ee | 290 | } |
| kosaka | 12:459af534d1ee | 291 | void timerTS3(){ |
| kosaka | 12:459af534d1ee | 292 | data2mbedUSB(); // data2mbedUSB() is called every TS3[s]. |
| kosaka | 12:459af534d1ee | 293 | } |
| kosaka | 12:459af534d1ee | 294 | void timerTS4(){ |
| kosaka | 12:459af534d1ee | 295 | display2PC(); // display to tera term on PC. display2PC() is called every TS4[s]. |
| kosaka | 12:459af534d1ee | 296 | } |
