SVPWM (Space vector pwm) for 4 switch inverter to drive 3 phase induction motor

Hello, I need some help with my problem. I am working on a 4-switch inverter to drive a 3-phase induction motor. Based on the B4 inverter topology, using SVPWM or Space Vector PWM can produce 4 conditions, there are:

  • q1: 0, q2: 0
  • q1: 0, q2: 1
  • q1: 1, q2: 0
  • q1: 1, q2: 1

However, why does the code I wrote below only produce 3 conditions (the one not produced is q1: 1 and q2: 0)? I still can't find the issue why it can't output according to the given topology. If you have any suggestions, I would be very grateful. Thank you.

#include <PWM.h> // Pustaka PWM untuk mengontrol frekuensi sinyal PWM

const int SINE_PIN1 = 9; // Pin output PWM untuk fasa 1
const int SINE_PIN2 = 10; // Pin output PWM untuk fasa 2
const int SINE_PIN3 = 11; // Pin output PWM untuk fasa 3
const int SINE_RESOLUTION = 256; // Resolusi tabel sinus
const float Phi = 3.14159265358979323846;
const int pwmPin = 12; // PWM pin triangle
const int amplitude = 127; // Amplitude of the triangle wave
int q1; // Pin output PWM Q1
int q2; // Pin output PWM Q2
const int PWM_Q1 = 5; //channel 4
const int PWM_Q2 = 6;

const int frequency = 5000; // Frekuensi dalam Hz
const float minValue = -2.0;  // Nilai minimum sinyal (dalam volt)
const float maxValue = 2.0;   // Nilai maksimum sinyal (dalam volt)
const int numSteps = 200; // Jumlah langkah dalam satu periode sinyal
const float stepDelay = 100 / numSteps; // Waktu per langkah dalam mikrodetik

int period = 0.0002; // Calculate period in microseconds
int delayTime = period / (2 * amplitude); // Calculate delay time for each step

// Matriks A
#define A11 1.0
#define A12 -0.5
#define A13 -0.5
#define A21 0.0
#define A22 (sqrt(3.0) / 2.0)
#define A23 (-sqrt(3.0) / 2.0)

// Vektor V (asumsi x1, x2, x3 didefinisikan sebagai global variabel)
float V1, V2, V3;

// Definisi Bilangan Real dan Imajiner
float z_real, z_imajiner;

// Variabel untuk menyimpan hasil perhitungan
float y1, y2, z_mag, z_ang, alpha;
int Sec;
float tb;
float tc;
float triangleWaveValue;
float tb_combined;
float tc_combined;
float segitigaf;

int Sector;
float angle, Ts, M;
float t00, t01, t10, t11;

byte sineTable[SINE_RESOLUTION];

void setup() {
  pinMode(PWM_Q1, OUTPUT);
  pinMode(PWM_Q2, OUTPUT);

  // Setting input dan output
  Serial.begin(9600);
  pinMode(SINE_PIN1, OUTPUT);
  pinMode(SINE_PIN2, OUTPUT);
  pinMode(SINE_PIN3, OUTPUT);
  pinMode(pwmPin, OUTPUT);

  // Generate the sine table
  generateSineTable();

  // Inisialisasi timer tanpa mengganggu timer 0
  InitTimersSafe();
  bool success = SetPinFrequencySafe(SINE_PIN1, frequency); // Set frequency to 16000 Hz
  SetPinFrequencySafe(SINE_PIN2, frequency);
  SetPinFrequencySafe(SINE_PIN3, frequency);
  SetPinFrequencySafe(pwmPin, frequency);

  if (!success) {
    Serial.println("Unable to set PWM frequency, check the pin configuration.");
    while (true);
  }
}

