VVVFインバーターの設計製作5

当初のプログラムからPWMの周波数を上げる方法を取りました。

通常のPWMの場合はかなり低い周波数で駆動しているため回転数を上げるとすぐに上限に達してしまって正弦波が崩れてしまっていました。

今回は源信(動作クロック16MHz)からの分周を変えることでPWM周波数を上げて波形品質を落とすことなく正弦波出力できるようになったのでプログラムをアップしておきます。

このときのキャリア周波数が大体31.4kHz程度らしいので可聴域を超えてくるため駆動ノイズがかなり減りましたね。

電流波形もきれいになってきて初めて電流フィードバックで位置補正ができるのではないかと思います。(ピーク値に差があるのが少し解せない。多分ch2の波形立ち上がりが鈍っているのでその影響か。)

そのへんが今後の課題ですね。

 

下記を参考にプログラムを修正しています。

Arduino PWM 周波数 高速化 : LabVIEW info. Sharing 新館 (exblog.jp)

 

全体波形

拡大波形とリップル

FET下流にシャントを入れて電流を測定

シャント電圧値をフィルタで除去できているかの確認







 

 

以下、プログラム↓

// 正弦波生成

const int IN_U = 9;
const int SD_U = 2;
const int IN_V = 10;
const int SD_V = 4;
const int IN_W = 11;
const int SD_W = 8;
volatile int val = LOW;      //inputpinの値を格納する代数

float uModulate;
float vModulate;
float wModulate;
int angu;
int angv;
int angw;
double pwm[180];
  
void setup() {
  TCCR1B &= B11111000;
  TCCR1B |= B00000001;
  TCCR2B &= B11111000;
  TCCR2B |= B00000001;
  Serial.begin(9600);
  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);
    }

}

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 + (1023 - val/10)/100;  //本来は+1のみで1度分の計算値を次に実行する。valの値を0~10まで変化させてpwm[angx]の計算を減らすことで回転数を上げる
  angv = angv + (1023 - val/10)/100;  //本来は+1のみで1度分の計算値を次に実行する。valの値を0~10まで変化させてpwm[angx]の計算を減らすことで回転数を上げる
  angw = angw + (1023 - val/10)/100;  //本来は+1のみで1度分の計算値を次に実行する。valの値を0~10まで変化させてpwm[angx]の計算を減らすことで回転数を上げる
  uModulate = angu;
  vModulate = angv;
  wModulate = angw;
  if (angu >= 180) {angu = 0;}  //オーバーフローしないよう0に戻す
  if (angv >= 180) {angv = 0;}  //オーバーフローしないよう0に戻す
  if (angw >= 180) {angw = 0;}  //オーバーフローしないよう0に戻す
    delayMicroseconds(val);
}