暇なのでBLDCモーターを回してみました。
基本的にはVVVFインバータのときと変わりません。
・6ステップ制御
ブラシレスモーターはコイルによってできる磁束の方向を回し、その磁力と永久磁石の磁力の作用で回すという構造になっています。それなので、コイルにかかる電流を変化させることでコイルにより発生する磁力を回転させる必要があります。
ブラシレスモーターの三相それぞれをU,V,Wとすると、
・U →V
・W→V
・W→U
・V →U
・V →W
・U →W
の方向に電気を流す6つのステップを繰り返すことで回すことができます。下の動画はそれを図式的に表してくれているので、ブラシレスモーターの回転原理がよくわかると思います。
この動画で説明している制御方法がまさに6ステップ制御です。これをするにあたって必要な回路は下の通りです。
基本はVVVFの時と同じですが、ハーフブリッジドライバのSDも操作するため、3番ピンもArduinoにつないでおきます。SDを使うことで、ハーフブリッジドライバからの出力を切ることができ、動作に必要ないFETに通電させないことができます。こうすることで各相の出力を以下のようにすることができます。
これを実現するためのプログラムは以下のようになります。
const int IN_U = 3;
基本的にはVVVFインバータのときと変わりません。
・6ステップ制御
ブラシレスモーターはコイルによってできる磁束の方向を回し、その磁力と永久磁石の磁力の作用で回すという構造になっています。それなので、コイルにかかる電流を変化させることでコイルにより発生する磁力を回転させる必要があります。
ブラシレスモーターの三相それぞれをU,V,Wとすると、
・U →V
・W→V
・W→U
・V →U
・V →W
・U →W
の方向に電気を流す6つのステップを繰り返すことで回すことができます。下の動画はそれを図式的に表してくれているので、ブラシレスモーターの回転原理がよくわかると思います。
この動画で説明している制御方法がまさに6ステップ制御です。これをするにあたって必要な回路は下の通りです。
基本はVVVFの時と同じですが、ハーフブリッジドライバのSDも操作するため、3番ピンもArduinoにつないでおきます。SDを使うことで、ハーフブリッジドライバからの出力を切ることができ、動作に必要ないFETに通電させないことができます。こうすることで各相の出力を以下のようにすることができます。
これを実現するためのプログラムは以下のようになります。
const int IN_U = 3;
const int SD_U = 2;
const int IN_V = 5;
const int SD_V = 4;
const int IN_W = 9;
const int SD_W = 8;
int delayTime;
void setup() {
pinMode(IN_U, OUTPUT);
pinMode(IN_V, OUTPUT);
pinMode(IN_W, OUTPUT);
pinMode(SD_U, OUTPUT);
pinMode(SD_V, OUTPUT);
pinMode(SD_W, OUTPUT);
analogWrite(IN_U, 0);
analogWrite(IN_V, 0);
analogWrite(IN_W, 0);
digitalWrite(SD_U, HIGH);
digitalWrite(SD_V, HIGH);
digitalWrite(SD_W, HIGH);
}
void loop() {
if (millis() < 8000) {
delayTime = 5 - millis() / 2000;
}
analogWrite(IN_U, 250);
analogWrite(IN_V, 0);
analogWrite(IN_W, 0);
digitalWrite(SD_U, HIGH);
digitalWrite(SD_V, LOW);
digitalWrite(SD_W, HIGH);
delay(delayTime);
analogWrite(IN_U, 250);
analogWrite(IN_V, 0);
analogWrite(IN_W, 0);
digitalWrite(SD_U, HIGH);
digitalWrite(SD_V, HIGH);
digitalWrite(SD_W, LOW);
delay(delayTime);
analogWrite(IN_U, 0);
analogWrite(IN_V, 0);
analogWrite(IN_W, 250);
digitalWrite(SD_U, LOW);
digitalWrite(SD_V, HIGH);
digitalWrite(SD_W, HIGH);
delay(delayTime);
analogWrite(IN_U, 0);
analogWrite(IN_V, 0);
analogWrite(IN_W, 250);
digitalWrite(SD_U, HIGH);
digitalWrite(SD_V, LOW);
digitalWrite(SD_W, HIGH);
delay(delayTime);
analogWrite(IN_U, 0);
analogWrite(IN_V, 250);
analogWrite(IN_W, 0);
digitalWrite(SD_U, HIGH);
digitalWrite(SD_V, HIGH);
digitalWrite(SD_W, LOW);
delay(delayTime);
analogWrite(IN_U, 0);
analogWrite(IN_V, 250);
analogWrite(IN_W, 0);
digitalWrite(SD_U, LOW);
digitalWrite(SD_V, HIGH);
digitalWrite(SD_W, HIGH);
delay(delayTime);
}
このプログラムは簡易的な加速機能がついており、8秒間かけて3ステップの加速をします。また、delayTimeはモーターによって回転数が違うので調節してください。
これを使ってブラシレスモーターを回すとこうなりました。
・疑似正弦波制御
6ステップ制御を発展させたものとして正弦波制御というものがあります。これは、6ステップ制御とは違い、コイルに(疑似)正弦波を入力することでモーターを滑らかに回すというものです。
これによってコイルによって発生する磁束の方向が滑らかに変化するのでモーターを滑らかに回すことができます。ただし、ArduinoのanalogWriteはPWMなので正確に正弦波を出せるわけではない上、出力がLOWの時は回路上その部分の出力はGNDに短絡されてしまいます。
そのような不具合はありますが、一応回路図とプログラムを挙げておきます。
6ステップ制御との違いは正弦波制御ではSDを使わないためVCCに短絡させてしまっている点だけです。プログラムは以下のようになります。
const int IN_U = 11;
このプログラムは簡易的な加速機能がついており、8秒間かけて3ステップの加速をします。また、delayTimeはモーターによって回転数が違うので調節してください。
これを使ってブラシレスモーターを回すとこうなりました。
ちさと@chisao_62暇だからBLDCモーターを6ステップ制御した https://t.co/w7OGv2nBFT
2020/04/23 23:17:11
・疑似正弦波制御
6ステップ制御を発展させたものとして正弦波制御というものがあります。これは、6ステップ制御とは違い、コイルに(疑似)正弦波を入力することでモーターを滑らかに回すというものです。
これによってコイルによって発生する磁束の方向が滑らかに変化するのでモーターを滑らかに回すことができます。ただし、ArduinoのanalogWriteはPWMなので正確に正弦波を出せるわけではない上、出力がLOWの時は回路上その部分の出力はGNDに短絡されてしまいます。
そのような不具合はありますが、一応回路図とプログラムを挙げておきます。
6ステップ制御との違いは正弦波制御ではSDを使わないためVCCに短絡させてしまっている点だけです。プログラムは以下のようになります。
const int IN_U = 11;
const int IN_V = 10;
const int IN_W = 9;
int delayTime = 1;
double pwm[360];
void setup() {
// put your setup code here, to run once:
pinMode(IN_U, OUTPUT);
pinMode(IN_V, OUTPUT);
pinMode(IN_W, OUTPUT);
analogWrite(IN_U, 0);//UVWのPWM 0〜255
analogWrite(IN_V, 0);
analogWrite(IN_W, 0);
delayMicroseconds(1);
for (int i = 0 ; i < 360 ; i++) {
pwm[i] = 125 * sin(i * PI / 180) + 125;
}
}
void loop() {
//1 U->W
for (int i = 0; i < 60; i++) {
analogWrite(IN_U, pwm[i]);
analogWrite(IN_V, pwm[i - 240]);
analogWrite(IN_W, pwm[i - 120]);
delayMicroseconds(delayTime);
}
//2 U->V
for (int i = 60; i < 120; i++) {
analogWrite(IN_U, pwm[i]);
analogWrite(IN_V, pwm[i - 240]);
analogWrite(IN_W, pwm[i - 120]);
delayMicroseconds(delayTime);
}
//3 W->V
for (int i = 120; i < 180; i++) {
analogWrite(IN_U, pwm[i]);
analogWrite(IN_V, pwm[i - 240]);
analogWrite(IN_W, pwm[i - 120]);
delayMicroseconds(delayTime);
}
//4 W->U
for (int i = 180; i < 240; i++) {
analogWrite(IN_U, pwm[i]);
analogWrite(IN_V, pwm[i - 240]);
analogWrite(IN_W, pwm[i - 120]);
delayMicroseconds(delayTime);
}
//5 V->U
for (int i = 240; i < 300; i++) {
analogWrite(IN_U, pwm[i]);
analogWrite(IN_V, pwm[i - 240]);
analogWrite(IN_W, pwm[i - 120]);
delayMicroseconds(delayTime);
}
//6 V->W
for (int i = 300; i < 360; i++) {
analogWrite(IN_U, pwm[i]);
analogWrite(IN_V, pwm[i - 240]);
analogWrite(IN_W, pwm[i - 120]);
delayMicroseconds(delayTime);
}
}
この肝はsetup()の段階で360°分の出力値を計算しておき、プログラム実行中の動作を軽くしている点です。ただしこれをやると変数の容量を食うので、今回はArduino UNOのグローバル変数を70%も使います。
実際に動かすと下のようになります。
そんなこんなで一応回すことはできたので、これから発展させていきたいと思います。あと今は、フォトカプラが欲しいです。それではまた今度。
この肝はsetup()の段階で360°分の出力値を計算しておき、プログラム実行中の動作を軽くしている点です。ただしこれをやると変数の容量を食うので、今回はArduino UNOのグローバル変数を70%も使います。
実際に動かすと下のようになります。
ちさと@chisao_62多分こっちの方がそれっぽいかもしれない https://t.co/EjApSC9fe9
2020/04/24 03:01:16
そんなこんなで一応回すことはできたので、これから発展させていきたいと思います。あと今は、フォトカプラが欲しいです。それではまた今度。