blog:2024-05-27_simple_foc_8
2024-05-27 SimpleFOC (8) 理論+實務深度分析SVPWM
Local Backup
說明
一、有感FOC控制原理
有感foc控制原理
1.測量馬達三相定子電流,可得到Ia 和Ib。將三相電流經Clark變換至兩相電流Iα和Iβ ,
2、依照控制環上一次迭代計算出的馬達角度, 透過Park變換得到旋轉座標系下相互正交的電流Id和Iq,
3、Id、 Iq與設定值比較得到電流環PI控制器的輸入。調節PI控制器的參數,得到Vd 和Vq ,即要施加到馬達上的電壓向量,
4、透過位置感測器得到新的馬達位置,從而得到新的角度和轉速。新的馬達角度可告知FOC演算法下一個電壓向量在何處,
5.透過使用新的馬達角度,Vd 和Vq經過Park逆變換產生下一個正交電壓值Vα、Vβ,
6、採用SVPWM演算法判定其合成的電壓向量位於哪個扇區,計算出三相各橋臂開關管的導通時間,最後經過三相逆變器驅動模組輸出馬達所需的三相電壓。
二、SVPWM原理
三、SimpleFOC(不含電流採樣)的控制原理:
-
首先去掉了電流採樣,所以簡單了很多,有位置感測器,所以不用觀測器估算位置。對空間向量作用時間可以直接利用下面的公式(這些公式來自《SVPWM分析、各個扇區詳細計算以及Matlab模擬》演算法推導的中間狀態,《SVPWM演算法原理及詳解》只寫了第一個扇區) :
-
對照向量圖,可以總結如下:
-
Udc表示電源電壓(在程式碼中是voltage_limit),Uref表示設定的力矩大小(在程式碼中是target_voltage),Ts表示PWM週期(程式碼中沒有把Ts體現出來,程式碼中的T1、T2是週期的百分比)。
四、SimpleFOC核心程式碼
五、程式碼實驗
5.1、實驗目的
5.2、硬體準備
序號 | 名稱 | 數量 |
1 | Arduino UNO | 1 |
2 | simpleFOCShield V2.0.3 | 1 |
3 | 雲台馬達 | 1 |
4 | 12V電源 | 1 |
5 | 方口USB線 | 1 |
5.3、修改程式碼第一階段
5.3.1 打開例程
5.3.2 修改代碼
simpleFOC工程以函式庫的形式安裝到Arduino中,不能修改底層程式碼,所以只能把程式碼複製出來,以子程式的形式放到目前程式中。之所以選擇standalone例程,是因為這個例程比較簡單,而且本身就是示範向量控制的。
①、增加SVPWM演算法的子程序
②、loop循環中呼叫子程序
例程為唯讀文件,可以驗證上傳,如需保存要「另存為」。
SVPWM子程序(為了讓程式碼看起來更簡潔,所以程式中沒有約束條件,參數設定一定要依要求範圍輸入):
void setPhaseVoltage(float Uq, float Ud, float angle_el) {
int sector = (angle_el / _PI_3) + 1; // find the sector we are in currently
float T1 = _SQRT3*_sin(sector*_PI_3 - angle_el) * Uq/driver.voltage_limit;
float T2 = _SQRT3*_sin(angle_el - (sector-1)*_PI_3) * Uq/driver.voltage_limit;
float T0 = 1 - T1 - T2;
float Ta,Tb,Tc;
switch(sector){
case 1:
Ta = T1 + T2 + T0/2;
Tb = T2 + T0/2;
Tc = T0/2;
break;
case 2:
Ta = T1 + T0/2;
Tb = T1 + T2 + T0/2;
Tc = T0/2;
break;
case 3:
Ta = T0/2;
Tb = T1 + T2 + T0/2;
Tc = T2 + T0/2;
break;
case 4:
Ta = T0/2;
Tb = T1+ T0/2;
Tc = T1 + T2 + T0/2;
break;
case 5:
Ta = T2 + T0/2;
Tb = T0/2;
Tc = T1 + T2 + T0/2;
break;
case 6:
Ta = T1 + T2 + T0/2;
Tb = T0/2;
Tc = T1 + T0/2;
break;
default: // possible error state
Ta = 0;
Tb = 0;
Tc = 0;
}
// calculate the phase voltages and center
float Ua = Ta*driver.voltage_limit;
float Ub = Tb*driver.voltage_limit;
float Uc = Tc*driver.voltage_limit;
driver.setPwm(Ua,Ub,Uc);
}
5.3.3 驗證上傳
5.3.4 馬達觀測
5.3.5 修改力矩
5.3.6 修改轉速
5.4、修改程式碼第二階段
5.4.1 修改代碼
在第一階段程序的基礎上,
-
串口通訊子程式:
void serialReceiveUserCommand() {
// a string to hold incoming data
static String received_chars;
while (Serial.available()) {
// get the new byte:
char inChar = (char)Serial.read();
// add it to the string buffer:
received_chars += inChar;
// end of user input
if (inChar == '\n') {
// change the motor target
theta = received_chars.toFloat();
Serial.print("Target Angle:");
Serial.println(theta);
// reset the command buffer
received_chars = "";
}
}
}
5.4.2 驗證上傳
5.4.3 馬達觀測
5.4.4 串列埠操作
5.4.5 觀察三相波形
串口輸入角度,示波器查看三相輸出波形,並與理論做比較。 (示波器只有兩個通道,所以三相波形只能透過拼接得到)
-
①、30度
②、90度
③、150度
④、210度
⑤、270度
⑥、330度
順便說下,Arduino UNO 的PWM頻率是31.25KHz。 16MHz晶振,時脈不分頻,PWM模式為相位校正模式(Phase Correct PWM Mode,在STM32稱為中央對齊模式),16000/256/2=31.25KHz。
以下是PWM的設定碼(程式碼路徑:…\Arduino-FOC-minimal\library_source\drivers\hardware_specific\atmega328_mcu)
-
本文涉及理論的部分寫的很籠統,存在用詞不準確,語句不通順的問題,請大家不要太糾結,做為合格的工程師就是要把科學研究人員的理論轉變為可以落地的程式碼,理論不是我的強項也不是我的目標。
請繼續閱讀相關文章:
Permalink blog/2024-05-27_simple_foc_8.txt · Last modified: 2024/05/27 16:11 by
jethro