色々と試行錯誤を繰り返してPWM駆動と起動シーケンスをプログラムに組み込むことができました。
といってもセンサやシャント抵抗などで位置推定を行っていないためオープンループ状態であり、2~3回に1回は起動に失敗してしまいます。
もう少しうまく作りこみしたいものです。
とは言え今までのON/OFFのみの疑似正弦波では0回転数から回し始めることはできなかったためかなりの進歩だと個人的に思っています。
今後の課題はセンサを使ってアナログ入力ピンから切り替えタイミングの割り込み制御を入れるような形にもっていくことですね。
そうすれば負荷をかけて回すことも可能になるはずです。
まあそのあたりについてはまた次回、進捗があり次第更新していこうと思います。
■回路図
回路図は画像の下側にあるインバーターの部分のみを切り出した感じのものになります。
■とりあえず回してみたときの動画↓
とりあえず回って嬉しい
— ねぎま2nd (@MTxG0LiTWawHxXU) 2024年10月13日
あと部屋が汚い pic.twitter.com/wB2GfcI9v3
■以下、ソースコード
const int IN_U = 3;
const int SD_U = 2;
const int IN_V = 5;
const int SD_V = 4;
const int IN_W = 6;
const int SD_W = 8;
volatile int val = LOW; //inputpinの値を格納する代数
float uModulate;
float vModulate;
float wModulate;
int angu;
int angv;
int angw;
int delayTime = 1;
double pwm[180];
void setup() {
// put your setup code here, to run once:
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);//UVWのPWM 0〜255
analogWrite(IN_V, 0);
analogWrite(IN_W, 0);
digitalWrite(SD_U, HIGH);
digitalWrite(SD_V, HIGH);
digitalWrite(SD_W, HIGH);
delayMicroseconds(1);
angu = 0;
angv = 60;
angw = 120;
Serial.begin(9600);
for (int i = 0 ; i < 180 ; i++) {
pwm[i] = 126 * (sin(i * PI / 90) + 1);
// Serial.print(pwm[i]); //計算値の確認
// Serial.println(","); //計算値の確認
}
//起動シーケンス
for (int i = 6000 ; i >= 1000 ; i--) {
analogWrite(IN_U, pwm[angu]);
analogWrite(IN_V, pwm[angv]);
analogWrite(IN_W, pwm[angw]);
angu = angu + 1 + (1023 - i/10)/100; //本来は+1のみで1度分の計算値を次に実行する。iの値を0~10まで変化させてpwm[ang_]の計算を減らすことで回転数を上げる
angv = angv + 1 + (1023 - i/10)/100; //本来は+1のみで1度分の計算値を次に実行する。iの値を0~10まで変化させてpwm[ang_]の計算を減らすことで回転数を上げる
angw = angw + 1 + (1023 - i/10)/100; //本来は+1のみで1度分の計算値を次に実行する。iの値を0~10まで変化させてpwm[ang_]の計算を減らすことで回転数を上げる
uModulate = angu;
vModulate = angv;
wModulate = angw;
if (angu >= 180) {angu = 0;} //オーバーフローしないよう0に戻す
if (angv >= 180) {angv = 0;} //オーバーフローしないよう0に戻す
if (angw >= 180) {angw = 0;} //オーバーフローしないよう0に戻す
val = analogRead(0); //A0ピンからアナログ値を読み込む
delayMicroseconds(i/10);
}
}
void loop() {
val = analogRead(0); //A0ピンからアナログ値を読み込む
uModulate = angu;
vModulate = angv;
wModulate = angw;
analogWrite(IN_U, pwm[angu]);
analogWrite(IN_V, pwm[angv]);
analogWrite(IN_W, pwm[angw]);
angu = angu + 1 + (2023 - val)/100; //本来は+1のみで1度分の計算値を次に実行する。valの値を0~10まで変化させてpwm[ang_]の計算を減らすことで回転数を上げる
angv = angv + 1 + (2023 - val)/100; //本来は+1のみで1度分の計算値を次に実行する。valの値を0~10まで変化させてpwm[ang_]の計算を減らすことで回転数を上げる
angw = angw + 1 + (2023 - val)/100; //本来は+1のみで1度分の計算値を次に実行する。valの値を0~10まで変化させてpwm[ang_]の計算を減らすことで回転数を上げる
uModulate = angu;
vModulate = angv;
wModulate = angw;
if (angu >= 180) {angu = 0;} //オーバーフローしないよう0に戻す
if (angv >= 180) {angv = 0;} //オーバーフローしないよう0に戻す
if (angw >= 180) {angw = 0;} //オーバーフローしないよう0に戻す
val = analogRead(0); //A0ピンからアナログ値を読み込む
delayMicroseconds(0);
}