7
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

ドレミファインバータを自作した

Posted at

三相VVVFインバータを自作しました。京急1000形のドレミファインバータを再現しました。
マイコンはESP-32を使用しました。開発環境はArduinoです。
GitHubにソースコードとKiCadの回路図をアップしています。
GitHub

※100Vを扱います。危険なので自己責任でお願いします。

インバータユニット回路図

インバータ回路図.jpg

電源ユニット回路図

電源回路図.jpg

回路図の説明

電源ユニットのJCN1とインバータユニットのJCN1を接続し、電源ユニットのTB2とインバータユニットのTB1を接続します。
電源ユニットのTB1には交流100Vを入力します。
ESP32との配線は以下の表のように接続します。

ESP32 インバータユニット[JCN2]
33 1
25 2
26 3
27 4
14 5
12 6
GND 7
ESP32 ジョイスティック
3.3V V+
32 VRx
GND GND

プログラム

vvvf.ino
#define U_PIN_IN 33
#define U_PIN_SD 25
#define V_PIN_IN 26
#define V_PIN_SD 27
#define W_PIN_IN 14
#define W_PIN_SD 12

#define TABLE_LEN 256
#define CTRL_RATE 20000
#define FREQ_LEN 9

hw_timer_t * timer = NULL;

// 非同期モードの周波数配列
const double freq_table[FREQ_LEN] = {175, 196, 223, 233, 262, 294, 311, 350, 400};
// 変調波(正弦波・交流波形)
const double sin_table[TABLE_LEN] = {0, 6.258, 12.512, 18.759, 24.994, 31.215, 37.416, 43.595, 49.748, 55.871, 61.96, 68.012, 74.023, 79.989, 85.907, 91.773, 97.584, 103.337, 109.027, 114.651, 120.206, 125.689, 131.096, 136.424, 141.67, 146.831, 151.903, 156.884, 161.77, 166.559, 171.248, 175.833, 180.312, 184.683, 188.943, 193.088, 197.118, 201.028, 204.818, 208.484, 212.025, 215.438, 218.721, 221.872, 224.89, 227.772, 230.517, 233.123, 235.589, 237.913, 240.094, 242.13, 244.02, 245.763, 247.358, 248.804, 250.1, 251.246, 252.24, 253.082, 253.772, 254.309, 254.693, 254.923, 255, 254.923, 254.693, 254.309, 253.772, 253.082, 252.24, 251.246, 250.1, 248.804, 247.358, 245.763, 244.02, 242.13, 240.094, 237.913, 235.589, 233.123, 230.517, 227.772, 224.89, 221.872, 218.721, 215.438, 212.025, 208.484, 204.818, 201.028, 197.118, 193.088, 188.943, 184.683, 180.312, 175.833, 171.248, 166.559, 161.77, 156.884, 151.903, 146.831, 141.67, 136.424, 131.096, 125.689, 120.206, 114.651, 109.027, 103.337, 97.584, 91.773, 85.907, 79.989, 74.023, 68.012, 61.96, 55.871, 49.748, 43.595, 37.416, 31.215, 24.994, 18.759, 12.512, 6.258, 0, -6.258, -12.512, -18.759, -24.994, -31.215, -37.416, -43.595, -49.748, -55.871, -61.96, -68.012, -74.023, -79.989, -85.907, -91.773, -97.584, -103.337, -109.027, -114.651, -120.206, -125.689, -131.096, -136.424, -141.67, -146.831, -151.903, -156.884, -161.77, -166.559, -171.248, -175.833, -180.312, -184.683, -188.943, -193.088, -197.118, -201.028, -204.818, -208.484, -212.025, -215.438, -218.721, -221.872, -224.89, -227.772, -230.517, -233.123, -235.589, -237.913, -240.094, -242.13, -244.02, -245.763, -247.358, -248.804, -250.1, -251.246, -252.24, -253.082, -253.772, -254.309, -254.693, -254.923, -255, -254.923, -254.693, -254.309, -253.772, -253.082, -252.24, -251.246, -250.1, -248.804, -247.358, -245.763, -244.02, -242.13, -240.094, -237.913, -235.589, -233.123, -230.517, -227.772, -224.89, -221.872, -218.721, -215.438, -212.025, -208.484, -204.818, -201.028, -197.118, -193.088, -188.943, -184.683, -180.312, -175.833, -171.248, -166.559, -161.77, -156.884, -151.903, -146.831, -141.67, -136.424, -131.096, -125.689, -120.206, -114.651, -109.027, -103.337, -97.584, -91.773, -85.907, -79.989, -74.023, -68.012, -61.96, -55.871, -49.748, -43.595, -37.416, -31.215, -24.994, -18.759, -12.512, -6.258};
// 搬送波(三角波・制御波形)
const double tri_table[TABLE_LEN] = {0, -6.259, -12.517, -18.776, -25.035, -31.293, -37.552, -43.81, -50.069, -56.328, -62.586, -68.845, -75.104, -81.362, -87.621, -93.88, -100.138, -106.397, -112.656, -118.914, -125.173, -131.431, -137.69, -143.949, -150.207, -156.466, -162.725, -168.983, -175.242, -181.501, -187.759, -194.018, -200.277, -206.535, -212.794, -219.052, -225.311, -231.57, -237.828, -244.087, -250.346, -256.604, -262.863, -269.122, -275.38, -281.639, -287.898, -294.156, -300.415, -306.673, -312.932, -319.191, -325.449, -331.708, -337.967, -344.225, -350.484, -356.743, -363.001, -369.26, -375.518, -381.777, -388.036, -394.294, -400.553, -394.294, -388.036, -381.777, -375.518, -369.26, -363.001, -356.743, -350.484, -344.225, -337.967, -331.708, -325.449, -319.191, -312.932, -306.673, -300.415, -294.156, -287.898, -281.639, -275.38, -269.122, -262.863, -256.604, -250.346, -244.087, -237.828, -231.57, -225.311, -219.052, -212.794, -206.535, -200.277, -194.018, -187.759, -181.501, -175.242, -168.983, -162.725, -156.466, -150.207, -143.949, -137.69, -131.431, -125.173, -118.914, -112.656, -106.397, -100.138, -93.88, -87.621, -81.362, -75.104, -68.845, -62.586, -56.328, -50.069, -43.81, -37.552, -31.293, -25.035, -18.776, -12.517, -6.259, 0, 6.259, 12.517, 18.776, 25.035, 31.293, 37.552, 43.81, 50.069, 56.328, 62.586, 68.845, 75.104, 81.362, 87.621, 93.88, 100.138, 106.397, 112.656, 118.914, 125.173, 131.431, 137.69, 143.949, 150.207, 156.466, 162.725, 168.983, 175.242, 181.501, 187.759, 194.018, 200.277, 206.535, 212.794, 219.052, 225.311, 231.57, 237.828, 244.087, 250.346, 256.604, 262.863, 269.122, 275.38, 281.639, 287.898, 294.156, 300.415, 306.673, 312.932, 319.191, 325.449, 331.708, 337.967, 344.225, 350.484, 356.743, 363.001, 369.26, 375.518, 381.777, 388.036, 394.294, 400.553, 394.294, 388.036, 381.777, 375.518, 369.26, 363.001, 356.743, 350.484, 344.225, 337.967, 331.708, 325.449, 319.191, 312.932, 306.673, 300.415, 294.156, 287.898, 281.639, 275.38, 269.122, 262.863, 256.604, 250.346, 244.087, 237.828, 231.57, 225.311, 219.052, 212.794, 206.535, 200.277, 194.018, 187.759, 181.501, 175.242, 168.983, 162.725, 156.466, 150.207, 143.949, 137.69, 131.431, 125.173, 118.914, 112.656, 106.397, 100.138, 93.88, 87.621, 81.362, 75.104, 68.845, 62.586, 56.328, 50.069, 43.81, 37.552, 31.293, 25.035, 18.776, 12.517, 6.259};
double sin_index = 0; // 正弦波の位相(0-255)
double tri_index = 0; // 三角波の位相(0-255)
double freq = 0;      // 変調波の周波数
double ctrl_freq = 0; // 非同期モードの周波数
double ctrl_freq_index = 0; // 非同期モードの周波数のインデックス
double voltage = 0;  // 出力電圧
unsigned char sync_mode = 0;  // 0: 非同期モード, 1: 同期モード
unsigned char pulse_mode = 0;  // パルスモード

