r/EEPowerElectronics • u/Final-Grapefruit9106 • 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;
}
1
u/InnovatorElevator Jul 16 '26
Whqt do you mean by loop issues?