// t: Time, passed from PSIM by value // delt: Time step, passed from PSIM by value // in: input array, passed from PSIM by reference // out: output array, sent back to PSIM (Note: the values of out[*] can // be modified in PSIM) // The maximum length of the input and output array "in" and "out" is 30. // Las entradas del sistema son // in[0]= fr; frecuencia de la red // in[1]= Vref; tension de referencia sin normalizar // in[2]= fs; frecuencia de conmutación: La frecuencia de muestreo es 2xfs // in[3]= Vcc; tension de la barra CC // in[4]= vc; tension de salida #include "dll.h" #include #include //#include "ganancias_inversor.h" //#define K11 0.440787706646521 // Gan. RE iLs (para fm=20KHz). //#define K12 25.848651939217628 // Gan. RE Vc (para fm=20KHz). //#define K13 1.381029356307010 // Gan. RE ukm1 (para fm=20KHz). //#define K1 0.798890354811086 // Gan. Servo (para fm=20KHz). // Aqui se implementa una estrategia de control diseñada en matlab, que consta de // un servo controlador mas una realimentación de los estados de la planta. // La frecuencia de muestreo es de 10 kHz. void __declspec(dllexport) simuser (double t, double delt, double *in, double *out) { static double Vbase=311; static double Ibase=64.28; static double vc=0; // tension de fase en bornes del capacitor de filtro static double iL=0; // Corriente en el inductor. static double uk=0, ukm1=0, unk=0; static double uc=0; static double ek=0; static double vk=0, vkm1=0; static double ekm1=0, ekm2=0; static double r, rd; static double rampa; static double K11= 0.880504424685516; static double K12=-0.365608376983481; static double K13= 1.636148773744687; static double K1= 0.522979790723460; static double Ksv=1.816513786671996; static double k1=0.02, k2=-0.135; static double uklim=1.0; static double Tiempo=6; // N° de periodos static double fr; static double Tr; static double Vcc; static double fn; static double Ts; static double Tp; static double TPER; fr=in[0]; Tr=1/fr; Vcc=in[3]; /* Periodo de muestreo */ Ts = 1/in[2]; // Variables enteras static int contador = 0, Ncont, calculo_u, muestreo, direccion = 1; static int PWM1, PWM2; static int ComparReg1, ComparReg2; // Se calcula el numero de conteos en un periodo: Valor máximo del contador Ncont=Ts/delt; Tp=Ncont/4; TPER=Ncont; // Valor máximo del contador up-down o pico de la portadora virtual if (calculo_u==1) { calculo_u=0; r = in[1]/Vbase; // poner una senoidal con la amplitud deseada para la tension de referencia rampa = t; // Variación inicial de Vref (generación de rampa): if (t < 0.12) {rd = (1/(Tiempo*Tr))*rampa*r;} // Calcula incremento de referencia. else {rd = r;} /*********************************************************************************/ /* Se calcula el error de tension */ /*********************************************************************************/ //rd = 1; ek = rd - vc; /*********************************************************************************/ /* Calculo de la estrategia de control */ /*********************************************************************************/ vk = vkm1 + ek; uk = K1*vk - K11*iL - K12*vc - K13*ukm1; /* Limitador de la acción de control y antiwindup if(uk > uklim) // Si uk supera un valor dado, {uk = uklim; // limita acción de control. vk = (uk + K11*iL + K12*vc + K13*ukm1)/K1;} // Recalcula vkm1. if(uk < -uklim) // Si uk supera un valor dado, {uk = -uklim; // limita acción de control. vk = (uk + K11*iL + K12*vc + K13*ukm1)/K1;} // Recalcula vkm1. */ vkm1 = vk; ukm1 = uk; ekm2 = ekm1; ekm1 = ek; // Para lazo abierto // uk = rd; // Se calcula la acción de control normalizada en función del valor base y de Vcc unk = uk*(Vbase/Vcc); } //termina el calculo de ley de control // **********************************************************// // Incrementamos o decrementamos el contador segun corresponda contador = contador + direccion; if (contador < 0) { direccion=1; muestreo=0; } if(contador == Ncont/2) { direccion=-1; muestreo=1; } if (contador == Ncont/2) { ComparReg1 = (TPER/2) + (unk*(TPER/2)); ComparReg2 = (TPER/2) - (unk*(TPER/2)); } // Maquina de estado que define el patron PWM if (ComparReg1 > contador) PWM1=1; else PWM1=0; if (ComparReg2 > contador) PWM2=1; else PWM2=0; if(muestreo==1) { muestreo=0; // Tension de la salida del filtro vc = in[4]/Vbase; iL = in[5]/Ibase; calculo_u=1; } // Se actualizan los valores de las salidas out[0] = PWM1; //brazo 1 out[1] = PWM2; //brazo 2 out[2] = uk; out[3] = rd; out[4] = vk; out[5] = ek; } BOOL WINAPI DllMain(HINSTANCE hinstDLL,DWORD fdwReason,LPVOID lpvReserved) { switch(fdwReason) { case DLL_PROCESS_ATTACH: { break; } case DLL_PROCESS_DETACH: { break; } case DLL_THREAD_ATTACH: { break; } case DLL_THREAD_DETACH: { break; } } /* Return TRUE on success, FALSE on failure */ return TRUE; }