void loop() {
  static unsigned long lastUpdate = 0;
  unsigned long currentTime = millis();
  
  // Output gelombang sinus 3 fasa menggunakan PWM
  for (int i = 0; i < SINE_RESOLUTION; i++) {
    // Tulis nilai sinus ke pin PWM fasa 1
    V1 = sineTable[i];
    pwmWrite(SINE_PIN1, V1);

    // Tulis nilai sinus ke pin PWM fasa 2 dengan fase 120 derajat
    V2 = sineTable[(i + SINE_RESOLUTION / 3) % SINE_RESOLUTION];
    pwmWrite(SINE_PIN2, V2);

    // Tulis nilai sinus ke pin PWM fasa 3 dengan fase 240 derajat
    V3 = sineTable[(i + 2 * SINE_RESOLUTION / 3) % SINE_RESOLUTION];
    pwmWrite(SINE_PIN3, V3);

    // Calculate alpha-beta values inside the loop
    alpha_beta();

    // Set nilai z_real dan z_imajiner
    z_real = y1; // contoh
    z_imajiner = y2; // contoh

    sector();

    fswitch();

    // Update sinyal segitiga setiap periode tertentu sesuai dengan frekuensi
    if (currentTime - lastUpdate >= (1000 / (frequency * numSteps * 2))) {
      segitigaf = generateTriangleWave();
    tb_combined = segitigaf - tb;
    tc_combined = segitigaf - tc;
      lastUpdate = currentTime;
    }

  }
  
// Fungsi untuk mengatur nilai q1 dan q2 berdasarkan tb_combined dan tc_combined

if (tb_combined >= 0) {
  q1 = 1;
} else {
  q1 = 0;
}
if (tc_combined >= 0) {
  q2 = 1;
} else {
  q2 = 0;
}

  if (q1 == 1) {
    digitalWrite(PWM_Q1, HIGH);
  } else {
    digitalWrite(PWM_Q1, LOW);
  }

  if (q2 == 1) {
    digitalWrite(PWM_Q2, HIGH);
  } else {
    digitalWrite(PWM_Q2, LOW);
  }

  Serial.print("tb_combined: ");
  Serial.print(tb_combined);
  Serial.print(" tc_combined: ");
  Serial.println(tc_combined);
  Serial.print("q1: ");
  Serial.print(q1);
  Serial.print(" q2: ");
  Serial.println(q2);
  Serial.print(" segitigaf: ");
  Serial.print(segitigaf);
}

// Fungsi untuk menghasilkan tabel sinus
void generateSineTable() {
  for (int i = 0; i < SINE_RESOLUTION; i++) {
    sineTable[i] = 127 + 127 * sin(2 * Phi * i / SINE_RESOLUTION);
  }
}

void alpha_beta() {
  // Perhitungan y1 dan y2
  y1 = sqrt(2.0 / 3.0) * (A11 * V1 + A12 * V2 + A13 * V3);
  y2 = sqrt(2.0 / 3.0) * (A21 * V1 + A22 * V2 + A23 * V3);
}

void sector() {
  // Konversi Rectangular ke Polar
  z_mag = sqrt(z_real * z_real + z_imajiner * z_imajiner);
  z_ang = atan2(z_imajiner, z_real);
  alpha = z_ang * 180.0 / 3.14;

  // Penentuan sektor
  if (alpha > 0 && alpha <= 90) {
    Sec = 1;
  } else if (alpha > 90 && alpha <= 180) {
    Sec = 2;
  } else if (alpha >= -180 && alpha <= -90) {
    Sec = 3;
  } else if (alpha > -90 && alpha <= 0) {
    Sec = 4;
  }
}

void fswitch() {
  // Menentukan case berdasarkan Sector
  M = 0.8;
  Ts = 0.00025;
  angle = z_ang;
  Sec;
  if (Sec == 1) {
    t10 = M * Ts * sin(angle);
    t00 = 0.5 * Ts - M * Ts * sin(angle - 3.14 / 3.0);
    t11 = 0.5 * Ts - M * Ts * sin(angle + 3.14 / 3.0);
    t01 = 0;
  } else if (Sec == 2) {
    t11 = -sqrt(3.0) * M * Ts * cos(angle);
    t10 = 0.5 * Ts + M * Ts * sin(angle + 3.14 / 3.0);
    t01 = 0.5 * Ts - M * Ts * sin(angle - 3.14 / 3.0);
    t00 = 0;
  } else if (Sec == 3) {
    t01 = -M * Ts * sin(angle);
    t00 = 0.5 * Ts + M * Ts * sin(angle + 3.14 / 3.0);
    t11 = 0.5 * Ts + M * Ts * sin(angle - 3.14 / 3.0);
    t10 = 0;
  } else {
    t00 = sqrt(3.0) * M * Ts * cos(angle);
    t10 = 0.5 * Ts + M * Ts * sin(angle - 3.14 / 3.0);
    t01 = 0.5 * Ts - M * Ts * sin(angle + 3.14 / 3.0);
    t11 = 0;
  }

  // Menghitung Tb dan Tc
  tb = (1.0 / Ts) * (-t00 + t10 + t11 - t01);
  tc = (1.0 / Ts) * (-t00 - t10 + t11 + t01);
}

// Fungsi untuk menghasilkan sinyal segitiga
float generateTriangleWave() {
  static float value = minValue;
  static bool ascending = true;
  float stepSize = (maxValue - minValue) / numSteps;

  if (ascending) {
    value += stepSize;
    if (value >= maxValue) {
      value = maxValue;
      ascending = false;
    }
  } else {
    value -= stepSize;
    if (value <= minValue) {
      value = minValue;
      ascending = true;
    }
  }

  return value;
}

There is something wrong here

What does this do?

—-

Please review the following expression. All-integer operands may produce wrong results in operations like this.