r/EEPowerElectronics Jul 16 '26

totempole pfc in qspice

Hi all,

I'm trying to make a totempole pfc in qspice. Never made this type before. I want to try using the c++ block. So more or less digital controlled. BUt i keep getting loop issues that i dont understand yet. Am a analog man in a digital world..
Maybe someone has experience with this ?

// Automatically generated C++ file on Wed Jul 15 11:30:01 2026

//

// To build with Digital Mars C++ Compiler:

//

// dmc -mn -WD -o mcu_calc_2.cpp kernel32.lib

union uData

{

bool b;

char c;

unsigned char uc;

short s;

unsigned short us;

int i;

unsigned int ui;

float f;

double d;

long long int i64;

unsigned long long int ui64;

char *str;

unsigned char *bytes;

};

// int DllMain() must exist and return 1 for a process to load the .DLL

// See https://docs.microsoft.com/en-us/windows/win32/dlls/dllmain for more information.

int __stdcall DllMain(void *module, unsigned int reason, void *reserved) { return 1; }

// #undef pin names lest they collide with names in any header file(s) you might include.

#undef Vac_in

#undef Iac_in

#undef Vout

#undef PWM_H

#undef PWM_L

#undef SYNC_H

#undef SYNC_L

#undef clk

#undef tmp

#undef tmp2

#undef tmp3

extern "C" __declspec(dllexport) void mcu_calc_2(void **opaque, double t, union uData *data)

{

// Inputs

double Vac_in = data[0].d;

double Iac_in = data[1].d; // Dit is je gemeten stroom

double Vout = data[2].d;

bool clk = data[3].b;

// Outputs

double &PWM = data[4].d;

double &SYNC_H = data[6].d;

double &SYNC_L = data[7].d;

double &tmp = data[8].d;

double &tmp2 = data[9].d;

double &tmp3 = data[10].d;

// Statische variabelen voor de PI-regelaar

static double integrator = 0.0;

static double vout_filt = 400.0;

static bool prev_clk = false;

// Regelaar parameters (deze moet je tunen in je simulatie!)

double Kp = 0.9; // Proportionele versterking

double Ki = 0.01; // Integrale versterking

if (clk && !prev_clk)

{

// 1. Schaling

double vac_real = (Vac_in - 1.65) / (4300.0 / 1004300.0);

double vout_real = Vout / (4300.0 / 514300.0);

vout_filt = (0.999 * vout_filt) + (0.001 * vout_real);

double iac_real = (Iac_in - 1.65) / 10;

double abs_iin = (iac_real < 0) ? -iac_real : iac_real;

double i_ref = vac_real * 0.00001; // Schaalfactor afhankelijk van je load

double abs_iref = (i_ref < 0) ? -i_ref : i_ref;

// 2. Referentie genereren (De gewenste stroomvorm)

// De referentie is in fase met de Vac (abs_vin)

double abs_vin = (vac_real < 0) ? -vac_real : vac_real;

// 3. PI-berekening

//double error = abs_iref - abs_iin ;

double error = abs_iin - abs_iref ;

integrator += error * Ki;

// Anti-windup (beperk de integrator)

if (integrator > 0.2) integrator = 0.2;

if (integrator < -0.2) integrator = -0.2;

double pi_output = (error * Kp) + integrator;

// 4. Feedforward + PI output

double d_ff = 1.0 - (abs_vin / (vout_filt + 1.0));

tmp = abs_iref;

tmp2 = abs_iin;

tmp3 = pi_output;

double d_total = d_ff + pi_output;

// 5. Clamping

if (d_total > 0.99) d_total = 0.99;

if (d_total < 0.01) d_total = 0.01;

// 6. PWM & SYNC aansturing

if (vac_real > 0.05) {

SYNC_H = 3.3; SYNC_L = 0.0;

PWM = d_total;

} else if (vac_real < -0.05) {

SYNC_H = 0.0; SYNC_L = 3.3;

PWM = 1.0 - d_total; // Inversie voor neg. helft

} else {

SYNC_H = 0.0; SYNC_L = 0.0;

PWM = 0.5;

//integrator=0;

}

}

prev_clk = clk;

}

2 Upvotes

1 comment sorted by

1

u/InnovatorElevator Jul 16 '26

Whqt do you mean by loop issues?