char U_IN_FLAG = LOW; // U相の出力
char V_IN_FLAG = LOW; // V相の出力
char W_IN_FLAG = LOW; // W相の出力
int accel = 0;

void IRAM_ATTR onTimer() {
  // 出力波形の周波数を計算
  freq = min(max(freq + (double)accel * 0.5 / (double)CTRL_RATE, 0.0), 120.0);
  // 電圧を計算
  voltage = min(0.06 + freq / 80.0, 1.0);
  // 正弦波の位相を計算
  sin_index += (double)TABLE_LEN * freq / (double)CTRL_RATE;
  
  // 非同期モード(加速)
  if(freq < 24.0 && accel > 0){
    sync_mode = 0;
    // 非同期モードの周波数を計算
    ctrl_freq_index = min(freq * 2.0, (double)FREQ_LEN - 1.0);
    ctrl_freq = freq_table[((unsigned int)ctrl_freq_index) % FREQ_LEN];
    // 非同期モードの位相を計算
    tri_index += (double)TABLE_LEN * ctrl_freq / (double)CTRL_RATE;
  }
  // 非同期モード(減速)
  else if(freq < 24.0){
    sync_mode = 0;
    // 非同期モードの周波数を400Hz固定にする
    ctrl_freq = freq_table[FREQ_LEN - 1];
    // 非同期モードの位相を計算
    tri_index += (double)TABLE_LEN * ctrl_freq / (double)CTRL_RATE;
  }
  // 同期モード
  else{
    sync_mode = 1;
    // パルスモードの設定
    if(freq > 80){
      pulse_mode = 1;
    }
    else if(freq > 58){
      pulse_mode = 3;
    }
    else if(freq > 56){
      pulse_mode = 5;
    }
    else if(freq > 44){
      pulse_mode = 7;
    }
    else if(freq > 36){
      pulse_mode = 9;
    }
    else if(freq > 30){
      pulse_mode = 11;
    }
    else if(freq > 26){
      pulse_mode = 13;
    }
    else{
      pulse_mode = 15;
    }
    // 三角波の位相を計算
    tri_index = sin_index * pulse_mode;
  }

  // 位相が1周したら1周分を引く
  while(sin_index >= TABLE_LEN){
    sin_index -= (double)TABLE_LEN;
  }
  while(tri_index >= TABLE_LEN){
    tri_index -= (double)TABLE_LEN;
  }

  // 正弦波が三角波より大きいときは出力ON(U相)
  if(sin_table[((unsigned int)sin_index) % TABLE_LEN] * voltage > tri_table[((unsigned int)tri_index) % TABLE_LEN]){
    U_IN_FLAG = HIGH;
  }
  else{
    U_IN_FLAG = LOW;
  }

  // 正弦波が三角波より大きいときは出力ON(V相)
  if(sin_table[((unsigned int)sin_index + TABLE_LEN / 3) % TABLE_LEN] * voltage > tri_table[((unsigned int)tri_index) % TABLE_LEN]){
    V_IN_FLAG = HIGH;
  }
  else{
    V_IN_FLAG = LOW;
  }

  // 正弦波が三角波より大きいときは出力ON(W相)
  if(sin_table[((unsigned int)sin_index + TABLE_LEN * 2 / 3) % TABLE_LEN] * voltage > tri_table[((unsigned int)tri_index) % TABLE_LEN]){
    W_IN_FLAG = HIGH;
  }
  else{
    W_IN_FLAG = LOW;
  }

  // 周波数が1Hzより大きくまたは加速しているときは出力ON
  if(accel > 0 || freq > 1.0){
    digitalWrite(U_PIN_SD, HIGH);
    digitalWrite(V_PIN_SD, HIGH);
    digitalWrite(W_PIN_SD, HIGH);
    digitalWrite(U_PIN_IN, U_IN_FLAG);
    digitalWrite(V_PIN_IN, V_IN_FLAG);
    digitalWrite(W_PIN_IN, W_IN_FLAG);
  }
  // 周波数1Hz以下で停止または減速しているときは停止
  else{
    // リセット処理
    sin_index = 0;
    tri_index = 0;
    freq = 0;
    ctrl_freq = 0;
    ctrl_freq_index = 0;
    voltage = 0;
    sync_mode = 0;
    digitalWrite(U_PIN_SD, LOW);
    digitalWrite(V_PIN_SD, LOW);
    digitalWrite(W_PIN_SD, LOW);
    digitalWrite(U_PIN_IN, LOW);
    digitalWrite(V_PIN_IN, LOW);
    digitalWrite(W_PIN_IN, LOW);
  }
}

