DC motor control program using TA7291P type H bridge driver and rotary encoder with A, B phase.

Dependencies:   QEI mbed-rtos mbed

Fork of DCmotor by manabu kosaka

Committer:
kosaka
Date:
Tue Mar 12 04:32:22 2013 +0000
Revision:
14:02411880ffb9
Parent:
13:ba71733c11d7
130303;

Who changed what in which revision?

UserRevisionLine numberNew contents of line
kosaka 13:ba71733c11d7 1 // controller.cpp: モータ制御器(位置制御、電流制御)
kosaka 13:ba71733c11d7 2 #include "mbed.h" // mbedマイコンではstdio.hに相当
kosaka 13:ba71733c11d7 3 #include "QEI.h" // エンコーダ用ライブラリを使用
kosaka 12:459af534d1ee 4
kosaka 13:ba71733c11d7 5 #include "controller.h" // controller.cpp: モータ制御器(位置制御、電流制御)
kosaka 13:ba71733c11d7 6 #include "Hbridge.h" // Hbridge.cpp: モータ駆動用ドライバのフルブリッジ(Hブリッジ)をPWM駆動する。
kosaka 13:ba71733c11d7 7 Serial pc(USBTX, USBRX); // PCのモニタ上のtera termに文字を表示する宣言
kosaka 12:459af534d1ee 8
kosaka 12:459af534d1ee 9 motor_parameters p; // モータの定数、信号など
kosaka 12:459af534d1ee 10 current_loop_parameters il; // 電流制御マイナーループの定数、変数
kosaka 12:459af534d1ee 11 velocity_loop_parameters vl; // 速度制御メインループの定数、変数
kosaka 12:459af534d1ee 12
kosaka 13:ba71733c11d7 13 QEI encoder (CH_A, CH_B, NC, N_ENC, QEI::X4_ENCODING); // エンコーダ用ライブラリを使用
kosaka 12:459af534d1ee 14 // QEI(PinName channelA, mbed pin for channel A input.
kosaka 12:459af534d1ee 15 // PinName channelB, mbed pin for channel B input.
kosaka 12:459af534d1ee 16 // PinName index, mbed pin for channel Z input. (index channel input Z phase th=0), (pass NC if not needed).
kosaka 12:459af534d1ee 17 // int pulsesPerRev, Number of pulses in one revolution(=360 deg).
kosaka 12:459af534d1ee 18 // 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 19 // X4 uses them on both channels.
kosaka 12:459af534d1ee 20 // )
kosaka 12:459af534d1ee 21 // void reset (void)
kosaka 12:459af534d1ee 22 // Reset the encoder.
kosaka 12:459af534d1ee 23 // int getCurrentState (void)
kosaka 12:459af534d1ee 24 // Read the state of the encoder.
kosaka 12:459af534d1ee 25 // int getPulses (void)
kosaka 12:459af534d1ee 26 // Read the number of pulses recorded by the encoder.
kosaka 12:459af534d1ee 27 // int getRevolutions (void)
kosaka 12:459af534d1ee 28 // Read the number of revolutions recorded by the encoder on the index channel.
kosaka 12:459af534d1ee 29 /*********** User setting for control parameters (end) ***************/
kosaka 12:459af534d1ee 30
kosaka 13:ba71733c11d7 31 AnalogOut analog_out(DA_PORT); // デバッグ用DA(アナログ信号をDA_PORTに出力)
kosaka 12:459af534d1ee 32
kosaka 13:ba71733c11d7 33 unsigned long _countTS0; // TS0[s]ごとのカウント数
kosaka 13:ba71733c11d7 34 float _time; // [s], プログラム開始時からの経過時間
kosaka 13:ba71733c11d7 35 float debug[20]; // デバッグ用変数
kosaka 13:ba71733c11d7 36 DigitalOut led1(LED1); // mbedマイコンのLED1を点灯
kosaka 13:ba71733c11d7 37 DigitalOut led2(LED2); // mbedマイコンのLED2を点灯
kosaka 13:ba71733c11d7 38 DigitalOut led3(LED3); // mbedマイコンのLED3を点灯
kosaka 13:ba71733c11d7 39 DigitalOut led4(LED4); // mbedマイコンのLED4を点灯
kosaka 12:459af534d1ee 40
kosaka 13:ba71733c11d7 41
kosaka 13:ba71733c11d7 42 float data[1000][5]; // PC上のmbed USB ディスクにセーブするデータ memory to save data offline instead of "online fprintf".
kosaka 13:ba71733c11d7 43 //unsigned int count3; //
kosaka 13:ba71733c11d7 44 //unsigned int count2=(int)(TS2/TS0); //
kosaka 13:ba71733c11d7 45 unsigned short _countTS3=0;
kosaka 13:ba71733c11d7 46
kosaka 12:459af534d1ee 47 DigitalOut debug_p26(p26); // p17 for debug
kosaka 12:459af534d1ee 48 DigitalOut debug_p25(p25); // p17 for debug
kosaka 12:459af534d1ee 49 //DigitalOut debug_p24(p24); // p17 for debug
kosaka 12:459af534d1ee 50 //AnalogIn VCC(p19); // *3.3 [V], Volt of VCC for motor
kosaka 12:459af534d1ee 51 //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 52
kosaka 12:459af534d1ee 53
kosaka 13:ba71733c11d7 54 void init_parameters(){
kosaka 13:ba71733c11d7 55 // モータ機器定数等、モータ・制御器の初期値の設定
kosaka 13:ba71733c11d7 56 // 親関数: main()
kosaka 13:ba71733c11d7 57 // 子関数: なし
kosaka 12:459af534d1ee 58 #ifdef SIMULATION
kosaka 13:ba71733c11d7 59 // モータ機器定数の設定
kosaka 13:ba71733c11d7 60 p.L = 0.0063; // [H], インダクタンス
kosaka 13:ba71733c11d7 61 p.R = 0.143; // [Ω], モータ巻線抵抗
kosaka 13:ba71733c11d7 62 p.phi = 0.176; // [V s], 永久磁石の鎖交磁束
kosaka 13:ba71733c11d7 63 p.Jm = 0.00018; // [Nms^2], イナーシャ
kosaka 12:459af534d1ee 64 p.p = 2; // 極対数
kosaka 12:459af534d1ee 65 #endif
kosaka 13:ba71733c11d7 66 // モータの初期値の設定
kosaka 13:ba71733c11d7 67 #ifdef SIMULATION
kosaka 13:ba71733c11d7 68 p.th[0] = p.th[1] = 0; // [rad], ロータの回転角, th[0]は現在の値, th[1]はTS0[s]だけ過去の値
kosaka 13:ba71733c11d7 69 #else
kosaka 13:ba71733c11d7 70 encoder.reset(); // 現在の回転角を原点に設定(エンコーダのカウント数をゼロに設定) set encoder counter zero
kosaka 13:ba71733c11d7 71 p.th[0] = p.th[1] = (float)encoder.getPulses()/(float)N_ENC*2.0*PI; // [rad], ロータの回転角をエンコーダ検出値に設定, th[0]は現在の値, th[1]はTS0[s]だけ過去の値 get angle [rad] from encoder
kosaka 13:ba71733c11d7 72 #endif
kosaka 13:ba71733c11d7 73 p.w = 0; // [rad/s], モータの回転速度
kosaka 13:ba71733c11d7 74 p.i = 0; // [A], モータ電流
kosaka 13:ba71733c11d7 75 p.v =0; // [V], モータ電圧
kosaka 12:459af534d1ee 76
kosaka 13:ba71733c11d7 77 // 制御器の初期値の設定
kosaka 12:459af534d1ee 78 vl.i_ref=0; // 電流指令[A]
kosaka 12:459af534d1ee 79 vl.w_lpf = 0; // 検出した速度[rad/s]
kosaka 13:ba71733c11d7 80 vl.eI = 0; // 速度制御用偏差の積分値(積分項)
kosaka 13:ba71733c11d7 81 vl.e_old = 0; // 速度制御用偏差の1サンプル過去の値
kosaka 13:ba71733c11d7 82 il.eI = 0; // 電流制御用偏差の積分値(積分項)
kosaka 13:ba71733c11d7 83 il.e_old = 0; // 電流制御用偏差の1サンプル過去の値
kosaka 12:459af534d1ee 84 }
kosaka 12:459af534d1ee 85
kosaka 13:ba71733c11d7 86 void i_control(){
kosaka 13:ba71733c11d7 87 // 電流PID制御器(電流マイナーループのフィードバック制御)
kosaka 13:ba71733c11d7 88 // 親関数: current_loop()
kosaka 13:ba71733c11d7 89 // 子関数: なし
kosaka 13:ba71733c11d7 90 // 入力:指令電流 il.i_ref [A], 実電流 p.i [A], PID制御積分項 il.eI, サンプル時間 TS0 [s]
kosaka 13:ba71733c11d7 91 // 出力:電圧指令 il.v_ref [A]
kosaka 13:ba71733c11d7 92 float e, ed;
kosaka 12:459af534d1ee 93
kosaka 13:ba71733c11d7 94 e = il.i_ref - p.i; // 電流偏差の計算
kosaka 13:ba71733c11d7 95
kosaka 13:ba71733c11d7 96 il.eI = il.eI + TS0*e; // 電流偏差の積分項の計算
kosaka 12:459af534d1ee 97
kosaka 13:ba71733c11d7 98 ed = (e-il.e_old)/TS0; // 電流偏差の微分値の計算
kosaka 13:ba71733c11d7 99 il.e_old = e; // 電流偏差の1サンプル過去の値を更新
kosaka 12:459af534d1ee 100
kosaka 13:ba71733c11d7 101 il.v_ref = iKP*e + iKI*il.eI + iKD*ed; // PID制御器の出力を計算
kosaka 12:459af534d1ee 102 }
kosaka 12:459af534d1ee 103
kosaka 13:ba71733c11d7 104 void current_loop(){
kosaka 13:ba71733c11d7 105 // 電流制御マイナーループ、サンプル時間TS0秒
kosaka 13:ba71733c11d7 106 // 親関数: timerTS0()
kosaka 13:ba71733c11d7 107 // 子関数: i_control()
kosaka 13:ba71733c11d7 108 // 入力:指令電流 il.i_ref [A], 実電流 p.i [A]
kosaka 13:ba71733c11d7 109 // 出力:電圧指令 p.v [V]
kosaka 13:ba71733c11d7 110
kosaka 12:459af534d1ee 111 #ifdef USE_CURRENT_CONTROL
kosaka 13:ba71733c11d7 112 i_control(); // 電流制御(電流フィードバック制御)
kosaka 12:459af534d1ee 113 #else
kosaka 13:ba71733c11d7 114 il.v_ref = il.i_ref/iMAX*vMAX; // 速度制御の出力をそのまま電圧指令にする
kosaka 12:459af534d1ee 115 #endif
kosaka 12:459af534d1ee 116 // 電圧指令の大きさをMAX制限
kosaka 13:ba71733c11d7 117 // アンチワインゴアップ:制御入力v_refが飽和したとき積分項eIを減衰させる anti-windup: if u=v_ref is saturated, then reduce eI.
kosaka 13:ba71733c11d7 118 if( il.v_ref > vMAX ){ // 電圧指令がプラス側に大きすぎるとき
kosaka 13:ba71733c11d7 119 il.eI -= (il.v_ref - vMAX)/iKI; // 電圧指令がvMAXと等しくなる積分項を計算
kosaka 13:ba71733c11d7 120 if( il.eI<0 ){ il.eI=0;} // 積分項が負になるとゼロにする
kosaka 13:ba71733c11d7 121 il.v_ref = vMAX; // 電圧指令をvMAXにする
kosaka 13:ba71733c11d7 122 }else if( il.v_ref < -vMAX ){ // 電圧指令がマイナス側に大きすぎるとき
kosaka 13:ba71733c11d7 123 il.eI -= (il.v_ref + vMAX)/iKI; // 電圧指令が-vMAXと等しくなる積分項を計算
kosaka 13:ba71733c11d7 124 if( il.eI>0 ){ il.eI=0;} // 積分項が正になるとゼロにする
kosaka 13:ba71733c11d7 125 il.v_ref = -vMAX; // 電圧指令を-vMAXにする
kosaka 12:459af534d1ee 126 }
kosaka 13:ba71733c11d7 127 p.v = il.v_ref; // 指令電圧をp.vに格納してv2Hbridge()に渡す
kosaka 12:459af534d1ee 128 }
kosaka 12:459af534d1ee 129
kosaka 12:459af534d1ee 130
kosaka 12:459af534d1ee 131 void vel_control(){
kosaka 12:459af534d1ee 132 // 速度制御器:速度偏差が入力され、q軸電流指令を出力。
kosaka 13:ba71733c11d7 133 // 入力:指令速度 vl.w_ref [rad/s], 実速度 vl.w_lpf [rad/s], PI制御積分項 vl.eI, サンプル時間 TS1 [s]
kosaka 13:ba71733c11d7 134 // 出力:電流指令 vl.i_ref [A]
kosaka 13:ba71733c11d7 135 float e, ed;
kosaka 13:ba71733c11d7 136
kosaka 13:ba71733c11d7 137 e = vl.w_ref - vl.w_lpf; // 速度偏差の計算
kosaka 14:02411880ffb9 138 debug[1]=vl.w_ref/2/PI;//[Hz], for debug
kosaka 12:459af534d1ee 139
kosaka 13:ba71733c11d7 140 vl.eI = vl.eI + TS1*e; // 速度偏差の積分値の計算
kosaka 12:459af534d1ee 141
kosaka 13:ba71733c11d7 142 ed = (e-vl.e_old)/TS1; // 速度偏差の微分値の計算
kosaka 13:ba71733c11d7 143 vl.e_old = e; // 速度偏差の1サンプル過去の値を更新
kosaka 12:459af534d1ee 144
kosaka 13:ba71733c11d7 145 vl.i_ref = wKp*e + wKi*vl.eI + wKd*ed; // PID制御器の出力を計算
kosaka 12:459af534d1ee 146 }
kosaka 12:459af534d1ee 147
kosaka 13:ba71733c11d7 148 void velocity_loop(){
kosaka 13:ba71733c11d7 149 // 速度制御メインループ、サンプル時間TS1秒
kosaka 13:ba71733c11d7 150 // 親関数: timerTS1()
kosaka 13:ba71733c11d7 151 // 子関数: vel_control()
kosaka 13:ba71733c11d7 152 // 入力:指令速度 vl.w_ref [rad/s], 実速度 vl.w_lpf [rad/s]
kosaka 13:ba71733c11d7 153 // 出力:電圧指令 il.i_ref [A]
kosaka 12:459af534d1ee 154 float tmp;
kosaka 12:459af534d1ee 155
kosaka 13:ba71733c11d7 156 #if 1
kosaka 12:459af534d1ee 157 // 速度ωを求めるために、位置θをオイラー微分して、一次ローパスフィルタに通す。
kosaka 13:ba71733c11d7 158 tmp = p.th[0]-p.th[1]; // 回転角の差分を取る
kosaka 13:ba71733c11d7 159 while( tmp> PI ){ tmp -= 2*PI;} // 差分の値域を-π~+πに設定
kosaka 13:ba71733c11d7 160 while( tmp<-PI ){ tmp += 2*PI;} // 〃
kosaka 13:ba71733c11d7 161 vl.w_lpf = iLPF*vl.w_lpf + tmp/TS0 *(1-iLPF); // オイラー微分近似+1次LPFで現在速度を計算
kosaka 12:459af534d1ee 162 #else
kosaka 12:459af534d1ee 163 vl.w_lpf = p.th[0];
kosaka 12:459af534d1ee 164 #endif
kosaka 13:ba71733c11d7 165
kosaka 13:ba71733c11d7 166 vel_control(); // 速度制御:速度偏差が入力され、電流指令を出力。
kosaka 12:459af534d1ee 167
kosaka 13:ba71733c11d7 168 // 電流指令の大きさをMAX制限
kosaka 13:ba71733c11d7 169 // アンチワインドアップ:制御入力i_refが飽和したとき積分項eIを減衰させる anti-windup: if u=v_ref is saturated, then reduce eI.
kosaka 13:ba71733c11d7 170 if( vl.i_ref > iMAX ){ // 電流指令がプラス側に大きすぎるとき
kosaka 13:ba71733c11d7 171 vl.eI -= (vl.i_ref - iMAX)/wKi; // 電流指令がvMAXと等しくなる積分項を計算
kosaka 13:ba71733c11d7 172 if( vl.eI<0 ){ vl.eI=0;} // 積分項が負になるとゼロにする
kosaka 13:ba71733c11d7 173 vl.i_ref = iMAX; // 電流指令をvMAXにする
kosaka 13:ba71733c11d7 174 }else if( vl.i_ref < -iMAX ){ // 電流指令がマイナス側に大きすぎるとき
kosaka 13:ba71733c11d7 175 vl.eI -= (vl.i_ref + iMAX)/wKi; // 電流指令が-vMAXと等しくなる積分項を計算
kosaka 13:ba71733c11d7 176 if( vl.eI>0 ){ vl.eI=0;} // 積分項が正になるとゼロにする
kosaka 13:ba71733c11d7 177 vl.i_ref = -iMAX; // 電流指令を-vMAXにする
kosaka 12:459af534d1ee 178 }
kosaka 12:459af534d1ee 179
kosaka 13:ba71733c11d7 180 il.i_ref = vl.i_ref; // 電流の目標値を速度制御メインループから電流制御マイナーループへ渡す。
kosaka 12:459af534d1ee 181 }
kosaka 12:459af534d1ee 182
kosaka 13:ba71733c11d7 183 void v2Hbridge(){
kosaka 13:ba71733c11d7 184 // 指令電圧vより、PWM関数pwm_out()のパラメータ(dutyとフラグ)をセット。
kosaka 13:ba71733c11d7 185 // 親関数: timerTS0()
kosaka 13:ba71733c11d7 186 // 子関数: なし
kosaka 13:ba71733c11d7 187 // 入力:電圧指令 p.v [V]
kosaka 13:ba71733c11d7 188 // 出力:フルブリッジのfwdIN, rvsIN用duty,
kosaka 13:ba71733c11d7 189 // デッドタイムフラグfDeadtime, モータ逆回転フラグfReverse
kosaka 12:459af534d1ee 190 float duty;
kosaka 12:459af534d1ee 191
kosaka 13:ba71733c11d7 192 duty = p.v/vMAX; // 指令電圧p.vの値を最大電圧vMAXで割って-1~1にしてdutyに代入
kosaka 13:ba71733c11d7 193 if( duty>=0 ){ // dutyがプラスでモータが順回転のとき
kosaka 13:ba71733c11d7 194 IN.duty = duty; // dutyをPWM関数pwm_out()に渡す
kosaka 13:ba71733c11d7 195 if( IN.fReverse==1 ){ // モータが逆回転から順回転に切り替ったとき
kosaka 13:ba71733c11d7 196 IN.fDeadtime = 1; // デッドタイム要求フラグをオンにする
kosaka 12:459af534d1ee 197 }
kosaka 13:ba71733c11d7 198 IN.fReverse = 0; // 逆回転フラグをオフにする
kosaka 13:ba71733c11d7 199 }else{ // dutyがマイナスでモータが逆回転のとき
kosaka 13:ba71733c11d7 200 IN.duty = -duty; // dutyの絶対値をPWM関数pwm_out()に渡す
kosaka 13:ba71733c11d7 201 if( IN.fReverse==0 ){ // モータが順回転から逆回転に切り替ったとき
kosaka 13:ba71733c11d7 202 IN.fDeadtime = 1; // デッドタイム要求フラグをオンにする
kosaka 12:459af534d1ee 203 }
kosaka 13:ba71733c11d7 204 IN.fReverse = 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 13:ba71733c11d7 210 // ブラシ付きDCモータシミュレータ
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 13:ba71733c11d7 216 // 電圧方程式より、指令電圧から電流を計算
kosaka 13:ba71733c11d7 217 i_dot = (1.0/p.L) * ( p.v - (p.R*p.i + p.w*p.phi) ); // 電圧方程式より電流の微分値を計算
kosaka 13:ba71733c11d7 218 p.i = p.i + TS0*i_dot; // オイラー近似微分で電流の微分値を積分して電流を求める
kosaka 12:459af534d1ee 219
kosaka 13:ba71733c11d7 220 // トルク方程式より、電流からモータトルクを計算
kosaka 12:459af534d1ee 221 p.Tm = p.p * p.phi * p.i;
kosaka 12:459af534d1ee 222
kosaka 12:459af534d1ee 223 // モータ速度ωの計算
kosaka 13:ba71733c11d7 224 if( abs(p.w) > 5*2*PI ){ // 速度が5rps以上のとき、減速するように負荷トルクTLをセット
kosaka 13:ba71733c11d7 225 if( p.w>=0 ){ TL= p.TL;} // 速度が正なら負荷トルクを+TLにセット
kosaka 13:ba71733c11d7 226 else{ TL=-p.TL;} // 速度が負なら負荷トルクを-TLにセット
kosaka 13:ba71733c11d7 227 }else{ // 速度が5rps以下のとき、速度に比例した負荷トルクをセット
kosaka 12:459af534d1ee 228 TL = p.w/(5*2*PI)*p.TL;
kosaka 13:ba71733c11d7 229 }
kosaka 12:459af534d1ee 230
kosaka 13:ba71733c11d7 231 Tall = p.Tm - TL; // モータのシャフトにかかるトルクを計算
kosaka 13:ba71733c11d7 232 p.w = p.w + TS0 * (1.0 / p.Jm) * Tall; // モータの機械的特性をシミュレートしてトルクから速度を計算
kosaka 12:459af534d1ee 233
kosaka 12:459af534d1ee 234 // モータ角度θの計算
kosaka 13:ba71733c11d7 235 p.th[0] = p.th[0] + TS0 * p.w; // オイラー近似微分で速度を積分して回転角を計算
kosaka 12:459af534d1ee 236
kosaka 13:ba71733c11d7 237 // 回転角の値域を0~2πにする
kosaka 13:ba71733c11d7 238 if( p.th[0]>2*PI) // 回転角が2π以上のとき
kosaka 13:ba71733c11d7 239 p.th[0] = p.th[0] - 2*PI; // 2π引く
kosaka 13:ba71733c11d7 240 if( p.th[0]<0 ) // 回転角が負のとき
kosaka 13:ba71733c11d7 241 p.th[0] = p.th[0] + 2*PI; // 2π足す
kosaka 12:459af534d1ee 242 }
kosaka 12:459af534d1ee 243 #endif
kosaka 12:459af534d1ee 244
kosaka 13:ba71733c11d7 245 void data2mbedUSB(){ // PC上のmbed USB ディスクにセーブするためのデータをTS3[s]ごとに代入 save data to mbed USB drive
kosaka 13:ba71733c11d7 246 if( _countTS3<1000 ){ // データ数が1,000の5種類のデータをメモリーに貯める
kosaka 14:02411880ffb9 247 data[_countTS3][0]=debug[0]; data[_countTS3][1]=debug[1];
kosaka 13:ba71733c11d7 248 data[_countTS3][2]=vl.w_lpf; data[_countTS3][3]=_countTS0*TS0; data[_countTS3][4]=il.v_ref;
kosaka 13:ba71733c11d7 249 _countTS3++;
kosaka 12:459af534d1ee 250 }
kosaka 12:459af534d1ee 251 #if 0
kosaka 13:ba71733c11d7 252 if( _countTS3<500 ){
kosaka 12:459af534d1ee 253 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 254 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 255 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 13:ba71733c11d7 256 debug[15]=p.Tm; debug[16]=p.w; debug[17]=vl.w_lpf; debug[18]=p.th[0]; debug[19]=_countTS0*TS0;//_time;
kosaka 12:459af534d1ee 257 //BUG for(j=0;j<19;j++){ fprintf( fp, "%f, ",debug[j]);} fprintf( fp, "%f\n",debug[19]);
kosaka 12:459af534d1ee 258 for(j=0;j<19;j++){ printf("%f, ",debug[j]);} printf("%f\n",debug[19]);
kosaka 12:459af534d1ee 259 // for(j=0;j<19;j++){ pc.printf("%f, ",debug[j]);} pc.printf("%f\n",debug[19]);
kosaka 12:459af534d1ee 260 }
kosaka 12:459af534d1ee 261 #endif
kosaka 12:459af534d1ee 262 }
kosaka 13:ba71733c11d7 263 void timerTS0(){ // タイマーtimerTS0()はTS0[s]ごとにコールされる timer called every TS0[s].
kosaka 13:ba71733c11d7 264 // debug_p26 = 1;
kosaka 13:ba71733c11d7 265 _countTS0++; // カウンターに1足す
kosaka 13:ba71733c11d7 266 _time += TS0; // 現在の時間にTS0[s]足す
kosaka 12:459af534d1ee 267
kosaka 13:ba71733c11d7 268 current_loop(); // 電流制御マイナーループ(指令電流i_refからPID制御で指令電圧を計算)
kosaka 13:ba71733c11d7 269 v2Hbridge(); // 指令電圧を見てPWM関数pwm_out()のパラメータを決める volt. to Hbridge
kosaka 13:ba71733c11d7 270
kosaka 13:ba71733c11d7 271 // モータ回転角の検出
kosaka 13:ba71733c11d7 272 p.th[1] = p.th[0]; // // 1サンプル前の回転角p.th[1]を更新
kosaka 13:ba71733c11d7 273 #ifdef SIMULATION
kosaka 13:ba71733c11d7 274 sim_motor(); // モータシミュレータ
kosaka 13:ba71733c11d7 275 #else
kosaka 13:ba71733c11d7 276 p.th[0] = (float)encoder.getPulses()/(float)N_ENC*2.0*PI; // エンコーダで回転角を検出 get angle [rad] from encoder
kosaka 13:ba71733c11d7 277 #endif
kosaka 13:ba71733c11d7 278 // debug_p26 = 0;
kosaka 12:459af534d1ee 279 }
kosaka 12:459af534d1ee 280
kosaka 13:ba71733c11d7 281 void timerTS1(void const *argument){ // タイマーtimerTS1()はTS1[s]ごとにコールされる
kosaka 13:ba71733c11d7 282 // debug_p25 = 1;
kosaka 13:ba71733c11d7 283 velocity_loop(); // 速度制御メインループ(指令速度w_refから指令電流i_refを求める)
kosaka 13:ba71733c11d7 284 // debug_p25 = 0;
kosaka 13:ba71733c11d7 285 }
kosaka 13:ba71733c11d7 286
kosaka 13:ba71733c11d7 287 void display2PC(){ // PCのモニタ上のtera termに諸量を表示 display to tera term on PC
kosaka 13:ba71733c11d7 288 pc.printf("%8.1f[s]\t%8.2f[V]\t%8.2f [Hz]\t%8.2f\t%8.2f\r\n",
kosaka 13:ba71733c11d7 289 _time, il.v_ref, vl.w_lpf/(2*PI), vl.w_ref/(2*PI), debug[0]);
kosaka 12:459af534d1ee 290 // 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 291 }
kosaka 13:ba71733c11d7 292 void timerTS2(){ // タイマーtimerTS2()はTS2[s]ごとにコールされる
kosaka 12:459af534d1ee 293 }
kosaka 13:ba71733c11d7 294 void timerTS3(){ // タイマーtimerTS3()はTS3[s]ごとにコールされる
kosaka 13:ba71733c11d7 295 data2mbedUSB(); // PC上のmbed USB ディスクにセーブするためのデータをTS3[s]ごとに代入 data2mbedUSB() is called every TS3[s].
kosaka 12:459af534d1ee 296 }
kosaka 13:ba71733c11d7 297 void timerTS4(){ // タイマーtimerTS4()はTS4[s]ごとにコールされる
kosaka 13:ba71733c11d7 298 display2PC(); // PCのモニタ上のtera termに文字を表示 display to tera term on PC. display2PC() is called every TS4[s].
kosaka 12:459af534d1ee 299 }