void setup() {
  // ウォッチドッグタイマ無効
  disableCore0WDT();
  disableCore1WDT();
  // 出力モードに設定
  pinMode(U_PIN_IN, OUTPUT);
  pinMode(V_PIN_IN, OUTPUT);
  pinMode(W_PIN_IN, OUTPUT);
  pinMode(U_PIN_SD, OUTPUT);
  pinMode(V_PIN_SD, OUTPUT);
  pinMode(W_PIN_SD, OUTPUT);
  // タイマー割り込みの設定
  timer = timerBegin(0, 80, true);
  timerAttachInterrupt(timer, &onTimer, true);
  timerAlarmWrite(timer, 1000000 / CTRL_RATE, true);
  timerAlarmEnable(timer);
}

void loop() {
  // 加速制御
  int acl_val = analogRead(32);
  if(acl_val > 4096.0 * 0.85){
    accel = 5;
  }
  else if(acl_val > 4096.0 * 0.7){
    accel = 3;
  }
  else if(acl_val > 4096.0 * 0.6){
    accel = 1.5;
  }
  else if(acl_val > 4096.0 * 0.3){
    accel = 0;
  }
  else if(acl_val > 4096.0 * 0.25){
    accel = -1;
  }
  else if(acl_val > 4096.0 * 0.2){
    accel = -2;
  }
  else if(acl_val > 4096.0 * 0.15){
    accel = -3;
  }
  else if(acl_val > 4096.0 * 0.1){
    accel = -4;
  }
  else{
    accel = -5;
  }
}

デモ

7
3
18

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?